annotate tccasm.c @ 594:2365d90138f5 default tip

Bugfix from Sean Matthews.
author Rob Landley <rob@landley.net>
date Thu, 24 Apr 2008 16:05:02 -0500
parents 7fc19a001568
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
1 /*
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
2 * GAS like assembler for TCC
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
3 *
331
417ae7104677 [project @ 2004-10-27 21:38:03 by bellard]
bellard
parents: 328
diff changeset
4 * Copyright (c) 2001-2004 Fabrice Bellard
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
5 *
499
2b451d2e68ea Exercise LGPL clause 3 and convert more notices from LGPL to GPLv2. (If you
Rob Landley <rob@landley.net>
parents: 481
diff changeset
6 * Licensed under GPLv2, see file LICENSE in this tarball.
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
7 */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
8
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
9 static int asm_get_local_label_name(TCCState *s1, unsigned int n)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
10 {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
11 char buf[64];
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
12 TokenSym *ts;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
13
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
14 snprintf(buf, sizeof(buf), "L..%u", n);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
15 ts = tok_alloc(buf, strlen(buf));
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
16 return ts->tok;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
17 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
18
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
19 static void asm_expr(TCCState *s1, ExprValue *pe);
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
20
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
21 /* We do not use the C expression parser to handle symbols. Maybe the
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
22 C expression parser could be tweaked to do so. */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
23
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
24 static void asm_expr_unary(TCCState *s1, ExprValue *pe)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
25 {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
26 Sym *sym;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
27 int op, n, label;
553
4533aa54ffcf More simplification and attacking warnings.
Rob Landley <rob@landley.net>
parents: 551
diff changeset
28 char *p;
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
29
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
30 switch(tok) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
31 case TOK_PPNUM:
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
32 p = tokc.cstr->data;
250
be6b0d0eec66 [project @ 2003-04-21 15:21:19 by bellard]
bellard
parents: 242
diff changeset
33 n = strtoul(p, (char **)&p, 0);
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
34 if (*p == 'b' || *p == 'f') {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
35 /* backward or forward label */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
36 label = asm_get_local_label_name(s1, n);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
37 sym = label_find(label);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
38 if (*p == 'b') {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
39 /* backward : find the last corresponding defined label */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
40 if (sym && sym->r == 0)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
41 sym = sym->prev_tok;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
42 if (!sym)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
43 error("local label '%d' not found backward", n);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
44 } else {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
45 /* forward */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
46 if (!sym || sym->r) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
47 /* if the last label is defined, then define a new one */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
48 sym = label_push(&s1->asm_labels, label, 0);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
49 sym->type.t = VT_STATIC | VT_VOID;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
50 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
51 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
52 pe->v = 0;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
53 pe->sym = sym;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
54 } else if (*p == '\0') {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
55 pe->v = n;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
56 pe->sym = NULL;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
57 } else {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
58 error("invalid number syntax");
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
59 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
60 next();
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
61 break;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
62 case '+':
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
63 next();
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
64 asm_expr_unary(s1, pe);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
65 break;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
66 case '-':
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
67 case '~':
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
68 op = tok;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
69 next();
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
70 asm_expr_unary(s1, pe);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
71 if (pe->sym)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
72 error("invalid operation with label");
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
73 if (op == '-')
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
74 pe->v = -pe->v;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
75 else
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
76 pe->v = ~pe->v;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
77 break;
258
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
78 case TOK_CCHAR:
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
79 case TOK_LCHAR:
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
80 pe->v = tokc.i;
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
81 pe->sym = NULL;
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
82 next();
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
83 break;
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
84 case '(':
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
85 next();
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
86 asm_expr(s1, pe);
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
87 skip(')');
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
88 break;
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
89 default:
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
90 if (tok >= TOK_IDENT) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
91 /* label case : if the label was not found, add one */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
92 sym = label_find(tok);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
93 if (!sym) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
94 sym = label_push(&s1->asm_labels, tok, 0);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
95 /* NOTE: by default, the symbol is global */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
96 sym->type.t = VT_VOID;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
97 }
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
98 if (sym->r == SHN_ABS) {
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
99 /* if absolute symbol, no need to put a symbol value */
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
100 pe->v = (long)sym->next;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
101 pe->sym = NULL;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
102 } else {
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
103 pe->v = 0;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
104 pe->sym = sym;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
105 }
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
106 next();
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
107 } else {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
108 error("bad expression syntax [%s]", get_tok_str(tok, &tokc));
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
109 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
110 break;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
111 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
112 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
113
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
114 static void asm_expr_prod(TCCState *s1, ExprValue *pe)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
115 {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
116 int op;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
117 ExprValue e2;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
118
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
119 asm_expr_unary(s1, pe);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
120 for(;;) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
121 op = tok;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
122 if (op != '*' && op != '/' && op != '%' &&
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
123 op != TOK_SHL && op != TOK_SAR)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
124 break;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
125 next();
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
126 asm_expr_unary(s1, &e2);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
127 if (pe->sym || e2.sym)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
128 error("invalid operation with label");
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
129 switch(op) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
130 case '*':
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
131 pe->v *= e2.v;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
132 break;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
133 case '/':
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
134 if (e2.v == 0) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
135 div_error:
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
136 error("division by zero");
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
137 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
138 pe->v /= e2.v;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
139 break;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
140 case '%':
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
141 if (e2.v == 0)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
142 goto div_error;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
143 pe->v %= e2.v;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
144 break;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
145 case TOK_SHL:
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
146 pe->v <<= e2.v;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
147 break;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
148 default:
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
149 case TOK_SAR:
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
150 pe->v >>= e2.v;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
151 break;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
152 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
153 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
154 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
155
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
156 static void asm_expr_logic(TCCState *s1, ExprValue *pe)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
157 {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
158 int op;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
159 ExprValue e2;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
160
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
161 asm_expr_prod(s1, pe);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
162 for(;;) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
163 op = tok;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
164 if (op != '&' && op != '|' && op != '^')
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
165 break;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
166 next();
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
167 asm_expr_prod(s1, &e2);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
168 if (pe->sym || e2.sym)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
169 error("invalid operation with label");
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
170 switch(op) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
171 case '&':
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
172 pe->v &= e2.v;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
173 break;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
174 case '|':
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
175 pe->v |= e2.v;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
176 break;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
177 default:
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
178 case '^':
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
179 pe->v ^= e2.v;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
180 break;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
181 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
182 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
183 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
184
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
185 static inline void asm_expr_sum(TCCState *s1, ExprValue *pe)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
186 {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
187 int op;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
188 ExprValue e2;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
189
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
190 asm_expr_logic(s1, pe);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
191 for(;;) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
192 op = tok;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
193 if (op != '+' && op != '-')
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
194 break;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
195 next();
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
196 asm_expr_logic(s1, &e2);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
197 if (op == '+') {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
198 if (pe->sym != NULL && e2.sym != NULL)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
199 goto cannot_relocate;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
200 pe->v += e2.v;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
201 if (pe->sym == NULL && e2.sym != NULL)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
202 pe->sym = e2.sym;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
203 } else {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
204 pe->v -= e2.v;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
205 /* NOTE: we are less powerful than gas in that case
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
206 because we store only one symbol in the expression */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
207 if (!pe->sym && !e2.sym) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
208 /* OK */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
209 } else if (pe->sym && !e2.sym) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
210 /* OK */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
211 } else if (pe->sym && e2.sym) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
212 if (pe->sym == e2.sym) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
213 /* OK */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
214 } else if (pe->sym->r == e2.sym->r && pe->sym->r != 0) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
215 /* we also accept defined symbols in the same section */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
216 pe->v += (long)pe->sym->next - (long)e2.sym->next;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
217 } else {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
218 goto cannot_relocate;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
219 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
220 pe->sym = NULL; /* same symbols can be substracted to NULL */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
221 } else {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
222 cannot_relocate:
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
223 error("invalid operation with label");
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
224 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
225 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
226 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
227 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
228
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
229 static void asm_expr(TCCState *s1, ExprValue *pe)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
230 {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
231 asm_expr_sum(s1, pe);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
232 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
233
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
234 static int asm_int_expr(TCCState *s1)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
235 {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
236 ExprValue e;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
237 asm_expr(s1, &e);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
238 if (e.sym)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
239 expect("constant");
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
240 return e.v;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
241 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
242
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
243 /* NOTE: the same name space as C labels is used to avoid using too
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
244 much memory when storing labels in TokenStrings */
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
245 static void asm_new_label1(TCCState *s1, int label, int is_local,
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
246 int sh_num, int value)
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
247 {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
248 Sym *sym;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
249
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
250 sym = label_find(label);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
251 if (sym) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
252 if (sym->r) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
253 /* the label is already defined */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
254 if (!is_local) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
255 error("assembler label '%s' already defined",
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
256 get_tok_str(label, NULL));
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
257 } else {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
258 /* redefinition of local labels is possible */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
259 goto new_label;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
260 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
261 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
262 } else {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
263 new_label:
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
264 sym = label_push(&s1->asm_labels, label, 0);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
265 sym->type.t = VT_STATIC | VT_VOID;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
266 }
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
267 sym->r = sh_num;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
268 sym->next = (void *)value;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
269 }
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
270
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
271 static void asm_new_label(TCCState *s1, int label, int is_local)
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
272 {
585
7fc19a001568 Rename global gen.c variable ind to gen_ind.
Rob Landley <rob@landley.net>
parents: 572
diff changeset
273 asm_new_label1(s1, label, is_local, cur_text_section->sh_num, gen_ind);
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
274 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
275
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
276 static void asm_free_labels(TCCState *st)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
277 {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
278 Sym *s, *s1;
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
279 Section *sec;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
280
553
4533aa54ffcf More simplification and attacking warnings.
Rob Landley <rob@landley.net>
parents: 551
diff changeset
281 for(s = st->asm_labels; s; s = s1) {
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
282 s1 = s->prev;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
283 /* define symbol value in object file */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
284 if (s->r) {
553
4533aa54ffcf More simplification and attacking warnings.
Rob Landley <rob@landley.net>
parents: 551
diff changeset
285 if (s->r == SHN_ABS) sec = SECTION_ABS;
4533aa54ffcf More simplification and attacking warnings.
Rob Landley <rob@landley.net>
parents: 551
diff changeset
286 else sec = st->sections[s->r];
373
64bb1c7ea969 [project @ 2005-06-15 22:32:10 by bellard]
bellard
parents: 341
diff changeset
287 put_extern_sym2(s, sec, (long)s->next, 0, 0);
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
288 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
289 /* remove label */
551
d8b3fa09ca5d One of the members of "struct Sym" is a token. Rename it from "v" to "token", and change local variables
Rob Landley <rob@landley.net>
parents: 507
diff changeset
290 table_ident[s->token - TOK_IDENT]->sym_label = NULL;
341
62f3ca78e53e [project @ 2004-11-07 15:45:40 by bellard]
bellard
parents: 331
diff changeset
291 sym_free(s);
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
292 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
293 st->asm_labels = NULL;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
294 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
295
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
296 static void use_section1(TCCState *s1, Section *sec)
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
297 {
585
7fc19a001568 Rename global gen.c variable ind to gen_ind.
Rob Landley <rob@landley.net>
parents: 572
diff changeset
298 cur_text_section->data_offset = gen_ind;
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
299 cur_text_section = sec;
585
7fc19a001568 Rename global gen.c variable ind to gen_ind.
Rob Landley <rob@landley.net>
parents: 572
diff changeset
300 gen_ind = cur_text_section->data_offset;
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
301 }
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
302
553
4533aa54ffcf More simplification and attacking warnings.
Rob Landley <rob@landley.net>
parents: 551
diff changeset
303 static void use_section(TCCState *s1, char *name)
258
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
304 {
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
305 Section *sec;
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
306 sec = find_section(s1, name);
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
307 use_section1(s1, sec);
258
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
308 }
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
309
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
310 static void asm_parse_directive(TCCState *s1)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
311 {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
312 int n, offset, v, size, tok1;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
313 Section *sec;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
314 uint8_t *ptr;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
315
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
316 /* assembler directive */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
317 next();
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
318 sec = cur_text_section;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
319 switch(tok) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
320 case TOK_ASM_align:
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
321 case TOK_ASM_skip:
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
322 case TOK_ASM_space:
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
323 tok1 = tok;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
324 next();
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
325 n = asm_int_expr(s1);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
326 if (tok1 == TOK_ASM_align) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
327 if (n < 0 || (n & (n-1)) != 0)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
328 error("alignment must be a positive power of two");
585
7fc19a001568 Rename global gen.c variable ind to gen_ind.
Rob Landley <rob@landley.net>
parents: 572
diff changeset
329 offset = (gen_ind + n - 1) & -n;
7fc19a001568 Rename global gen.c variable ind to gen_ind.
Rob Landley <rob@landley.net>
parents: 572
diff changeset
330 size = offset - gen_ind;
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
331 /* the section must have a compatible alignment */
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
332 if (sec->sh_addralign < n)
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
333 sec->sh_addralign = n;
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
334 } else {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
335 size = n;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
336 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
337 v = 0;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
338 if (tok == ',') {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
339 next();
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
340 v = asm_int_expr(s1);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
341 }
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
342 zero_pad:
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
343 if (sec->sh_type != SHT_NOBITS) {
585
7fc19a001568 Rename global gen.c variable ind to gen_ind.
Rob Landley <rob@landley.net>
parents: 572
diff changeset
344 sec->data_offset = gen_ind;
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
345 ptr = section_ptr_add(sec, size);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
346 memset(ptr, v, size);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
347 }
585
7fc19a001568 Rename global gen.c variable ind to gen_ind.
Rob Landley <rob@landley.net>
parents: 572
diff changeset
348 gen_ind += size;
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
349 break;
328
3fe3ae25515d [project @ 2004-10-25 18:54:29 by bellard]
bellard
parents: 323
diff changeset
350 case TOK_ASM_quad:
3fe3ae25515d [project @ 2004-10-25 18:54:29 by bellard]
bellard
parents: 323
diff changeset
351 next();
3fe3ae25515d [project @ 2004-10-25 18:54:29 by bellard]
bellard
parents: 323
diff changeset
352 for(;;) {
3fe3ae25515d [project @ 2004-10-25 18:54:29 by bellard]
bellard
parents: 323
diff changeset
353 uint64_t vl;
553
4533aa54ffcf More simplification and attacking warnings.
Rob Landley <rob@landley.net>
parents: 551
diff changeset
354 char *p;
328
3fe3ae25515d [project @ 2004-10-25 18:54:29 by bellard]
bellard
parents: 323
diff changeset
355
3fe3ae25515d [project @ 2004-10-25 18:54:29 by bellard]
bellard
parents: 323
diff changeset
356 p = tokc.cstr->data;
3fe3ae25515d [project @ 2004-10-25 18:54:29 by bellard]
bellard
parents: 323
diff changeset
357 if (tok != TOK_PPNUM) {
3fe3ae25515d [project @ 2004-10-25 18:54:29 by bellard]
bellard
parents: 323
diff changeset
358 error_constant:
3fe3ae25515d [project @ 2004-10-25 18:54:29 by bellard]
bellard
parents: 323
diff changeset
359 error("64 bit constant");
3fe3ae25515d [project @ 2004-10-25 18:54:29 by bellard]
bellard
parents: 323
diff changeset
360 }
3fe3ae25515d [project @ 2004-10-25 18:54:29 by bellard]
bellard
parents: 323
diff changeset
361 vl = strtoll(p, (char **)&p, 0);
3fe3ae25515d [project @ 2004-10-25 18:54:29 by bellard]
bellard
parents: 323
diff changeset
362 if (*p != '\0')
3fe3ae25515d [project @ 2004-10-25 18:54:29 by bellard]
bellard
parents: 323
diff changeset
363 goto error_constant;
3fe3ae25515d [project @ 2004-10-25 18:54:29 by bellard]
bellard
parents: 323
diff changeset
364 next();
3fe3ae25515d [project @ 2004-10-25 18:54:29 by bellard]
bellard
parents: 323
diff changeset
365 if (sec->sh_type != SHT_NOBITS) {
3fe3ae25515d [project @ 2004-10-25 18:54:29 by bellard]
bellard
parents: 323
diff changeset
366 /* XXX: endianness */
3fe3ae25515d [project @ 2004-10-25 18:54:29 by bellard]
bellard
parents: 323
diff changeset
367 gen_le32(vl);
3fe3ae25515d [project @ 2004-10-25 18:54:29 by bellard]
bellard
parents: 323
diff changeset
368 gen_le32(vl >> 32);
3fe3ae25515d [project @ 2004-10-25 18:54:29 by bellard]
bellard
parents: 323
diff changeset
369 } else {
585
7fc19a001568 Rename global gen.c variable ind to gen_ind.
Rob Landley <rob@landley.net>
parents: 572
diff changeset
370 gen_ind += 8;
328
3fe3ae25515d [project @ 2004-10-25 18:54:29 by bellard]
bellard
parents: 323
diff changeset
371 }
3fe3ae25515d [project @ 2004-10-25 18:54:29 by bellard]
bellard
parents: 323
diff changeset
372 if (tok != ',')
3fe3ae25515d [project @ 2004-10-25 18:54:29 by bellard]
bellard
parents: 323
diff changeset
373 break;
3fe3ae25515d [project @ 2004-10-25 18:54:29 by bellard]
bellard
parents: 323
diff changeset
374 next();
3fe3ae25515d [project @ 2004-10-25 18:54:29 by bellard]
bellard
parents: 323
diff changeset
375 }
3fe3ae25515d [project @ 2004-10-25 18:54:29 by bellard]
bellard
parents: 323
diff changeset
376 break;
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
377 case TOK_ASM_byte:
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
378 size = 1;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
379 goto asm_data;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
380 case TOK_ASM_word:
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
381 case TOK_SHORT:
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
382 size = 2;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
383 goto asm_data;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
384 case TOK_LONG:
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
385 case TOK_INT:
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
386 size = 4;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
387 asm_data:
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
388 next();
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
389 for(;;) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
390 ExprValue e;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
391 asm_expr(s1, &e);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
392 if (sec->sh_type != SHT_NOBITS) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
393 if (size == 4) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
394 gen_expr32(&e);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
395 } else {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
396 if (e.sym)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
397 expect("constant");
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
398 if (size == 1)
572
9414324cc68a Rename g() to gen_byte(). Much easier to grep for, and a step towards making
Rob Landley <rob@landley.net>
parents: 553
diff changeset
399 gen_byte(e.v);
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
400 else
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
401 gen_le16(e.v);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
402 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
403 } else {
585
7fc19a001568 Rename global gen.c variable ind to gen_ind.
Rob Landley <rob@landley.net>
parents: 572
diff changeset
404 gen_ind += size;
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
405 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
406 if (tok != ',')
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
407 break;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
408 next();
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
409 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
410 break;
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
411 case TOK_ASM_fill:
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
412 {
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
413 int repeat, size, val, i, j;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
414 uint8_t repeat_buf[8];
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
415 next();
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
416 repeat = asm_int_expr(s1);
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
417 if (repeat < 0) {
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
418 error("repeat < 0; .fill ignored");
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
419 break;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
420 }
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
421 size = 1;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
422 val = 0;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
423 if (tok == ',') {
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
424 next();
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
425 size = asm_int_expr(s1);
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
426 if (size < 0) {
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
427 error("size < 0; .fill ignored");
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
428 break;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
429 }
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
430 if (size > 8)
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
431 size = 8;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
432 if (tok == ',') {
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
433 next();
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
434 val = asm_int_expr(s1);
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
435 }
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
436 }
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
437 /* XXX: endianness */
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
438 repeat_buf[0] = val;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
439 repeat_buf[1] = val >> 8;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
440 repeat_buf[2] = val >> 16;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
441 repeat_buf[3] = val >> 24;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
442 repeat_buf[4] = 0;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
443 repeat_buf[5] = 0;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
444 repeat_buf[6] = 0;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
445 repeat_buf[7] = 0;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
446 for(i = 0; i < repeat; i++) {
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
447 for(j = 0; j < size; j++) {
572
9414324cc68a Rename g() to gen_byte(). Much easier to grep for, and a step towards making
Rob Landley <rob@landley.net>
parents: 553
diff changeset
448 gen_byte(repeat_buf[j]);
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
449 }
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
450 }
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
451 }
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
452 break;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
453 case TOK_ASM_org:
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
454 {
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
455 unsigned long n;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
456 next();
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
457 /* XXX: handle section symbols too */
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
458 n = asm_int_expr(s1);
585
7fc19a001568 Rename global gen.c variable ind to gen_ind.
Rob Landley <rob@landley.net>
parents: 572
diff changeset
459 if (n < gen_ind)
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
460 error("attempt to .org backwards");
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
461 v = 0;
585
7fc19a001568 Rename global gen.c variable ind to gen_ind.
Rob Landley <rob@landley.net>
parents: 572
diff changeset
462 size = n - gen_ind;
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
463 goto zero_pad;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
464 }
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
465 break;
258
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
466 case TOK_ASM_globl:
302
464079a88a2f [project @ 2004-10-02 14:01:26 by bellard]
bellard
parents: 268
diff changeset
467 case TOK_ASM_global:
258
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
468 {
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
469 Sym *sym;
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
470
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
471 next();
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
472 sym = label_find(tok);
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
473 if (!sym) {
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
474 sym = label_push(&s1->asm_labels, tok, 0);
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
475 sym->type.t = VT_VOID;
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
476 }
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
477 sym->type.t &= ~VT_STATIC;
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
478 next();
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
479 }
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
480 break;
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
481 case TOK_ASM_string:
323
164e85dc9987 [project @ 2004-10-23 22:52:42 by bellard]
bellard
parents: 318
diff changeset
482 case TOK_ASM_ascii:
164e85dc9987 [project @ 2004-10-23 22:52:42 by bellard]
bellard
parents: 318
diff changeset
483 case TOK_ASM_asciz:
258
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
484 {
553
4533aa54ffcf More simplification and attacking warnings.
Rob Landley <rob@landley.net>
parents: 551
diff changeset
485 uint8_t *p;
323
164e85dc9987 [project @ 2004-10-23 22:52:42 by bellard]
bellard
parents: 318
diff changeset
486 int i, size, t;
258
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
487
323
164e85dc9987 [project @ 2004-10-23 22:52:42 by bellard]
bellard
parents: 318
diff changeset
488 t = tok;
258
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
489 next();
323
164e85dc9987 [project @ 2004-10-23 22:52:42 by bellard]
bellard
parents: 318
diff changeset
490 for(;;) {
164e85dc9987 [project @ 2004-10-23 22:52:42 by bellard]
bellard
parents: 318
diff changeset
491 if (tok != TOK_STR)
164e85dc9987 [project @ 2004-10-23 22:52:42 by bellard]
bellard
parents: 318
diff changeset
492 expect("string constant");
164e85dc9987 [project @ 2004-10-23 22:52:42 by bellard]
bellard
parents: 318
diff changeset
493 p = tokc.cstr->data;
164e85dc9987 [project @ 2004-10-23 22:52:42 by bellard]
bellard
parents: 318
diff changeset
494 size = tokc.cstr->size;
164e85dc9987 [project @ 2004-10-23 22:52:42 by bellard]
bellard
parents: 318
diff changeset
495 if (t == TOK_ASM_ascii && size > 0)
164e85dc9987 [project @ 2004-10-23 22:52:42 by bellard]
bellard
parents: 318
diff changeset
496 size--;
164e85dc9987 [project @ 2004-10-23 22:52:42 by bellard]
bellard
parents: 318
diff changeset
497 for(i = 0; i < size; i++)
572
9414324cc68a Rename g() to gen_byte(). Much easier to grep for, and a step towards making
Rob Landley <rob@landley.net>
parents: 553
diff changeset
498 gen_byte(p[i]);
323
164e85dc9987 [project @ 2004-10-23 22:52:42 by bellard]
bellard
parents: 318
diff changeset
499 next();
164e85dc9987 [project @ 2004-10-23 22:52:42 by bellard]
bellard
parents: 318
diff changeset
500 if (tok == ',') {
164e85dc9987 [project @ 2004-10-23 22:52:42 by bellard]
bellard
parents: 318
diff changeset
501 next();
164e85dc9987 [project @ 2004-10-23 22:52:42 by bellard]
bellard
parents: 318
diff changeset
502 } else if (tok != TOK_STR) {
164e85dc9987 [project @ 2004-10-23 22:52:42 by bellard]
bellard
parents: 318
diff changeset
503 break;
164e85dc9987 [project @ 2004-10-23 22:52:42 by bellard]
bellard
parents: 318
diff changeset
504 }
164e85dc9987 [project @ 2004-10-23 22:52:42 by bellard]
bellard
parents: 318
diff changeset
505 }
258
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
506 }
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
507 break;
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
508 case TOK_ASM_text:
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
509 case TOK_ASM_data:
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
510 case TOK_ASM_bss:
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
511 {
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
512 char sname[64];
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
513 tok1 = tok;
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
514 n = 0;
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
515 next();
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
516 if (tok != ';' && tok != TOK_LINEFEED) {
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
517 n = asm_int_expr(s1);
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
518 next();
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
519 }
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
520 sprintf(sname, (n?".%s%d":".%s"), get_tok_str(tok1, NULL), n);
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
521 use_section(s1, sname);
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
522 }
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
523 break;
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
524 case TOK_SECTION1:
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
525 {
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
526 char sname[256];
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
527
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
528 /* XXX: support more options */
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
529 next();
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
530 sname[0] = '\0';
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
531 while (tok != ';' && tok != TOK_LINEFEED && tok != ',') {
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
532 if (tok == TOK_STR)
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
533 pstrcat(sname, sizeof(sname), tokc.cstr->data);
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
534 else
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
535 pstrcat(sname, sizeof(sname), get_tok_str(tok, NULL));
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
536 next();
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
537 }
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
538 if (tok == ',') {
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
539 /* skip section options */
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
540 next();
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
541 if (tok != TOK_STR)
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
542 expect("string constant");
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
543 next();
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
544 }
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
545 last_text_section = cur_text_section;
258
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
546 use_section(s1, sname);
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
547 }
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
548 break;
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
549 case TOK_ASM_previous:
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
550 {
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
551 Section *sec;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
552 next();
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
553 if (!last_text_section)
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
554 error("no previous section referenced");
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
555 sec = cur_text_section;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
556 use_section1(s1, last_text_section);
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
557 last_text_section = sec;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
558 }
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
559 break;
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
560 default:
258
23d6a8deb2d6 [project @ 2003-04-28 21:23:53 by bellard]
bellard
parents: 250
diff changeset
561 error("unknown assembler directive '.%s'", get_tok_str(tok, NULL));
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
562 break;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
563 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
564 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
565
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
566
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
567 /* assemble a file */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
568 static int tcc_assemble_internal(TCCState *s1, int do_preprocess)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
569 {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
570 int opcode;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
571
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
572 #if 0
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
573 /* print stats about opcodes */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
574 {
553
4533aa54ffcf More simplification and attacking warnings.
Rob Landley <rob@landley.net>
parents: 551
diff changeset
575 ASMInstr *pa;
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
576 int freq[4];
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
577 int op_vals[500];
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
578 int nb_op_vals, i, j;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
579
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
580 nb_op_vals = 0;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
581 memset(freq, 0, sizeof(freq));
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
582 for(pa = asm_instrs; pa->sym != 0; pa++) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
583 freq[pa->nb_ops]++;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
584 for(i=0;i<pa->nb_ops;i++) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
585 for(j=0;j<nb_op_vals;j++) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
586 if (pa->op_type[i] == op_vals[j])
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
587 goto found;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
588 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
589 op_vals[nb_op_vals++] = pa->op_type[i];
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
590 found: ;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
591 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
592 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
593 for(i=0;i<nb_op_vals;i++) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
594 int v = op_vals[i];
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
595 if ((v & (v - 1)) != 0)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
596 printf("%3d: %08x\n", i, v);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
597 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
598 printf("size=%d nb=%d f0=%d f1=%d f2=%d f3=%d\n",
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
599 sizeof(asm_instrs), sizeof(asm_instrs) / sizeof(ASMInstr),
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
600 freq[0], freq[1], freq[2], freq[3]);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
601 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
602 #endif
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
603
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
604 /* XXX: undefine C labels */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
605
479
7909d3c7e712 Replace global "ch" with "fch" so it's slightly easier to grep for. (It's the
Rob Landley <rob@landley.net>
parents: 475
diff changeset
606 fch = file->buf_ptr[0];
453
a70ac19d704b Stringize patch from Harald van Dijk:
Rob Landley <rob@landley.net>
parents: 388
diff changeset
607 next_tok_flags = TOK_FLAG_BOW | TOK_FLAG_BOL | TOK_FLAG_BOF;
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
608 parse_flags = PARSE_FLAG_ASM_COMMENTS;
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
609 if (do_preprocess)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
610 parse_flags |= PARSE_FLAG_PREPROCESS;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
611 next();
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
612 for(;;) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
613 if (tok == TOK_EOF)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
614 break;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
615 parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
616 redo:
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
617 if (tok == '#') {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
618 /* horrible gas comment */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
619 while (tok != TOK_LINEFEED)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
620 next();
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
621 } else if (tok == '.') {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
622 asm_parse_directive(s1);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
623 } else if (tok == TOK_PPNUM) {
553
4533aa54ffcf More simplification and attacking warnings.
Rob Landley <rob@landley.net>
parents: 551
diff changeset
624 char *p;
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
625 int n;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
626 p = tokc.cstr->data;
250
be6b0d0eec66 [project @ 2003-04-21 15:21:19 by bellard]
bellard
parents: 242
diff changeset
627 n = strtoul(p, (char **)&p, 10);
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
628 if (*p != '\0')
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
629 expect("':'");
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
630 /* new local label */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
631 asm_new_label(s1, asm_get_local_label_name(s1, n), 1);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
632 next();
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
633 skip(':');
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
634 goto redo;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
635 } else if (tok >= TOK_IDENT) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
636 /* instruction or label */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
637 opcode = tok;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
638 next();
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
639 if (tok == ':') {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
640 /* new label */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
641 asm_new_label(s1, opcode, 0);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
642 next();
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
643 goto redo;
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
644 } else if (tok == '=') {
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
645 int n;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
646 next();
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
647 n = asm_int_expr(s1);
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
648 asm_new_label1(s1, opcode, 0, SHN_ABS, n);
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
649 goto redo;
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
650 } else {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
651 asm_opcode(s1, opcode);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
652 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
653 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
654 /* end of line */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
655 if (tok != ';' && tok != TOK_LINEFEED){
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
656 expect("end of line");
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
657 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
658 parse_flags &= ~PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
659 next();
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
660 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
661
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
662 asm_free_labels(s1);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
663
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
664 return 0;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
665 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
666
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
667 /* Assemble the current file */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
668 static int tcc_assemble(TCCState *s1, int do_preprocess)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
669 {
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
670 Sym *define_start;
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
671 int ret;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
672
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
673 preprocess_init(s1);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
674
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
675 /* default section is text */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
676 cur_text_section = text_section;
585
7fc19a001568 Rename global gen.c variable ind to gen_ind.
Rob Landley <rob@landley.net>
parents: 572
diff changeset
677 gen_ind = cur_text_section->data_offset;
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
678
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
679 define_start = define_stack;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
680
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
681 ret = tcc_assemble_internal(s1, do_preprocess);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
682
585
7fc19a001568 Rename global gen.c variable ind to gen_ind.
Rob Landley <rob@landley.net>
parents: 572
diff changeset
683 cur_text_section->data_offset = gen_ind;
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
684
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
685 free_defines(define_start);
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
686
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
687 return ret;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
688 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
689
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
690 /********************************************************************/
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
691 /* GCC inline asm support */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
692
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
693 /* assemble the string 'str' in the current C compilation unit without
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
694 C preprocessing. NOTE: str is modified by modifying the '\0' at the
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
695 end */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
696 static void tcc_assemble_inline(TCCState *s1, char *str, int len)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
697 {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
698 BufferedFile *bf, *saved_file;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
699 int saved_parse_flags, *saved_macro_ptr;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
700
507
67453c7d623e Clean up malloc() and friends to xmalloc/xzmalloc/xstrdup, and remove redundant
Rob Landley <rob@landley.net>
parents: 499
diff changeset
701 bf = xzmalloc(sizeof(BufferedFile));
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
702 bf->fd = -1;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
703 bf->buf_ptr = str;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
704 bf->buf_end = str + len;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
705 str[len] = CH_EOB;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
706 /* same name as current file so that errors are correctly
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
707 reported */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
708 pstrcpy(bf->filename, sizeof(bf->filename), file->filename);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
709 bf->line_num = file->line_num;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
710 saved_file = file;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
711 file = bf;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
712 saved_parse_flags = parse_flags;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
713 saved_macro_ptr = macro_ptr;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
714 macro_ptr = NULL;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
715
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
716 tcc_assemble_internal(s1, 0);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
717
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
718 parse_flags = saved_parse_flags;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
719 macro_ptr = saved_macro_ptr;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
720 file = saved_file;
481
0f5c38ddf450 Remove MEM_DEBUG and now-useless tcc_free() wrapper. Now, would anyone like to
Rob Landley <rob@landley.net>
parents: 479
diff changeset
721 free(bf);
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
722 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
723
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
724 /* find a constraint by its number or id (gcc 3 extended
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
725 syntax). return -1 if not found. Return in *pp in char after the
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
726 constraint */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
727 static int find_constraint(ASMOperand *operands, int nb_operands,
553
4533aa54ffcf More simplification and attacking warnings.
Rob Landley <rob@landley.net>
parents: 551
diff changeset
728 char *name, char **pp)
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
729 {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
730 int index;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
731 TokenSym *ts;
553
4533aa54ffcf More simplification and attacking warnings.
Rob Landley <rob@landley.net>
parents: 551
diff changeset
732 char *p;
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
733
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
734 if (isnum(*name)) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
735 index = 0;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
736 while (isnum(*name)) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
737 index = (index * 10) + (*name) - '0';
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
738 name++;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
739 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
740 if ((unsigned)index >= nb_operands)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
741 index = -1;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
742 } else if (*name == '[') {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
743 name++;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
744 p = strchr(name, ']');
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
745 if (p) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
746 ts = tok_alloc(name, p - name);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
747 for(index = 0; index < nb_operands; index++) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
748 if (operands[index].id == ts->tok)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
749 goto found;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
750 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
751 index = -1;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
752 found:
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
753 name = p + 1;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
754 } else {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
755 index = -1;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
756 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
757 } else {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
758 index = -1;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
759 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
760 if (pp)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
761 *pp = name;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
762 return index;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
763 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
764
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
765 static void subst_asm_operands(ASMOperand *operands, int nb_operands,
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
766 int nb_outputs,
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
767 CString *out_str, CString *in_str)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
768 {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
769 int c, index, modifier;
553
4533aa54ffcf More simplification and attacking warnings.
Rob Landley <rob@landley.net>
parents: 551
diff changeset
770 char *str;
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
771 ASMOperand *op;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
772 SValue sv;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
773
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
774 cstr_new(out_str);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
775 str = in_str->data;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
776 for(;;) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
777 c = *str++;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
778 if (c == '%') {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
779 if (*str == '%') {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
780 str++;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
781 goto add_char;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
782 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
783 modifier = 0;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
784 if (*str == 'c' || *str == 'n' ||
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
785 *str == 'b' || *str == 'w' || *str == 'h')
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
786 modifier = *str++;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
787 index = find_constraint(operands, nb_operands, str, &str);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
788 if (index < 0)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
789 error("invalid operand reference after %%");
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
790 op = &operands[index];
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
791 sv = *op->vt;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
792 if (op->reg >= 0) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
793 sv.r = op->reg;
475
91c4c7d64f5e From Joshua Phillips, fix dereferences used in inline assembly output.
Rob Landley <rob@landley.net>
parents: 453
diff changeset
794 if ((op->vt->r & VT_VALMASK) == VT_LLOCAL && op->is_memory)
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
795 sv.r |= VT_LVAL;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
796 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
797 subst_asm_operand(out_str, &sv, modifier);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
798 } else {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
799 add_char:
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
800 cstr_ccat(out_str, c);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
801 if (c == '\0')
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
802 break;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
803 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
804 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
805 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
806
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
807
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
808 static void parse_asm_operands(ASMOperand *operands, int *nb_operands_ptr,
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
809 int is_output)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
810 {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
811 ASMOperand *op;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
812 int nb_operands;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
813
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
814 if (tok != ':') {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
815 nb_operands = *nb_operands_ptr;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
816 for(;;) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
817 if (nb_operands >= MAX_ASM_OPERANDS)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
818 error("too many asm operands");
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
819 op = &operands[nb_operands++];
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
820 op->id = 0;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
821 if (tok == '[') {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
822 next();
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
823 if (tok < TOK_IDENT)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
824 expect("identifier");
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
825 op->id = tok;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
826 next();
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
827 skip(']');
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
828 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
829 if (tok != TOK_STR)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
830 expect("string constant");
507
67453c7d623e Clean up malloc() and friends to xmalloc/xzmalloc/xstrdup, and remove redundant
Rob Landley <rob@landley.net>
parents: 499
diff changeset
831 op->constraint = xmalloc(tokc.cstr->size);
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
832 strcpy(op->constraint, tokc.cstr->data);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
833 next();
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
834 skip('(');
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
835 gexpr();
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
836 if (is_output) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
837 test_lvalue();
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
838 } else {
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
839 /* we want to avoid LLOCAL case, except when the 'm'
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
840 constraint is used. Note that it may come from
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
841 register storage, so we need to convert (reg)
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
842 case */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
843 if ((vtop->r & VT_LVAL) &&
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
844 ((vtop->r & VT_VALMASK) == VT_LLOCAL ||
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
845 (vtop->r & VT_VALMASK) < VT_CONST) &&
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
846 !strchr(op->constraint, 'm')) {
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
847 gv(RC_INT);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
848 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
849 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
850 op->vt = vtop;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
851 skip(')');
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
852 if (tok == ',') {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
853 next();
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
854 } else {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
855 break;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
856 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
857 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
858 *nb_operands_ptr = nb_operands;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
859 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
860 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
861
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
862 static void parse_asm_str(CString *astr)
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
863 {
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
864 skip('(');
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
865 /* read the string */
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
866 if (tok != TOK_STR)
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
867 expect("string constant");
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
868 cstr_new(astr);
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
869 while (tok == TOK_STR) {
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
870 /* XXX: add \0 handling too ? */
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
871 cstr_cat(astr, tokc.cstr->data);
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
872 next();
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
873 }
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
874 cstr_ccat(astr, '\0');
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
875 }
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
876
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
877 /* parse the GCC asm() instruction */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
878 static void asm_instr(void)
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
879 {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
880 CString astr, astr1;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
881 ASMOperand operands[MAX_ASM_OPERANDS];
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
882 int nb_inputs, nb_outputs, nb_operands, i, must_subst, out_reg;
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
883 uint8_t clobber_regs[NB_ASM_REGS];
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
884
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
885 next();
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
886 /* since we always generate the asm() instruction, we can ignore
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
887 volatile */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
888 if (tok == TOK_VOLATILE1 || tok == TOK_VOLATILE2 || tok == TOK_VOLATILE3) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
889 next();
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
890 }
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
891 parse_asm_str(&astr);
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
892 nb_operands = 0;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
893 nb_outputs = 0;
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
894 must_subst = 0;
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
895 memset(clobber_regs, 0, sizeof(clobber_regs));
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
896 if (tok == ':') {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
897 next();
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
898 must_subst = 1;
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
899 /* output args */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
900 parse_asm_operands(operands, &nb_operands, 1);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
901 nb_outputs = nb_operands;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
902 if (tok == ':') {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
903 next();
388
25f4a44d713f [project @ 2005-09-03 22:23:59 by bellard]
bellard
parents: 373
diff changeset
904 if (tok != ')') {
25f4a44d713f [project @ 2005-09-03 22:23:59 by bellard]
bellard
parents: 373
diff changeset
905 /* input args */
25f4a44d713f [project @ 2005-09-03 22:23:59 by bellard]
bellard
parents: 373
diff changeset
906 parse_asm_operands(operands, &nb_operands, 0);
25f4a44d713f [project @ 2005-09-03 22:23:59 by bellard]
bellard
parents: 373
diff changeset
907 if (tok == ':') {
25f4a44d713f [project @ 2005-09-03 22:23:59 by bellard]
bellard
parents: 373
diff changeset
908 /* clobber list */
25f4a44d713f [project @ 2005-09-03 22:23:59 by bellard]
bellard
parents: 373
diff changeset
909 /* XXX: handle registers */
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
910 next();
388
25f4a44d713f [project @ 2005-09-03 22:23:59 by bellard]
bellard
parents: 373
diff changeset
911 for(;;) {
25f4a44d713f [project @ 2005-09-03 22:23:59 by bellard]
bellard
parents: 373
diff changeset
912 if (tok != TOK_STR)
25f4a44d713f [project @ 2005-09-03 22:23:59 by bellard]
bellard
parents: 373
diff changeset
913 expect("string constant");
25f4a44d713f [project @ 2005-09-03 22:23:59 by bellard]
bellard
parents: 373
diff changeset
914 asm_clobber(clobber_regs, tokc.cstr->data);
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
915 next();
388
25f4a44d713f [project @ 2005-09-03 22:23:59 by bellard]
bellard
parents: 373
diff changeset
916 if (tok == ',') {
25f4a44d713f [project @ 2005-09-03 22:23:59 by bellard]
bellard
parents: 373
diff changeset
917 next();
25f4a44d713f [project @ 2005-09-03 22:23:59 by bellard]
bellard
parents: 373
diff changeset
918 } else {
25f4a44d713f [project @ 2005-09-03 22:23:59 by bellard]
bellard
parents: 373
diff changeset
919 break;
25f4a44d713f [project @ 2005-09-03 22:23:59 by bellard]
bellard
parents: 373
diff changeset
920 }
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
921 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
922 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
923 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
924 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
925 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
926 skip(')');
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
927 /* NOTE: we do not eat the ';' so that we can restore the current
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
928 token after the assembler parsing */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
929 if (tok != ';')
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
930 expect("';'");
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
931 nb_inputs = nb_operands - nb_outputs;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
932
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
933 /* save all values in the memory */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
934 save_regs(0);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
935
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
936 /* compute constraints */
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
937 asm_compute_constraints(operands, nb_operands, nb_outputs,
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
938 clobber_regs, &out_reg);
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
939
242
244b2df32b67 [project @ 2003-04-14 22:22:34 by bellard]
bellard
parents: 217
diff changeset
940 /* substitute the operands in the asm string. No substitution is
244b2df32b67 [project @ 2003-04-14 22:22:34 by bellard]
bellard
parents: 217
diff changeset
941 done if no operands (GCC behaviour) */
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
942 #ifdef ASM_DEBUG
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
943 printf("asm: \"%s\"\n", (char *)astr.data);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
944 #endif
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
945 if (must_subst) {
242
244b2df32b67 [project @ 2003-04-14 22:22:34 by bellard]
bellard
parents: 217
diff changeset
946 subst_asm_operands(operands, nb_operands, nb_outputs, &astr1, &astr);
244b2df32b67 [project @ 2003-04-14 22:22:34 by bellard]
bellard
parents: 217
diff changeset
947 cstr_free(&astr);
244b2df32b67 [project @ 2003-04-14 22:22:34 by bellard]
bellard
parents: 217
diff changeset
948 } else {
244b2df32b67 [project @ 2003-04-14 22:22:34 by bellard]
bellard
parents: 217
diff changeset
949 astr1 = astr;
244b2df32b67 [project @ 2003-04-14 22:22:34 by bellard]
bellard
parents: 217
diff changeset
950 }
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
951 #ifdef ASM_DEBUG
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
952 printf("subst_asm: \"%s\"\n", (char *)astr1.data);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
953 #endif
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
954
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
955 /* generate loads */
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
956 asm_gen_code(operands, nb_operands, nb_outputs, 0,
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
957 clobber_regs, out_reg);
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
958
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
959 /* assemble the string with tcc internal assembler */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
960 tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
961
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
962 /* restore the current C token */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
963 next();
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
964
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
965 /* store the output values if needed */
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
966 asm_gen_code(operands, nb_operands, nb_outputs, 1,
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
967 clobber_regs, out_reg);
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
968
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
969 /* free everything */
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
970 for(i=0;i<nb_operands;i++) {
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
971 ASMOperand *op;
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
972 op = &operands[i];
481
0f5c38ddf450 Remove MEM_DEBUG and now-useless tcc_free() wrapper. Now, would anyone like to
Rob Landley <rob@landley.net>
parents: 479
diff changeset
973 free(op->constraint);
217
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
974 vpop();
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
975 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
976 cstr_free(&astr1);
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
977 }
d2e6c20b9f28 [project @ 2003-01-06 20:21:42 by bellard]
bellard
parents:
diff changeset
978
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
979 static void asm_global_instr(void)
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
980 {
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
981 CString astr;
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
982
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
983 next();
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
984 parse_asm_str(&astr);
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
985 skip(')');
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
986 /* NOTE: we do not eat the ';' so that we can restore the current
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
987 token after the assembler parsing */
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
988 if (tok != ';')
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
989 expect("';'");
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
990
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
991 #ifdef ASM_DEBUG
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
992 printf("asm_global: \"%s\"\n", (char *)astr.data);
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
993 #endif
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
994 cur_text_section = text_section;
585
7fc19a001568 Rename global gen.c variable ind to gen_ind.
Rob Landley <rob@landley.net>
parents: 572
diff changeset
995 gen_ind = cur_text_section->data_offset;
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
996
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
997 /* assemble the string with tcc internal assembler */
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
998 tcc_assemble_inline(tcc_state, astr.data, astr.size - 1);
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
999
585
7fc19a001568 Rename global gen.c variable ind to gen_ind.
Rob Landley <rob@landley.net>
parents: 572
diff changeset
1000 cur_text_section->data_offset = gen_ind;
318
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
1001
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
1002 /* restore the current C token */
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
1003 next();
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
1004
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
1005 cstr_free(&astr);
0fbfac1441f5 [project @ 2004-10-18 00:19:51 by bellard]
bellard
parents: 302
diff changeset
1006 }