History

Move almost all global variables to TCCState, actually all tests pass on Ubuntu 18.04 x86_64

mingodad committed 5 years ago

Commit af686a71 parent ca1184930 files · +11217 −10750Browse files

Unified · Split

30 files
  1. arm-asm.c +556 −556
  2. arm-gen.c +563 −570
  3. arm-link.c +32 −32
  4. arm64-asm.c +13 −13
  5. arm64-gen.c +641 −647
  6. arm64-link.c +32 −32
  7. c67-gen.c +758 −758
  8. c67-link.c +7 −7
  9. i386-asm.c +187 −187
  10. i386-gen.c +365 −368
  11. i386-link.c +34 −34
  12. libtcc.c +470 −393
  13. libtcc.h +72 −21
  14. riscv64-asm.c +187 −187
  15. riscv64-gen.c +451 −457
  16. riscv64-link.c +30 −30
  17. tcc.c +168 −70
  18. tcc.h +458 −299
  19. tccasm.c +418 −420
  20. tcccoff.c +58 −58
  21. tccelf.c +672 −675
  22. tccgen.c +2636 −2728
  23. tccmacho.c +112 −113
  24. tccpe.c +177 −178
  25. tccpp.c +1063 −1108
  26. tccqsort.c +261 −0
  27. tccrun.c +64 −64
  28. tcctools.c +27 −27
  29. x86_64-gen.c +667 −680
  30. x86_64-link.c +38 −38
arm-asm.c+556−556
@@ -24,9 +24,9 @@ · 23 unmodified lines
24#define CONFIG_TCC_ASM24#define CONFIG_TCC_ASM
25#define NB_ASM_REGS 1625#define NB_ASM_REGS 16
26 26
27ST_FUNC void g(int c);27ST_FUNC void g(TCCState* S, int c);
28ST_FUNC void gen_le16(int c);28ST_FUNC void gen_le16(TCCState* S, int c);
29ST_FUNC void gen_le32(int c);29ST_FUNC void gen_le32(TCCState* S, int c);
30 30
31/*************************************************************/31/*************************************************************/
32#else32#else
@@ -92,7 +92,7 @@ static int asm_parse_vfp_status_regvar(int t) · 59 unmodified lines
92}92}
93 93
94/* Parse a text containing operand and store the result in OP */94/* Parse a text containing operand and store the result in OP */
95static void parse_operand(TCCState *s1, Operand *op)95static void parse_operand(TCCState *S, Operand *op)
96{96{
97 ExprValue e;97 ExprValue e;
98 int8_t reg;98 int8_t reg;
@@ -100,54 +100,54 @@ static void parse_operand(TCCState *s1, Operand *op) · 1 unmodified line
100 100
101 op->type = 0;101 op->type = 0;
102 102
103 if (tok == '{') { // regset literal103 if (S->tccpp_tok == '{') { // regset literal
104 next(); // skip '{'104 next(S); // skip '{'
105 while (tok != '}' && tok != TOK_EOF) {105 while (S->tccpp_tok != '}' && S->tccpp_tok != TOK_EOF) {
106 reg = asm_parse_regvar(tok);106 reg = asm_parse_regvar(S, S->tccpp_tok);
107 if (reg == -1) {107 if (reg == -1) {
108 expect("register");108 expect(S, "register");
109 return;109 return;
110 } else110 } else
111 next(); // skip register name111 next(S); // skip register name
112 112
113 if ((1 << reg) < regset)113 if ((1 << reg) < regset)
114 tcc_warning("registers will be processed in ascending order by hardware--but are not specified in ascending order here");114 tcc_warning(S, "registers will be processed in ascending order by hardware--but are not specified in ascending order here");
115 regset |= 1 << reg;115 regset |= 1 << reg;
116 if (tok != ',')116 if (S->tccpp_tok != ',')
117 break;117 break;
118 next(); // skip ','118 next(S); // skip ','
119 }119 }
120 if (tok != '}')120 if (S->tccpp_tok != '}')
121 expect("'}'");121 expect(S, "'}'");
122 next(); // skip '}'122 next(S); // skip '}'
123 if (regset == 0) {123 if (regset == 0) {
124 // ARM instructions don't support empty regset.124 // ARM instructions don't support empty regset.
125 tcc_error("empty register list is not supported");125 tcc_error(S, "empty register list is not supported");
126 } else {126 } else {
127 op->type = OP_REGSET32;127 op->type = OP_REGSET32;
128 op->regset = regset;128 op->regset = regset;
129 }129 }
130 return;130 return;
131 } else if ((reg = asm_parse_regvar(tok)) != -1) {131 } else if ((reg = asm_parse_regvar(S, S->tccpp_tok)) != -1) {
132 next(); // skip register name132 next(S); // skip register name
133 op->type = OP_REG32;133 op->type = OP_REG32;
134 op->reg = (uint8_t) reg;134 op->reg = (uint8_t) reg;
135 return;135 return;
136 } else if ((reg = asm_parse_vfp_regvar(tok, 0)) != -1) {136 } else if ((reg = asm_parse_vfp_regvar(S->tccpp_tok, 0)) != -1) {
137 next(); // skip register name137 next(S); // skip register name
138 op->type = OP_VREG32;138 op->type = OP_VREG32;
139 op->reg = (uint8_t) reg;139 op->reg = (uint8_t) reg;
140 return;140 return;
141 } else if ((reg = asm_parse_vfp_regvar(tok, 1)) != -1) {141 } else if ((reg = asm_parse_vfp_regvar(S->tccpp_tok, 1)) != -1) {
142 next(); // skip register name142 next(S); // skip register name
143 op->type = OP_VREG64;143 op->type = OP_VREG64;
144 op->reg = (uint8_t) reg;144 op->reg = (uint8_t) reg;
145 return;145 return;
146 } else if (tok == '#' || tok == '$') {146 } else if (S->tccpp_tok == '#' || S->tccpp_tok == '$') {
147 /* constant value */147 /* constant value */
148 next(); // skip '#' or '$'148 next(S); // skip '#' or '$'
149 }149 }
150 asm_expr(s1, &e);150 asm_expr(S, &e);
151 op->type = OP_IM32;151 op->type = OP_IM32;
152 op->e = e;152 op->e = e;
153 if (!op->e.sym) {153 if (!op->e.sym) {
@@ -156,64 +156,64 @@ static void parse_operand(TCCState *s1, Operand *op) · 2 unmodified lines
156 else if (op->e.v == (uint8_t)op->e.v)156 else if (op->e.v == (uint8_t)op->e.v)
157 op->type = OP_IM8;157 op->type = OP_IM8;
158 } else158 } else
159 expect("operand");159 expect(S, "operand");
160}160}
161 161
162/* XXX: make it faster ? */162/* XXX: make it faster ? */
163ST_FUNC void g(int c)163ST_FUNC void g(TCCState* S, int c)
164{164{
165 int ind1;165 int ind1;
166 if (nocode_wanted)166 if (S->tccgen_nocode_wanted)
167 return;167 return;
168 ind1 = ind + 1;168 ind1 = S->tccgen_ind + 1;
169 if (ind1 > cur_text_section->data_allocated)169 if (ind1 > cur_text_section->data_allocated)
170 section_realloc(cur_text_section, ind1);170 section_realloc(S, cur_text_section, ind1);
171 cur_text_section->data[ind] = c;171 cur_text_section->data[S->tccgen_ind] = c;
172 ind = ind1;172 S->tccgen_ind = ind1;
173}173}
174 174
175ST_FUNC void gen_le16 (int i)175ST_FUNC void gen_le16 (TCCState* S, int i)
176{176{
177 g(i);177 g(S, i);
178 g(i>>8);178 g(S, i>>8);
179}179}
180 180
181ST_FUNC void gen_le32 (int i)181ST_FUNC void gen_le32 (TCCState* S, int i)
182{182{
183 int ind1;183 int ind1;
184 if (nocode_wanted)184 if (S->tccgen_nocode_wanted)
185 return;185 return;
186 ind1 = ind + 4;186 ind1 = S->tccgen_ind + 4;
187 if (ind1 > cur_text_section->data_allocated)187 if (ind1 > cur_text_section->data_allocated)
188 section_realloc(cur_text_section, ind1);188 section_realloc(S, cur_text_section, ind1);
189 cur_text_section->data[ind++] = i & 0xFF;189 cur_text_section->data[S->tccgen_ind++] = i & 0xFF;
190 cur_text_section->data[ind++] = (i >> 8) & 0xFF;190 cur_text_section->data[S->tccgen_ind++] = (i >> 8) & 0xFF;
191 cur_text_section->data[ind++] = (i >> 16) & 0xFF;191 cur_text_section->data[S->tccgen_ind++] = (i >> 16) & 0xFF;
192 cur_text_section->data[ind++] = (i >> 24) & 0xFF;192 cur_text_section->data[S->tccgen_ind++] = (i >> 24) & 0xFF;
193}193}
194 194
195ST_FUNC void gen_expr32(ExprValue *pe)195ST_FUNC void gen_expr32(TCCState* S, ExprValue *pe)
196{196{
197 gen_le32(pe->v);197 gen_le32(S, pe->v);
198}198}
199 199
200static uint32_t condition_code_of_token(int token) {200static uint32_t condition_code_of_token(TCCState* S, int token) {
201 if (token < TOK_ASM_nopeq) {201 if (token < TOK_ASM_nopeq) {
202 expect("condition-enabled instruction");202 expect(S, "condition-enabled instruction");
203 return 0;203 return 0;
204 } else204 } else
205 return (token - TOK_ASM_nopeq) & 15;205 return (token - TOK_ASM_nopeq) & 15;
206}206}
207 207
208static void asm_emit_opcode(int token, uint32_t opcode) {208static void asm_emit_opcode(TCCState* S, int token, uint32_t opcode) {
209 gen_le32((condition_code_of_token(token) << 28) | opcode);209 gen_le32(S, (condition_code_of_token(S, token) << 28) | opcode);
210}210}
211 211
212static void asm_emit_unconditional_opcode(uint32_t opcode) {212static void asm_emit_unconditional_opcode(TCCState* S, uint32_t opcode) {
213 gen_le32(opcode);213 gen_le32(S, opcode);
214}214}
215 215
216static void asm_emit_coprocessor_opcode(uint32_t high_nibble, uint8_t cp_number, uint8_t cp_opcode, uint8_t cp_destination_register, uint8_t cp_n_operand_register, uint8_t cp_m_operand_register, uint8_t cp_opcode2, int inter_processor_transfer)216static void asm_emit_coprocessor_opcode(TCCState* S, uint32_t high_nibble, uint8_t cp_number, uint8_t cp_opcode, uint8_t cp_destination_register, uint8_t cp_n_operand_register, uint8_t cp_m_operand_register, uint8_t cp_opcode2, int inter_processor_transfer)
217{217{
218 uint32_t opcode = 0xe000000;218 uint32_t opcode = 0xe000000;
219 if (inter_processor_transfer)219 if (inter_processor_transfer)
@@ -230,69 +230,69 @@ static void asm_emit_coprocessor_opcode(uint32_t high_nibble, uint8_t cp_number, · 10 unmodified lines
230 opcode |= cp_opcode2 << 5;230 opcode |= cp_opcode2 << 5;
231 //assert(cp_m_operand_register < 16);231 //assert(cp_m_operand_register < 16);
232 opcode |= cp_m_operand_register;232 opcode |= cp_m_operand_register;
233 asm_emit_unconditional_opcode((high_nibble << 28) | opcode);233 asm_emit_unconditional_opcode(S, (high_nibble << 28) | opcode);
234}234}
235 235
236static void asm_nullary_opcode(int token)236static void asm_nullary_opcode(TCCState* S, int token)
237{237{
238 switch (ARM_INSTRUCTION_GROUP(token)) {238 switch (ARM_INSTRUCTION_GROUP(token)) {
239 case TOK_ASM_nopeq:239 case TOK_ASM_nopeq:
240 asm_emit_opcode(token, 0xd << 21); // mov r0, r0240 asm_emit_opcode(S, token, 0xd << 21); // mov r0, r0
241 break;241 break;
242 case TOK_ASM_wfeeq:242 case TOK_ASM_wfeeq:
243 asm_emit_opcode(token, 0x320f002);243 asm_emit_opcode(S, token, 0x320f002);
244 case TOK_ASM_wfieq:244 case TOK_ASM_wfieq:
245 asm_emit_opcode(token, 0x320f003);245 asm_emit_opcode(S, token, 0x320f003);
246 break;246 break;
247 default:247 default:
248 expect("nullary instruction");248 expect(S, "nullary instruction");
249 }249 }
250}250}
251 251
252static void asm_unary_opcode(TCCState *s1, int token)252static void asm_unary_opcode(TCCState *S, int token)
253{253{
254 Operand op;254 Operand op;
255 parse_operand(s1, &op);255 parse_operand(S, &op);
256 256
257 switch (ARM_INSTRUCTION_GROUP(token)) {257 switch (ARM_INSTRUCTION_GROUP(token)) {
258 case TOK_ASM_swieq:258 case TOK_ASM_swieq:
259 case TOK_ASM_svceq:259 case TOK_ASM_svceq:
260 if (op.type != OP_IM8)260 if (op.type != OP_IM8)
261 expect("immediate 8-bit unsigned integer");261 expect(S, "immediate 8-bit unsigned integer");
262 else {262 else {
263 /* Note: Dummy operand (ignored by processor): ARM ref documented 0...255, ARM instruction set documented 24 bit */263 /* Note: Dummy operand (ignored by processor): ARM ref documented 0...255, ARM instruction set documented 24 bit */
264 asm_emit_opcode(token, (0xf << 24) | op.e.v);264 asm_emit_opcode(S, token, (0xf << 24) | op.e.v);
265 }265 }
266 break;266 break;
267 default:267 default:
268 expect("unary instruction");268 expect(S, "unary instruction");
269 }269 }
270}270}
271 271
272static void asm_binary_opcode(TCCState *s1, int token)272static void asm_binary_opcode(TCCState *S, int token)
273{273{
274 Operand ops[2];274 Operand ops[2];
275 Operand rotation;275 Operand rotation;
276 uint32_t encoded_rotation = 0;276 uint32_t encoded_rotation = 0;
277 uint64_t amount;277 uint64_t amount;
278 parse_operand(s1, &ops[0]);278 parse_operand(S, &ops[0]);
279 if (tok == ',')279 if (S->tccpp_tok == ',')
280 next();280 next(S);
281 else281 else
282 expect("','");282 expect(S, "','");
283 parse_operand(s1, &ops[1]);283 parse_operand(S, &ops[1]);
284 if (ops[0].type != OP_REG32) {284 if (ops[0].type != OP_REG32) {
285 expect("(destination operand) register");285 expect(S, "(destination operand) register");
286 return;286 return;
287 }287 }
288 288
289 if (ops[0].reg == 15) {289 if (ops[0].reg == 15) {
290 tcc_error("'%s' does not support 'pc' as operand", get_tok_str(token, NULL));290 tcc_error(S, "'%s' does not support 'pc' as operand", get_tok_str(S, token, NULL));
291 return;291 return;
292 }292 }
293 293
294 if (ops[0].reg == 13)294 if (ops[0].reg == 13)
295 tcc_warning("Using 'sp' as operand with '%s' is deprecated by ARM", get_tok_str(token, NULL));295 tcc_warning(S, "Using 'sp' as operand with '%s' is deprecated by ARM", get_tok_str(S, token, NULL));
296 296
297 if (ops[1].type != OP_REG32) {297 if (ops[1].type != OP_REG32) {
298 switch (ARM_INSTRUCTION_GROUP(token)) {298 switch (ARM_INSTRUCTION_GROUP(token)) {
@@ -303,38 +303,38 @@ static void asm_binary_opcode(TCCState *s1, int token) · 4 unmodified lines
303 uint16_t immediate_value = ops[1].e.v;303 uint16_t immediate_value = ops[1].e.v;
304 switch (ARM_INSTRUCTION_GROUP(token)) {304 switch (ARM_INSTRUCTION_GROUP(token)) {
305 case TOK_ASM_movteq:305 case TOK_ASM_movteq:
306 asm_emit_opcode(token, 0x3400000 | (ops[0].reg << 12) | (immediate_value & 0xF000) << 4 | (immediate_value & 0xFFF));306 asm_emit_opcode(S, token, 0x3400000 | (ops[0].reg << 12) | (immediate_value & 0xF000) << 4 | (immediate_value & 0xFFF));
307 break;307 break;
308 case TOK_ASM_movweq:308 case TOK_ASM_movweq:
309 asm_emit_opcode(token, 0x3000000 | (ops[0].reg << 12) | (immediate_value & 0xF000) << 4 | (immediate_value & 0xFFF));309 asm_emit_opcode(S, token, 0x3000000 | (ops[0].reg << 12) | (immediate_value & 0xF000) << 4 | (immediate_value & 0xFFF));
310 break;310 break;
311 }311 }
312 } else312 } else
313 expect("(source operand) immediate 16 bit value");313 expect(S, "(source operand) immediate 16 bit value");
314 } else314 } else
315 expect("(source operand) immediate");315 expect(S, "(source operand) immediate");
316 break;316 break;
317 default:317 default:
318 expect("(source operand) register");318 expect(S, "(source operand) register");
319 }319 }
320 return;320 return;
321 }321 }
322 322
323 if (ops[1].reg == 15) {323 if (ops[1].reg == 15) {
324 tcc_error("'%s' does not support 'pc' as operand", get_tok_str(token, NULL));324 tcc_error(S, "'%s' does not support 'pc' as operand", get_tok_str(S, token, NULL));
325 return;325 return;
326 }326 }
327 327
328 if (ops[1].reg == 13)328 if (ops[1].reg == 13)
329 tcc_warning("Using 'sp' as operand with '%s' is deprecated by ARM", get_tok_str(token, NULL));329 tcc_warning(S, "Using 'sp' as operand with '%s' is deprecated by ARM", get_tok_str(S, token, NULL));
330 330
331 if (tok == ',') {331 if (S->tccpp_tok == ',') {
332 next(); // skip ','332 next(S); // skip ','
333 if (tok == TOK_ASM_ror) {333 if (S->tccpp_tok == TOK_ASM_ror) {
334 next(); // skip 'ror'334 next(S); // skip 'ror'
335 parse_operand(s1, &rotation);335 parse_operand(S, &rotation);
336 if (rotation.type != OP_IM8) {336 if (rotation.type != OP_IM8) {
337 expect("immediate value for rotation");337 expect(S, "immediate value for rotation");
338 return;338 return;
339 } else {339 } else {
340 amount = rotation.e.v;340 amount = rotation.e.v;
@@ -349,7 +349,7 @@ static void asm_binary_opcode(TCCState *s1, int token) · 8 unmodified lines
349 encoded_rotation = 3 << 10;349 encoded_rotation = 3 << 10;
350 break;350 break;
351 default:351 default:
352 expect("'8' or '16' or '24'");352 expect(S, "'8' or '16' or '24'");
353 return;353 return;
354 }354 }
355 }355 }
@@ -358,27 +358,27 @@ static void asm_binary_opcode(TCCState *s1, int token) · 2 unmodified lines
358 switch (ARM_INSTRUCTION_GROUP(token)) {358 switch (ARM_INSTRUCTION_GROUP(token)) {
359 case TOK_ASM_clzeq:359 case TOK_ASM_clzeq:
360 if (encoded_rotation)360 if (encoded_rotation)
361 tcc_error("clz does not support rotation");361 tcc_error(S, "clz does not support rotation");
362 asm_emit_opcode(token, 0x16f0f10 | (ops[0].reg << 12) | ops[1].reg);362 asm_emit_opcode(S, token, 0x16f0f10 | (ops[0].reg << 12) | ops[1].reg);
363 break;363 break;
364 case TOK_ASM_sxtbeq:364 case TOK_ASM_sxtbeq:
365 asm_emit_opcode(token, 0x6af0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation);365 asm_emit_opcode(S, token, 0x6af0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation);
366 break;366 break;
367 case TOK_ASM_sxtheq:367 case TOK_ASM_sxtheq:
368 asm_emit_opcode(token, 0x6bf0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation);368 asm_emit_opcode(S, token, 0x6bf0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation);
369 break;369 break;
370 case TOK_ASM_uxtbeq:370 case TOK_ASM_uxtbeq:
371 asm_emit_opcode(token, 0x6ef0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation);371 asm_emit_opcode(S, token, 0x6ef0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation);
372 break;372 break;
373 case TOK_ASM_uxtheq:373 case TOK_ASM_uxtheq:
374 asm_emit_opcode(token, 0x6ff0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation);374 asm_emit_opcode(S, token, 0x6ff0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation);
375 break;375 break;
376 default:376 default:
377 expect("binary instruction");377 expect(S, "binary instruction");
378 }378 }
379}379}
380 380
381static void asm_coprocessor_opcode(TCCState *s1, int token) {381static void asm_coprocessor_opcode(TCCState *S, int token) {
382 uint8_t coprocessor;382 uint8_t coprocessor;
383 Operand opcode1;383 Operand opcode1;
384 Operand opcode2;384 Operand opcode2;
@@ -387,70 +387,70 @@ static void asm_coprocessor_opcode(TCCState *s1, int token) { · 2 unmodified lines
387 uint8_t high_nibble;387 uint8_t high_nibble;
388 uint8_t mrc = 0;388 uint8_t mrc = 0;
389 389
390 if (tok >= TOK_ASM_p0 && tok <= TOK_ASM_p15) {390 if (S->tccpp_tok >= TOK_ASM_p0 && S->tccpp_tok <= TOK_ASM_p15) {
391 coprocessor = tok - TOK_ASM_p0;391 coprocessor = S->tccpp_tok - TOK_ASM_p0;
392 next();392 next(S);
393 } else {393 } else {
394 expect("'p<number>'");394 expect(S, "'p<number>'");
395 return;395 return;
396 }396 }
397 397
398 if (tok == ',')398 if (S->tccpp_tok == ',')
399 next();399 next(S);
400 else400 else
401 expect("','");401 expect(S, "','");
402 402
403 parse_operand(s1, &opcode1);403 parse_operand(S, &opcode1);
404 if (opcode1.type != OP_IM8 || opcode1.e.v > 15) {404 if (opcode1.type != OP_IM8 || opcode1.e.v > 15) {
405 tcc_error("opcode1 of instruction '%s' must be an immediate value between 0 and 15", get_tok_str(token, NULL));405 tcc_error(S, "opcode1 of instruction '%s' must be an immediate value between 0 and 15", get_tok_str(S, token, NULL));
406 return;406 return;
407 }407 }
408 408
409 for (i = 0; i < 3; ++i) {409 for (i = 0; i < 3; ++i) {
410 if (tok == ',')410 if (S->tccpp_tok == ',')
411 next();411 next(S);
412 else412 else
413 expect("','");413 expect(S, "','");
414 if (i == 0 && token != TOK_ASM_cdp2 && (ARM_INSTRUCTION_GROUP(token) == TOK_ASM_mrceq || ARM_INSTRUCTION_GROUP(token) == TOK_ASM_mcreq)) {414 if (i == 0 && token != TOK_ASM_cdp2 && (ARM_INSTRUCTION_GROUP(token) == TOK_ASM_mrceq || ARM_INSTRUCTION_GROUP(token) == TOK_ASM_mcreq)) {
415 if (tok >= TOK_ASM_r0 && tok <= TOK_ASM_r15) {415 if (S->tccpp_tok >= TOK_ASM_r0 && S->tccpp_tok <= TOK_ASM_r15) {
416 registers[i] = tok - TOK_ASM_r0;416 registers[i] = S->tccpp_tok - TOK_ASM_r0;
417 next();417 next(S);
418 } else {418 } else {
419 expect("'r<number>'");419 expect(S, "'r<number>'");
420 return;420 return;
421 }421 }
422 } else {422 } else {
423 if (tok >= TOK_ASM_c0 && tok <= TOK_ASM_c15) {423 if (S->tccpp_tok >= TOK_ASM_c0 && S->tccpp_tok <= TOK_ASM_c15) {
424 registers[i] = tok - TOK_ASM_c0;424 registers[i] = S->tccpp_tok - TOK_ASM_c0;
425 next();425 next(S);
426 } else {426 } else {
427 expect("'c<number>'");427 expect(S, "'c<number>'");
428 return;428 return;
429 }429 }
430 }430 }
431 }431 }
432 if (tok == ',') {432 if (S->tccpp_tok == ',') {
433 next();433 next(S);
434 parse_operand(s1, &opcode2);434 parse_operand(S, &opcode2);
435 } else {435 } else {
436 opcode2.type = OP_IM8;436 opcode2.type = OP_IM8;
437 opcode2.e.v = 0;437 opcode2.e.v = 0;
438 }438 }
439 if (opcode2.type != OP_IM8 || opcode2.e.v > 15) {439 if (opcode2.type != OP_IM8 || opcode2.e.v > 15) {
440 tcc_error("opcode2 of instruction '%s' must be an immediate value between 0 and 15", get_tok_str(token, NULL));440 tcc_error(S, "opcode2 of instruction '%s' must be an immediate value between 0 and 15", get_tok_str(S, token, NULL));
441 return;441 return;
442 }442 }
443 443
444 if (token == TOK_ASM_cdp2) {444 if (token == TOK_ASM_cdp2) {
445 high_nibble = 0xF;445 high_nibble = 0xF;
446 asm_emit_coprocessor_opcode(high_nibble, coprocessor, opcode1.e.v, registers[0], registers[1], registers[2], opcode2.e.v, 0);446 asm_emit_coprocessor_opcode(S, high_nibble, coprocessor, opcode1.e.v, registers[0], registers[1], registers[2], opcode2.e.v, 0);
447 return;447 return;
448 } else448 } else
449 high_nibble = condition_code_of_token(token);449 high_nibble = condition_code_of_token(S, token);
450 450
451 switch (ARM_INSTRUCTION_GROUP(token)) {451 switch (ARM_INSTRUCTION_GROUP(token)) {
452 case TOK_ASM_cdpeq:452 case TOK_ASM_cdpeq:
453 asm_emit_coprocessor_opcode(high_nibble, coprocessor, opcode1.e.v, registers[0], registers[1], registers[2], opcode2.e.v, 0);453 asm_emit_coprocessor_opcode(S, high_nibble, coprocessor, opcode1.e.v, registers[0], registers[1], registers[2], opcode2.e.v, 0);
454 break;454 break;
455 case TOK_ASM_mrceq:455 case TOK_ASM_mrceq:
456 // opcode1 encoding changes! highest and lowest bit gone.456 // opcode1 encoding changes! highest and lowest bit gone.
@@ -459,13 +459,13 @@ static void asm_coprocessor_opcode(TCCState *s1, int token) { · 2 unmodified lines
459 case TOK_ASM_mcreq:459 case TOK_ASM_mcreq:
460 // opcode1 encoding changes! highest and lowest bit gone.460 // opcode1 encoding changes! highest and lowest bit gone.
461 if (opcode1.e.v > 7) {461 if (opcode1.e.v > 7) {
462 tcc_error("opcode1 of instruction '%s' must be an immediate value between 0 and 7", get_tok_str(token, NULL));462 tcc_error(S, "opcode1 of instruction '%s' must be an immediate value between 0 and 7", get_tok_str(S, token, NULL));
463 return;463 return;
464 }464 }
465 asm_emit_coprocessor_opcode(high_nibble, coprocessor, (opcode1.e.v << 1) | mrc, registers[0], registers[1], registers[2], opcode2.e.v, 1);465 asm_emit_coprocessor_opcode(S, high_nibble, coprocessor, (opcode1.e.v << 1) | mrc, registers[0], registers[1], registers[2], opcode2.e.v, 1);
466 break;466 break;
467 default:467 default:
468 expect("known instruction");468 expect(S, "known instruction");
469 }469 }
470}470}
471 471
@@ -486,27 +486,27 @@ static void asm_coprocessor_opcode(TCCState *s1, int token) { · 14 unmodified lines
486#define ENCODE_BARREL_SHIFTER_REGISTER(register_index) ((register_index) << 8)486#define ENCODE_BARREL_SHIFTER_REGISTER(register_index) ((register_index) << 8)
487#define ENCODE_BARREL_SHIFTER_IMMEDIATE(value) ((value) << 7)487#define ENCODE_BARREL_SHIFTER_IMMEDIATE(value) ((value) << 7)
488 488
489static void asm_block_data_transfer_opcode(TCCState *s1, int token)489static void asm_block_data_transfer_opcode(TCCState *S, int token)
490{490{
491 uint32_t opcode;491 uint32_t opcode;
492 int op0_exclam = 0;492 int op0_exclam = 0;
493 Operand ops[2];493 Operand ops[2];
494 int nb_ops = 1;494 int nb_ops = 1;
495 parse_operand(s1, &ops[0]);495 parse_operand(S, &ops[0]);
496 if (tok == '!') {496 if (S->tccpp_tok == '!') {
497 op0_exclam = 1;497 op0_exclam = 1;
498 next(); // skip '!'498 next(S); // skip '!'
499 }499 }
500 if (tok == ',') {500 if (S->tccpp_tok == ',') {
501 next(); // skip comma501 next(S); // skip comma
502 parse_operand(s1, &ops[1]);502 parse_operand(S, &ops[1]);
503 ++nb_ops;503 ++nb_ops;
504 }504 }
505 if (nb_ops < 1) {505 if (nb_ops < 1) {
506 expect("at least one operand");506 expect(S, "at least one operand");
507 return;507 return;
508 } else if (ops[nb_ops - 1].type != OP_REGSET32) {508 } else if (ops[nb_ops - 1].type != OP_REGSET32) {
509 expect("(last operand) register list");509 expect(S, "(last operand) register list");
510 return;510 return;
511 }511 }
512 512
@@ -522,9 +522,9 @@ static void asm_block_data_transfer_opcode(TCCState *s1, int token) · 9 unmodified lines
522 // Rn: base register522 // Rn: base register
523 // Register List: bits 15...0523 // Register List: bits 15...0
524 if (nb_ops != 1)524 if (nb_ops != 1)
525 expect("exactly one operand");525 expect(S, "exactly one operand");
526 else526 else
527 asm_emit_opcode(token, (0x92d << 16) | ops[0].regset); // TODO: base register ?527 asm_emit_opcode(S, token, (0x92d << 16) | ops[0].regset); // TODO: base register ?
528 break;528 break;
529 case TOK_ASM_popeq: // TODO: Optimize 1-register case to: ldr ?, [sp], #4529 case TOK_ASM_popeq: // TODO: Optimize 1-register case to: ldr ?, [sp], #4
530 // Instruction: 1 I=0 P=0 U=1 S=0 W=0 L=1 << 20, op 1101530 // Instruction: 1 I=0 P=0 U=1 S=0 W=0 L=1 << 20, op 1101
@@ -532,9 +532,9 @@ static void asm_block_data_transfer_opcode(TCCState *s1, int token) · 1 unmodified line
532 // Rn: base register532 // Rn: base register
533 // Register List: bits 15...0533 // Register List: bits 15...0
534 if (nb_ops != 1)534 if (nb_ops != 1)
535 expect("exactly one operand");535 expect(S, "exactly one operand");
536 else536 else
537 asm_emit_opcode(token, (0x8bd << 16) | ops[0].regset); // TODO: base register ?537 asm_emit_opcode(S, token, (0x8bd << 16) | ops[0].regset); // TODO: base register ?
538 break;538 break;
539 case TOK_ASM_stmdaeq:539 case TOK_ASM_stmdaeq:
540 case TOK_ASM_ldmdaeq:540 case TOK_ASM_ldmdaeq:
@@ -574,23 +574,23 @@ static void asm_block_data_transfer_opcode(TCCState *s1, int token) · 33 unmodified lines
574 opcode = 0x99 << 20;574 opcode = 0x99 << 20;
575 break;575 break;
576 default:576 default:
577 tcc_error("internal error: This place should not be reached (fallback in asm_block_data_transfer_opcode)");577 tcc_error(S, "internal error: This place should not be reached (fallback in asm_block_data_transfer_opcode)");
578 }578 }
579 // operands:579 // operands:
580 // Rn: first operand580 // Rn: first operand
581 // Register List: lower bits581 // Register List: lower bits
582 if (nb_ops != 2)582 if (nb_ops != 2)
583 expect("exactly two operands");583 expect(S, "exactly two operands");
584 else if (ops[0].type != OP_REG32)584 else if (ops[0].type != OP_REG32)
585 expect("(first operand) register");585 expect(S, "(first operand) register");
586 else {586 else {
587 if (op0_exclam)587 if (op0_exclam)
588 opcode |= 1 << 21; // writeback588 opcode |= 1 << 21; // writeback
589 asm_emit_opcode(token, opcode | ENCODE_RN(ops[0].reg) | ops[1].regset);589 asm_emit_opcode(S, token, opcode | ENCODE_RN(ops[0].reg) | ops[1].regset);
590 }590 }
591 break;591 break;
592 default:592 default:
593 expect("block data transfer instruction");593 expect(S, "block data transfer instruction");
594 }594 }
595}595}
596 596
@@ -600,17 +600,17 @@ static void asm_block_data_transfer_opcode(TCCState *s1, int token) · 3 unmodified lines
600 600
601 NB_SHIFT: will be set to 1 iff SHIFT is filled. Note that for rrx, there's no need to fill SHIFT.601 NB_SHIFT: will be set to 1 iff SHIFT is filled. Note that for rrx, there's no need to fill SHIFT.
602 SHIFT: will be filled in with the shift operand to use, if any. */602 SHIFT: will be filled in with the shift operand to use, if any. */
603static uint32_t asm_parse_optional_shift(TCCState* s1, int* nb_shift, Operand* shift)603static uint32_t asm_parse_optional_shift(TCCState* S, int* nb_shift, Operand* shift)
604{604{
605 uint32_t opcode = 0;605 uint32_t opcode = 0;
606 *nb_shift = 0;606 *nb_shift = 0;
607 switch (tok) {607 switch (S->tccpp_tok) {
608 case TOK_ASM_asl:608 case TOK_ASM_asl:
609 case TOK_ASM_lsl:609 case TOK_ASM_lsl:
610 case TOK_ASM_asr:610 case TOK_ASM_asr:
611 case TOK_ASM_lsr:611 case TOK_ASM_lsr:
612 case TOK_ASM_ror:612 case TOK_ASM_ror:
613 switch (tok) {613 switch (S->tccpp_tok) {
614 case TOK_ASM_asl:614 case TOK_ASM_asl:
615 /* fallthrough */615 /* fallthrough */
616 case TOK_ASM_lsl:616 case TOK_ASM_lsl:
@@ -626,26 +626,26 @@ static uint32_t asm_parse_optional_shift(TCCState* s1, int* nb_shift, Operand* s · 9 unmodified lines
626 opcode = ENCODE_BARREL_SHIFTER_MODE_ROR;626 opcode = ENCODE_BARREL_SHIFTER_MODE_ROR;
627 break;627 break;
628 }628 }
629 next();629 next(S);
630 parse_operand(s1, shift);630 parse_operand(S, shift);
631 *nb_shift = 1;631 *nb_shift = 1;
632 break;632 break;
633 case TOK_ASM_rrx:633 case TOK_ASM_rrx:
634 next();634 next(S);
635 opcode = ENCODE_BARREL_SHIFTER_MODE_ROR;635 opcode = ENCODE_BARREL_SHIFTER_MODE_ROR;
636 break;636 break;
637 }637 }
638 return opcode;638 return opcode;
639}639}
640 640
641static uint32_t asm_encode_shift(Operand* shift)641static uint32_t asm_encode_shift(TCCState *S, Operand* shift)
642{642{
643 uint64_t amount;643 uint64_t amount;
644 uint32_t operands = 0;644 uint32_t operands = 0;
645 switch (shift->type) {645 switch (shift->type) {
646 case OP_REG32:646 case OP_REG32:
647 if (shift->reg == 15)647 if (shift->reg == 15)
648 tcc_error("r15 cannot be used as a shift count");648 tcc_error(S, "r15 cannot be used as a shift count");
649 else {649 else {
650 operands = ENCODE_BARREL_SHIFTER_SHIFT_BY_REGISTER;650 operands = ENCODE_BARREL_SHIFTER_SHIFT_BY_REGISTER;
651 operands |= ENCODE_BARREL_SHIFTER_REGISTER(shift->reg);651 operands |= ENCODE_BARREL_SHIFTER_REGISTER(shift->reg);
@@ -656,15 +656,15 @@ static uint32_t asm_encode_shift(Operand* shift) · 4 unmodified lines
656 if (amount > 0 && amount < 32)656 if (amount > 0 && amount < 32)
657 operands = ENCODE_BARREL_SHIFTER_IMMEDIATE(amount);657 operands = ENCODE_BARREL_SHIFTER_IMMEDIATE(amount);
658 else658 else
659 tcc_error("shift count out of range");659 tcc_error(S, "shift count out of range");
660 break;660 break;
661 default:661 default:
662 tcc_error("unknown shift amount");662 tcc_error(S, "unknown shift amount");
663 }663 }
664 return operands;664 return operands;
665}665}
666 666
667static void asm_data_processing_opcode(TCCState *s1, int token)667static void asm_data_processing_opcode(TCCState *S, int token)
668{668{
669 Operand ops[3];669 Operand ops[3];
670 int nb_ops;670 int nb_ops;
@@ -677,31 +677,31 @@ static void asm_data_processing_opcode(TCCState *s1, int token) · 6 unmodified lines
677 uint32_t opcode_nos = opcode_idx >> 1; // without "s"; "OpCode" in ARM docs677 uint32_t opcode_nos = opcode_idx >> 1; // without "s"; "OpCode" in ARM docs
678 678
679 for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ) {679 for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ) {
680 if (tok == TOK_ASM_asl || tok == TOK_ASM_lsl || tok == TOK_ASM_lsr || tok == TOK_ASM_asr || tok == TOK_ASM_ror || tok == TOK_ASM_rrx)680 if (S->tccpp_tok == TOK_ASM_asl || S->tccpp_tok == TOK_ASM_lsl || S->tccpp_tok == TOK_ASM_lsr || S->tccpp_tok == TOK_ASM_asr || S->tccpp_tok == TOK_ASM_ror || S->tccpp_tok == TOK_ASM_rrx)
681 break;681 break;
682 parse_operand(s1, &ops[nb_ops]);682 parse_operand(S, &ops[nb_ops]);
683 ++nb_ops;683 ++nb_ops;
684 if (tok != ',')684 if (S->tccpp_tok != ',')
685 break;685 break;
686 next(); // skip ','686 next(S); // skip ','
687 }687 }
688 if (tok == ',')688 if (S->tccpp_tok == ',')
689 next();689 next(S);
690 operands |= asm_parse_optional_shift(s1, &nb_shift, &shift);690 operands |= asm_parse_optional_shift(S, &nb_shift, &shift);
691 if (nb_ops < 2)691 if (nb_ops < 2)
692 expect("at least two operands");692 expect(S, "at least two operands");
693 else if (nb_ops == 2) {693 else if (nb_ops == 2) {
694 memcpy(&ops[2], &ops[1], sizeof(ops[1])); // move ops[2]694 memcpy(&ops[2], &ops[1], sizeof(ops[1])); // move ops[2]
695 memcpy(&ops[1], &ops[0], sizeof(ops[0])); // ops[1] was implicit695 memcpy(&ops[1], &ops[0], sizeof(ops[0])); // ops[1] was implicit
696 nb_ops = 3;696 nb_ops = 3;
697 } else if (nb_ops == 3) {697 } else if (nb_ops == 3) {
698 if (opcode_nos == 0xd || opcode_nos == 0xf || opcode_nos == 0xa || opcode_nos == 0xb || opcode_nos == 0x8 || opcode_nos == 0x9) { // mov, mvn, cmp, cmn, tst, teq698 if (opcode_nos == 0xd || opcode_nos == 0xf || opcode_nos == 0xa || opcode_nos == 0xb || opcode_nos == 0x8 || opcode_nos == 0x9) { // mov, mvn, cmp, cmn, tst, teq
699 tcc_error("'%s' cannot be used with three operands", get_tok_str(token, NULL));699 tcc_error(S, "'%s' cannot be used with three operands", get_tok_str(S, token, NULL));
700 return;700 return;
701 }701 }
702 }702 }
703 if (nb_ops != 3) {703 if (nb_ops != 3) {
704 expect("two or three operands");704 expect(S, "two or three operands");
705 return;705 return;
706 } else {706 } else {
707 uint32_t opcode = 0;707 uint32_t opcode = 0;
@@ -710,7 +710,7 @@ static void asm_data_processing_opcode(TCCState *s1, int token) · 2 unmodified lines
710 if (nb_shift && shift.type == OP_REG32) {710 if (nb_shift && shift.type == OP_REG32) {
711 if ((ops[0].type == OP_REG32 && ops[0].reg == 15) ||711 if ((ops[0].type == OP_REG32 && ops[0].reg == 15) ||
712 (ops[1].type == OP_REG32 && ops[1].reg == 15)) {712 (ops[1].type == OP_REG32 && ops[1].reg == 15)) {
713 tcc_error("Using the 'pc' register in data processing instructions that have a register-controlled shift is not implemented by ARM");713 tcc_error(S, "Using the 'pc' register in data processing instructions that have a register-controlled shift is not implemented by ARM");
714 return;714 return;
715 }715 }
716 }716 }
@@ -726,13 +726,13 @@ static void asm_data_processing_opcode(TCCState *s1, int token) · 9 unmodified lines
726 /* operations in the token list are ordered by opcode */726 /* operations in the token list are ordered by opcode */
727 opcode = opcode_nos << 21; // drop "s"727 opcode = opcode_nos << 21; // drop "s"
728 if (ops[0].type != OP_REG32)728 if (ops[0].type != OP_REG32)
729 expect("(destination operand) register");729 expect(S, "(destination operand) register");
730 else if (opcode_nos == 0xa || opcode_nos == 0xb || opcode_nos == 0x8 || opcode_nos == 0x9) // cmp, cmn, tst, teq730 else if (opcode_nos == 0xa || opcode_nos == 0xb || opcode_nos == 0x8 || opcode_nos == 0x9) // cmp, cmn, tst, teq
731 operands |= ENCODE_SET_CONDITION_CODES; // force S set, otherwise it's a completely different instruction.731 operands |= ENCODE_SET_CONDITION_CODES; // force S set, otherwise it's a completely different instruction.
732 else732 else
733 operands |= ENCODE_RD(ops[0].reg);733 operands |= ENCODE_RD(ops[0].reg);
734 if (ops[1].type != OP_REG32)734 if (ops[1].type != OP_REG32)
735 expect("(first source operand) register");735 expect(S, "(first source operand) register");
736 else if (!(opcode_nos == 0xd || opcode_nos == 0xf)) // not: mov, mvn (those have only one source operand)736 else if (!(opcode_nos == 0xd || opcode_nos == 0xf)) // not: mov, mvn (those have only one source operand)
737 operands |= ENCODE_RN(ops[1].reg);737 operands |= ENCODE_RN(ops[1].reg);
738 switch (ops[2].type) {738 switch (ops[2].type) {
@@ -809,7 +809,7 @@ static void asm_data_processing_opcode(TCCState *s1, int token) · 70 unmodified lines
809 immediate_value = ~immediate_value;809 immediate_value = ~immediate_value;
810 break;810 break;
811 default:811 default:
812 tcc_error("cannot use '%s' with a negative immediate value", get_tok_str(token, NULL));812 tcc_error(S, "cannot use '%s' with a negative immediate value", get_tok_str(S, token, NULL));
813 }813 }
814 for (half_immediate_rotation = 0; half_immediate_rotation < 16; ++half_immediate_rotation) {814 for (half_immediate_rotation = 0; half_immediate_rotation < 16; ++half_immediate_rotation) {
815 if (immediate_value >= 0x00 && immediate_value < 0x100)815 if (immediate_value >= 0x00 && immediate_value < 0x100)
@@ -819,30 +819,30 @@ static void asm_data_processing_opcode(TCCState *s1, int token) · 3 unmodified lines
819 }819 }
820 if (half_immediate_rotation >= 16) {820 if (half_immediate_rotation >= 16) {
821 immediate_value = ops[2].e.v;821 immediate_value = ops[2].e.v;
822 tcc_error("immediate value 0x%X cannot be encoded into ARM immediate", (unsigned) immediate_value);822 tcc_error(S, "immediate value 0x%X cannot be encoded into ARM immediate", (unsigned) immediate_value);
823 return;823 return;
824 }824 }
825 operands |= immediate_value;825 operands |= immediate_value;
826 operands |= half_immediate_rotation << 8;826 operands |= half_immediate_rotation << 8;
827 break;827 break;
828 default:828 default:
829 expect("(second source operand) register or immediate value");829 expect(S, "(second source operand) register or immediate value");
830 }830 }
831 831
832 if (nb_shift) {832 if (nb_shift) {
833 if (operands & ENCODE_IMMEDIATE_FLAG)833 if (operands & ENCODE_IMMEDIATE_FLAG)
834 tcc_error("immediate rotation not implemented");834 tcc_error(S, "immediate rotation not implemented");
835 else835 else
836 operands |= asm_encode_shift(&shift);836 operands |= asm_encode_shift(S, &shift);
837 }837 }
838 838
839 /* S=0 and S=1 entries alternate one after another, in that order */839 /* S=0 and S=1 entries alternate one after another, in that order */
840 opcode |= (opcode_idx & 1) ? ENCODE_SET_CONDITION_CODES : 0;840 opcode |= (opcode_idx & 1) ? ENCODE_SET_CONDITION_CODES : 0;
841 asm_emit_opcode(token, opcode | operands);841 asm_emit_opcode(S, token, opcode | operands);
842 }842 }
843}843}
844 844
845static void asm_shift_opcode(TCCState *s1, int token)845static void asm_shift_opcode(TCCState *S, int token)
846{846{
847 Operand ops[3];847 Operand ops[3];
848 int nb_ops;848 int nb_ops;
@@ -851,20 +851,20 @@ static void asm_shift_opcode(TCCState *s1, int token) · 2 unmodified lines
851 uint32_t operands = 0;851 uint32_t operands = 0;
852 852
853 for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) {853 for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) {
854 parse_operand(s1, &ops[nb_ops]);854 parse_operand(S, &ops[nb_ops]);
855 if (tok != ',') {855 if (S->tccpp_tok != ',') {
856 ++nb_ops;856 ++nb_ops;
857 break;857 break;
858 }858 }
859 next(); // skip ','859 next(S); // skip ','
860 }860 }
861 if (nb_ops < 2) {861 if (nb_ops < 2) {
862 expect("at least two operands");862 expect(S, "at least two operands");
863 return;863 return;
864 }864 }
865 865
866 if (ops[0].type != OP_REG32) {866 if (ops[0].type != OP_REG32) {
867 expect("(destination operand) register");867 expect(S, "(destination operand) register");
868 return;868 return;
869 } else869 } else
870 operands |= ENCODE_RD(ops[0].reg);870 operands |= ENCODE_RD(ops[0].reg);
@@ -878,9 +878,9 @@ static void asm_shift_opcode(TCCState *s1, int token) · 7 unmodified lines
878 if (ops[1].type == OP_REG32) {878 if (ops[1].type == OP_REG32) {
879 operands |= ops[1].reg;879 operands |= ops[1].reg;
880 operands |= ENCODE_BARREL_SHIFTER_MODE_ROR;880 operands |= ENCODE_BARREL_SHIFTER_MODE_ROR;
881 asm_emit_opcode(token, opcode | operands);881 asm_emit_opcode(S, token, opcode | operands);
882 } else882 } else
883 tcc_error("(first source operand) register");883 tcc_error(S, "(first source operand) register");
884 return;884 return;
885 default:885 default:
886 memcpy(&ops[2], &ops[1], sizeof(ops[1])); // move ops[2]886 memcpy(&ops[2], &ops[1], sizeof(ops[1])); // move ops[2]
@@ -889,7 +889,7 @@ static void asm_shift_opcode(TCCState *s1, int token) · 2 unmodified lines
889 }889 }
890 }890 }
891 if (nb_ops != 3) {891 if (nb_ops != 3) {
892 expect("two or three operands");892 expect(S, "two or three operands");
893 return;893 return;
894 }894 }
895 895
@@ -909,7 +909,7 @@ static void asm_shift_opcode(TCCState *s1, int token) · 13 unmodified lines
909 case OP_IM8:909 case OP_IM8:
910 operands |= ENCODE_IMMEDIATE_FLAG;910 operands |= ENCODE_IMMEDIATE_FLAG;
911 operands |= ops[1].e.v;911 operands |= ops[1].e.v;
912 tcc_error("Using an immediate value as the source operand is not possible with '%s' instruction on ARM", get_tok_str(token, NULL));912 tcc_error(S, "Using an immediate value as the source operand is not possible with '%s' instruction on ARM", get_tok_str(S, token, NULL));
913 return;913 return;
914 }914 }
915 915
@@ -917,13 +917,13 @@ static void asm_shift_opcode(TCCState *s1, int token) · 1 unmodified line
917 case OP_REG32:917 case OP_REG32:
918 if ((ops[0].type == OP_REG32 && ops[0].reg == 15) ||918 if ((ops[0].type == OP_REG32 && ops[0].reg == 15) ||
919 (ops[1].type == OP_REG32 && ops[1].reg == 15)) {919 (ops[1].type == OP_REG32 && ops[1].reg == 15)) {
920 tcc_error("Using the 'pc' register in data processing instructions that have a register-controlled shift is not implemented by ARM");920 tcc_error(S, "Using the 'pc' register in data processing instructions that have a register-controlled shift is not implemented by ARM");
921 }921 }
922 operands |= asm_encode_shift(&ops[2]);922 operands |= asm_encode_shift(S, &ops[2]);
923 break;923 break;
924 case OP_IM8:924 case OP_IM8:
925 if (ops[2].e.v)925 if (ops[2].e.v)
926 operands |= asm_encode_shift(&ops[2]);926 operands |= asm_encode_shift(S, &ops[2]);
927 else927 else
928 definitely_neutral = 1;928 definitely_neutral = 1;
929 break;929 break;
@@ -947,28 +947,28 @@ static void asm_shift_opcode(TCCState *s1, int token) · 17 unmodified lines
947 operands |= ENCODE_BARREL_SHIFTER_MODE_ROR;947 operands |= ENCODE_BARREL_SHIFTER_MODE_ROR;
948 break;948 break;
949 default:949 default:
950 expect("shift instruction");950 expect(S, "shift instruction");
951 return;951 return;
952 }952 }
953 asm_emit_opcode(token, opcode | operands);953 asm_emit_opcode(S, token, opcode | operands);
954}954}
955 955
956static void asm_multiplication_opcode(TCCState *s1, int token)956static void asm_multiplication_opcode(TCCState *S, int token)
957{957{
958 Operand ops[4];958 Operand ops[4];
959 int nb_ops = 0;959 int nb_ops = 0;
960 uint32_t opcode = 0x90;960 uint32_t opcode = 0x90;
961 961
962 for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) {962 for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) {
963 parse_operand(s1, &ops[nb_ops]);963 parse_operand(S, &ops[nb_ops]);
964 if (tok != ',') {964 if (S->tccpp_tok != ',') {
965 ++nb_ops;965 ++nb_ops;
966 break;966 break;
967 }967 }
968 next(); // skip ','968 next(S); // skip ','
969 }969 }
970 if (nb_ops < 2)970 if (nb_ops < 2)
971 expect("at least two operands");971 expect(S, "at least two operands");
972 else if (nb_ops == 2) {972 else if (nb_ops == 2) {
973 switch (ARM_INSTRUCTION_GROUP(token)) {973 switch (ARM_INSTRUCTION_GROUP(token)) {
974 case TOK_ASM_mulseq:974 case TOK_ASM_mulseq:
@@ -976,7 +976,7 @@ static void asm_multiplication_opcode(TCCState *s1, int token) · 1 unmodified line
976 memcpy(&ops[2], &ops[0], sizeof(ops[1])); // ARM is actually like this!976 memcpy(&ops[2], &ops[0], sizeof(ops[1])); // ARM is actually like this!
977 break;977 break;
978 default:978 default:
979 expect("at least three operands");979 expect(S, "at least three operands");
980 return;980 return;
981 }981 }
982 nb_ops = 3;982 nb_ops = 3;
@@ -992,20 +992,20 @@ static void asm_multiplication_opcode(TCCState *s1, int token) · 9 unmodified lines
992 if (ops[0].type == OP_REG32)992 if (ops[0].type == OP_REG32)
993 opcode |= ops[0].reg << 16;993 opcode |= ops[0].reg << 16;
994 else994 else
995 expect("(destination operand) register");995 expect(S, "(destination operand) register");
996 if (ops[1].type == OP_REG32)996 if (ops[1].type == OP_REG32)
997 opcode |= ops[1].reg;997 opcode |= ops[1].reg;
998 else998 else
999 expect("(first source operand) register");999 expect(S, "(first source operand) register");
1000 if (ops[2].type == OP_REG32)1000 if (ops[2].type == OP_REG32)
1001 opcode |= ops[2].reg << 8;1001 opcode |= ops[2].reg << 8;
1002 else1002 else
1003 expect("(second source operand) register");1003 expect(S, "(second source operand) register");
1004 if (nb_ops > 3) {1004 if (nb_ops > 3) {
1005 if (ops[3].type == OP_REG32)1005 if (ops[3].type == OP_REG32)
1006 opcode |= ops[3].reg << 12;1006 opcode |= ops[3].reg << 12;
1007 else1007 else
1008 expect("(third source operand) register");1008 expect(S, "(third source operand) register");
1009 }1009 }
1010 1010
1011 switch (ARM_INSTRUCTION_GROUP(token)) {1011 switch (ARM_INSTRUCTION_GROUP(token)) {
@@ -1014,9 +1014,9 @@ static void asm_multiplication_opcode(TCCState *s1, int token) · 2 unmodified lines
1014 /* fallthrough */1014 /* fallthrough */
1015 case TOK_ASM_muleq:1015 case TOK_ASM_muleq:
1016 if (nb_ops != 3)1016 if (nb_ops != 3)
1017 expect("three operands");1017 expect(S, "three operands");
1018 else {1018 else {
1019 asm_emit_opcode(token, opcode);1019 asm_emit_opcode(S, token, opcode);
1020 }1020 }
1021 break;1021 break;
1022 case TOK_ASM_mlaseq:1022 case TOK_ASM_mlaseq:
@@ -1024,33 +1024,33 @@ static void asm_multiplication_opcode(TCCState *s1, int token) · 1 unmodified line
1024 /* fallthrough */1024 /* fallthrough */
1025 case TOK_ASM_mlaeq:1025 case TOK_ASM_mlaeq:
1026 if (nb_ops != 4)1026 if (nb_ops != 4)
1027 expect("four operands");1027 expect(S, "four operands");
1028 else {1028 else {
1029 opcode |= 1 << 21; // Accumulate1029 opcode |= 1 << 21; // Accumulate
1030 asm_emit_opcode(token, opcode);1030 asm_emit_opcode(S, token, opcode);
1031 }1031 }
1032 break;1032 break;
1033 default:1033 default:
1034 expect("known multiplication instruction");1034 expect(S, "known multiplication instruction");
1035 }1035 }
1036}1036}
1037 1037
1038static void asm_long_multiplication_opcode(TCCState *s1, int token)1038static void asm_long_multiplication_opcode(TCCState *S, int token)
1039{1039{
1040 Operand ops[4];1040 Operand ops[4];
1041 int nb_ops = 0;1041 int nb_ops = 0;
1042 uint32_t opcode = 0x90 | (1 << 23);1042 uint32_t opcode = 0x90 | (1 << 23);
1043 1043
1044 for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) {1044 for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) {
1045 parse_operand(s1, &ops[nb_ops]);1045 parse_operand(S, &ops[nb_ops]);
1046 if (tok != ',') {1046 if (S->tccpp_tok != ',') {
1047 ++nb_ops;1047 ++nb_ops;
1048 break;1048 break;
1049 }1049 }
1050 next(); // skip ','1050 next(S); // skip ','
1051 }1051 }
1052 if (nb_ops != 4) {1052 if (nb_ops != 4) {
1053 expect("four operands");1053 expect(S, "four operands");
1054 return;1054 return;
1055 }1055 }
1056 1056
@@ -1064,19 +1064,19 @@ static void asm_long_multiplication_opcode(TCCState *s1, int token) · 7 unmodified lines
1064 if (ops[0].type == OP_REG32)1064 if (ops[0].type == OP_REG32)
1065 opcode |= ops[0].reg << 12;1065 opcode |= ops[0].reg << 12;
1066 else1066 else
1067 expect("(destination lo accumulator) register");1067 expect(S, "(destination lo accumulator) register");
1068 if (ops[1].type == OP_REG32)1068 if (ops[1].type == OP_REG32)
1069 opcode |= ops[1].reg << 16;1069 opcode |= ops[1].reg << 16;
1070 else1070 else
1071 expect("(destination hi accumulator) register");1071 expect(S, "(destination hi accumulator) register");
1072 if (ops[2].type == OP_REG32)1072 if (ops[2].type == OP_REG32)
1073 opcode |= ops[2].reg;1073 opcode |= ops[2].reg;
1074 else1074 else
1075 expect("(first source operand) register");1075 expect(S, "(first source operand) register");
1076 if (ops[3].type == OP_REG32)1076 if (ops[3].type == OP_REG32)
1077 opcode |= ops[3].reg << 8;1077 opcode |= ops[3].reg << 8;
1078 else1078 else
1079 expect("(second source operand) register");1079 expect(S, "(second source operand) register");
1080 1080
1081 switch (ARM_INSTRUCTION_GROUP(token)) {1081 switch (ARM_INSTRUCTION_GROUP(token)) {
1082 case TOK_ASM_smullseq:1082 case TOK_ASM_smullseq:
@@ -1084,13 +1084,13 @@ static void asm_long_multiplication_opcode(TCCState *s1, int token) · 1 unmodified line
1084 /* fallthrough */1084 /* fallthrough */
1085 case TOK_ASM_smulleq:1085 case TOK_ASM_smulleq:
1086 opcode |= 1 << 22; // signed1086 opcode |= 1 << 22; // signed
1087 asm_emit_opcode(token, opcode);1087 asm_emit_opcode(S, token, opcode);
1088 break;1088 break;
1089 case TOK_ASM_umullseq:1089 case TOK_ASM_umullseq:
1090 opcode |= 1 << 20; // Status1090 opcode |= 1 << 20; // Status
1091 /* fallthrough */1091 /* fallthrough */
1092 case TOK_ASM_umulleq:1092 case TOK_ASM_umulleq:
1093 asm_emit_opcode(token, opcode);1093 asm_emit_opcode(S, token, opcode);
1094 break;1094 break;
1095 case TOK_ASM_smlalseq:1095 case TOK_ASM_smlalseq:
1096 opcode |= 1 << 20; // Status1096 opcode |= 1 << 20; // Status
@@ -1098,21 +1098,21 @@ static void asm_long_multiplication_opcode(TCCState *s1, int token) · 1 unmodified line
1098 case TOK_ASM_smlaleq:1098 case TOK_ASM_smlaleq:
1099 opcode |= 1 << 22; // signed1099 opcode |= 1 << 22; // signed
1100 opcode |= 1 << 21; // Accumulate1100 opcode |= 1 << 21; // Accumulate
1101 asm_emit_opcode(token, opcode);1101 asm_emit_opcode(S, token, opcode);
1102 break;1102 break;
1103 case TOK_ASM_umlalseq:1103 case TOK_ASM_umlalseq:
1104 opcode |= 1 << 20; // Status1104 opcode |= 1 << 20; // Status
1105 /* fallthrough */1105 /* fallthrough */
1106 case TOK_ASM_umlaleq:1106 case TOK_ASM_umlaleq:
1107 opcode |= 1 << 21; // Accumulate1107 opcode |= 1 << 21; // Accumulate
1108 asm_emit_opcode(token, opcode);1108 asm_emit_opcode(S, token, opcode);
1109 break;1109 break;
1110 default:1110 default:
1111 expect("known long multiplication instruction");1111 expect(S, "known long multiplication instruction");
1112 }1112 }
1113}1113}
1114 1114
1115static void asm_single_data_transfer_opcode(TCCState *s1, int token)1115static void asm_single_data_transfer_opcode(TCCState *S, int token)
1116{1116{
1117 Operand ops[3];1117 Operand ops[3];
1118 Operand strex_operand;1118 Operand strex_operand;
@@ -1126,67 +1126,67 @@ static void asm_single_data_transfer_opcode(TCCState *s1, int token) · 7 unmodified lines
1126 // Note: ldr r0, [r4, #4]! ; pre-indexed: r0 = *(int*)(r4+4); r4 = r4+41126 // Note: ldr r0, [r4, #4]! ; pre-indexed: r0 = *(int*)(r4+4); r4 = r4+4
1127 // Note: ldr r0, [r4], #4 ; post-indexed: r0 = *(int*)(r4+0); r4 = r4+41127 // Note: ldr r0, [r4], #4 ; post-indexed: r0 = *(int*)(r4+0); r4 = r4+4
1128 1128
1129 parse_operand(s1, &ops[0]);1129 parse_operand(S, &ops[0]);
1130 if (ops[0].type == OP_REG32)1130 if (ops[0].type == OP_REG32)
1131 opcode |= ENCODE_RD(ops[0].reg);1131 opcode |= ENCODE_RD(ops[0].reg);
1132 else {1132 else {
1133 expect("(destination operand) register");1133 expect(S, "(destination operand) register");
1134 return;1134 return;
1135 }1135 }
1136 if (tok != ',')1136 if (S->tccpp_tok != ',')
1137 expect("at least two arguments");1137 expect(S, "at least two arguments");
1138 else1138 else
1139 next(); // skip ','1139 next(S); // skip ','
1140 1140
1141 switch (ARM_INSTRUCTION_GROUP(token)) {1141 switch (ARM_INSTRUCTION_GROUP(token)) {
1142 case TOK_ASM_strexbeq:1142 case TOK_ASM_strexbeq:
1143 case TOK_ASM_strexeq:1143 case TOK_ASM_strexeq:
1144 parse_operand(s1, &strex_operand);1144 parse_operand(S, &strex_operand);
1145 if (strex_operand.type != OP_REG32) {1145 if (strex_operand.type != OP_REG32) {
1146 expect("register");1146 expect(S, "register");
1147 return;1147 return;
1148 }1148 }
1149 if (tok != ',')1149 if (S->tccpp_tok != ',')
1150 expect("at least three arguments");1150 expect(S, "at least three arguments");
1151 else1151 else
1152 next(); // skip ','1152 next(S); // skip ','
1153 break;1153 break;
1154 }1154 }
1155 1155
1156 if (tok != '[')1156 if (S->tccpp_tok != '[')
1157 expect("'['");1157 expect(S, "'['");
1158 else1158 else
1159 next(); // skip '['1159 next(S); // skip '['
1160 1160
1161 parse_operand(s1, &ops[1]);1161 parse_operand(S, &ops[1]);
1162 if (ops[1].type == OP_REG32)1162 if (ops[1].type == OP_REG32)
1163 opcode |= ENCODE_RN(ops[1].reg);1163 opcode |= ENCODE_RN(ops[1].reg);
1164 else {1164 else {
1165 expect("(first source operand) register");1165 expect(S, "(first source operand) register");
1166 return;1166 return;
1167 }1167 }
1168 if (tok == ']') {1168 if (S->tccpp_tok == ']') {
1169 next();1169 next(S);
1170 closed_bracket = 1;1170 closed_bracket = 1;
1171 // exclam = 1; // implicit in hardware; don't do it in software1171 // exclam = 1; // implicit in hardware; don't do it in software
1172 }1172 }
1173 if (tok == ',') {1173 if (S->tccpp_tok == ',') {
1174 next(); // skip ','1174 next(S); // skip ','
1175 if (tok == '-') {1175 if (S->tccpp_tok == '-') {
1176 op2_minus = 1;1176 op2_minus = 1;
1177 next();1177 next(S);
1178 }1178 }
1179 parse_operand(s1, &ops[2]);1179 parse_operand(S, &ops[2]);
1180 if (ops[2].type == OP_REG32) {1180 if (ops[2].type == OP_REG32) {
1181 if (ops[2].reg == 15) {1181 if (ops[2].reg == 15) {
1182 tcc_error("Using 'pc' for register offset in '%s' is not implemented by ARM", get_tok_str(token, NULL));1182 tcc_error(S, "Using 'pc' for register offset in '%s' is not implemented by ARM", get_tok_str(S, token, NULL));
1183 return;1183 return;
1184 }1184 }
1185 if (tok == ',') {1185 if (S->tccpp_tok == ',') {
1186 next();1186 next(S);
1187 opcode |= asm_parse_optional_shift(s1, &nb_shift, &shift);1187 opcode |= asm_parse_optional_shift(S, &nb_shift, &shift);
1188 if (opcode == 0)1188 if (opcode == 0)
1189 expect("shift directive, or no comma");1189 expect(S, "shift directive, or no comma");
1190 }1190 }
1191 }1191 }
1192 } else {1192 } else {
@@ -1196,14 +1196,14 @@ static void asm_single_data_transfer_opcode(TCCState *s1, int token) · 3 unmodified lines
1196 opcode |= 1 << 24; // add offset before transfer1196 opcode |= 1 << 24; // add offset before transfer
1197 }1197 }
1198 if (!closed_bracket) {1198 if (!closed_bracket) {
1199 if (tok != ']')1199 if (S->tccpp_tok != ']')
1200 expect("']'");1200 expect(S, "']'");
1201 else1201 else
1202 next(); // skip ']'1202 next(S); // skip ']'
1203 opcode |= 1 << 24; // add offset before transfer1203 opcode |= 1 << 24; // add offset before transfer
1204 if (tok == '!') {1204 if (S->tccpp_tok == '!') {
1205 exclam = 1;1205 exclam = 1;
1206 next(); // skip '!'1206 next(S); // skip '!'
1207 }1207 }
1208 }1208 }
1209 1209
@@ -1224,16 +1224,16 @@ static void asm_single_data_transfer_opcode(TCCState *s1, int token) · 14 unmodified lines
1224 if (ops[2].type == OP_IM32 || ops[2].type == OP_IM8 || ops[2].type == OP_IM8N) {1224 if (ops[2].type == OP_IM32 || ops[2].type == OP_IM8 || ops[2].type == OP_IM8N) {
1225 int v = ops[2].e.v;1225 int v = ops[2].e.v;
1226 if (op2_minus)1226 if (op2_minus)
1227 tcc_error("minus before '#' not supported for immediate values");1227 tcc_error(S, "minus before '#' not supported for immediate values");
1228 if (v >= 0) {1228 if (v >= 0) {
1229 opcode |= 1 << 23; // up1229 opcode |= 1 << 23; // up
1230 if (v >= 0x1000)1230 if (v >= 0x1000)
1231 tcc_error("offset out of range for '%s'", get_tok_str(token, NULL));1231 tcc_error(S, "offset out of range for '%s'", get_tok_str(S, token, NULL));
1232 else1232 else
1233 opcode |= v;1233 opcode |= v;
1234 } else { // down1234 } else { // down
1235 if (v <= -0x1000)1235 if (v <= -0x1000)
1236 tcc_error("offset out of range for '%s'", get_tok_str(token, NULL));1236 tcc_error(S, "offset out of range for '%s'", get_tok_str(S, token, NULL));
1237 else1237 else
1238 opcode |= -v;1238 opcode |= -v;
1239 }1239 }
@@ -1243,7 +1243,7 @@ static void asm_single_data_transfer_opcode(TCCState *s1, int token) · 3 unmodified lines
1243 opcode |= ENCODE_IMMEDIATE_FLAG; /* if set, it means it's NOT immediate */1243 opcode |= ENCODE_IMMEDIATE_FLAG; /* if set, it means it's NOT immediate */
1244 opcode |= ops[2].reg;1244 opcode |= ops[2].reg;
1245 } else1245 } else
1246 expect("register");1246 expect(S, "register");
1247 1247
1248 switch (ARM_INSTRUCTION_GROUP(token)) {1248 switch (ARM_INSTRUCTION_GROUP(token)) {
1249 case TOK_ASM_strbeq:1249 case TOK_ASM_strbeq:
@@ -1252,8 +1252,8 @@ static void asm_single_data_transfer_opcode(TCCState *s1, int token) · 2 unmodified lines
1252 case TOK_ASM_streq:1252 case TOK_ASM_streq:
1253 opcode |= 1 << 26; // Load/Store1253 opcode |= 1 << 26; // Load/Store
1254 if (nb_shift)1254 if (nb_shift)
1255 opcode |= asm_encode_shift(&shift);1255 opcode |= asm_encode_shift(S, &shift);
1256 asm_emit_opcode(token, opcode);1256 asm_emit_opcode(S, token, opcode);
1257 break;1257 break;
1258 case TOK_ASM_ldrbeq:1258 case TOK_ASM_ldrbeq:
1259 opcode |= 1 << 22; // B1259 opcode |= 1 << 22; // B
@@ -1262,56 +1262,56 @@ static void asm_single_data_transfer_opcode(TCCState *s1, int token) · 2 unmodified lines
1262 opcode |= 1 << 20; // L1262 opcode |= 1 << 20; // L
1263 opcode |= 1 << 26; // Load/Store1263 opcode |= 1 << 26; // Load/Store
1264 if (nb_shift)1264 if (nb_shift)
1265 opcode |= asm_encode_shift(&shift);1265 opcode |= asm_encode_shift(S, &shift);
1266 asm_emit_opcode(token, opcode);1266 asm_emit_opcode(S, token, opcode);
1267 break;1267 break;
1268 case TOK_ASM_strexbeq:1268 case TOK_ASM_strexbeq:
1269 opcode |= 1 << 22; // B1269 opcode |= 1 << 22; // B
1270 /* fallthrough */1270 /* fallthrough */
1271 case TOK_ASM_strexeq:1271 case TOK_ASM_strexeq:
1272 if ((opcode & 0xFFF) || nb_shift) {1272 if ((opcode & 0xFFF) || nb_shift) {
1273 tcc_error("neither offset nor shift allowed with 'strex'");1273 tcc_error(S, "neither offset nor shift allowed with 'strex'");
1274 return;1274 return;
1275 } else if (opcode & ENCODE_IMMEDIATE_FLAG) { // if set, it means it's NOT immediate1275 } else if (opcode & ENCODE_IMMEDIATE_FLAG) { // if set, it means it's NOT immediate
1276 tcc_error("offset not allowed with 'strex'");1276 tcc_error(S, "offset not allowed with 'strex'");
1277 return;1277 return;
1278 }1278 }
1279 if ((opcode & (1 << 24)) == 0) { // add offset after transfer1279 if ((opcode & (1 << 24)) == 0) { // add offset after transfer
1280 tcc_error("adding offset after transfer not allowed with 'strex'");1280 tcc_error(S, "adding offset after transfer not allowed with 'strex'");
1281 return;1281 return;
1282 }1282 }
1283 1283
1284 opcode |= 0xf90; // Used to mean: barrel shifter is enabled, barrel shift register is r15, mode is LSL1284 opcode |= 0xf90; // Used to mean: barrel shifter is enabled, barrel shift register is r15, mode is LSL
1285 opcode |= strex_operand.reg;1285 opcode |= strex_operand.reg;
1286 asm_emit_opcode(token, opcode);1286 asm_emit_opcode(S, token, opcode);
1287 break;1287 break;
1288 case TOK_ASM_ldrexbeq:1288 case TOK_ASM_ldrexbeq:
1289 opcode |= 1 << 22; // B1289 opcode |= 1 << 22; // B
1290 /* fallthrough */1290 /* fallthrough */
1291 case TOK_ASM_ldrexeq:1291 case TOK_ASM_ldrexeq:
1292 if ((opcode & 0xFFF) || nb_shift) {1292 if ((opcode & 0xFFF) || nb_shift) {
1293 tcc_error("neither offset nor shift allowed with 'ldrex'");1293 tcc_error(S, "neither offset nor shift allowed with 'ldrex'");
1294 return;1294 return;
1295 } else if (opcode & ENCODE_IMMEDIATE_FLAG) { // if set, it means it's NOT immediate1295 } else if (opcode & ENCODE_IMMEDIATE_FLAG) { // if set, it means it's NOT immediate
1296 tcc_error("offset not allowed with 'ldrex'");1296 tcc_error(S, "offset not allowed with 'ldrex'");
1297 return;1297 return;
1298 }1298 }
1299 if ((opcode & (1 << 24)) == 0) { // add offset after transfer1299 if ((opcode & (1 << 24)) == 0) { // add offset after transfer
1300 tcc_error("adding offset after transfer not allowed with 'ldrex'");1300 tcc_error(S, "adding offset after transfer not allowed with 'ldrex'");
1301 return;1301 return;
1302 }1302 }
1303 opcode |= 1 << 20; // L1303 opcode |= 1 << 20; // L
1304 opcode |= 0x00f;1304 opcode |= 0x00f;
1305 opcode |= 0xf90; // Used to mean: barrel shifter is enabled, barrel shift register is r15, mode is LSL1305 opcode |= 0xf90; // Used to mean: barrel shifter is enabled, barrel shift register is r15, mode is LSL
1306 asm_emit_opcode(token, opcode);1306 asm_emit_opcode(S, token, opcode);
1307 break;1307 break;
1308 default:1308 default:
1309 expect("data transfer instruction");1309 expect(S, "data transfer instruction");
1310 }1310 }
1311}1311}
1312 1312
1313// Note: Only call this using a VFP register if you know exactly what you are doing (i.e. cp_number is 10 or 11 and you are doing a vmov)1313// Note: Only call this using a VFP register if you know exactly what you are doing (i.e. cp_number is 10 or 11 and you are doing a vmov)
1314static void asm_emit_coprocessor_data_transfer(uint32_t high_nibble, uint8_t cp_number, uint8_t CRd, const Operand* Rn, const Operand* offset, int offset_minus, int preincrement, int writeback, int long_transfer, int load) {1314static void asm_emit_coprocessor_data_transfer(TCCState *S, uint32_t high_nibble, uint8_t cp_number, uint8_t CRd, const Operand* Rn, const Operand* offset, int offset_minus, int preincrement, int writeback, int long_transfer, int load) {
1315 uint32_t opcode = 0x0;1315 uint32_t opcode = 0x0;
1316 opcode |= 1 << 26; // Load/Store1316 opcode |= 1 << 26; // Load/Store
1317 opcode |= 1 << 27; // coprocessor1317 opcode |= 1 << 27; // coprocessor
@@ -1328,7 +1328,7 @@ static void asm_emit_coprocessor_data_transfer(uint32_t high_nibble, uint8_t cp_ · 10 unmodified lines
1328 opcode |= ENCODE_RD(CRd);1328 opcode |= ENCODE_RD(CRd);
1329 1329
1330 if (Rn->type != OP_REG32) {1330 if (Rn->type != OP_REG32) {
1331 expect("register");1331 expect(S, "register");
1332 return;1332 return;
1333 }1333 }
1334 //assert(Rn->reg < 16);1334 //assert(Rn->reg < 16);
@@ -1342,18 +1342,18 @@ static void asm_emit_coprocessor_data_transfer(uint32_t high_nibble, uint8_t cp_ · 7 unmodified lines
1342 if (offset->type == OP_IM8 || offset->type == OP_IM8N || offset->type == OP_IM32) {1342 if (offset->type == OP_IM8 || offset->type == OP_IM8N || offset->type == OP_IM32) {
1343 int v = offset->e.v;1343 int v = offset->e.v;
1344 if (offset_minus)1344 if (offset_minus)
1345 tcc_error("minus before '#' not supported for immediate values");1345 tcc_error(S, "minus before '#' not supported for immediate values");
1346 if (offset->type == OP_IM8N || v < 0)1346 if (offset->type == OP_IM8N || v < 0)
1347 v = -v;1347 v = -v;
1348 else1348 else
1349 opcode |= 1 << 23; // up1349 opcode |= 1 << 23; // up
1350 if (v & 3) {1350 if (v & 3) {
1351 tcc_error("immediate offset must be a multiple of 4");1351 tcc_error(S, "immediate offset must be a multiple of 4");
1352 return;1352 return;
1353 }1353 }
1354 v >>= 2;1354 v >>= 2;
1355 if (v > 255) {1355 if (v > 255) {
1356 tcc_error("immediate offset must be between -1020 and 1020");1356 tcc_error(S, "immediate offset must be between -1020 and 1020");
1357 return;1357 return;
1358 }1358 }
1359 opcode |= v;1359 opcode |= v;
@@ -1362,20 +1362,20 @@ static void asm_emit_coprocessor_data_transfer(uint32_t high_nibble, uint8_t cp_ · 2 unmodified lines
1362 opcode |= 1 << 23; // up1362 opcode |= 1 << 23; // up
1363 opcode |= ENCODE_IMMEDIATE_FLAG; /* if set, it means it's NOT immediate */1363 opcode |= ENCODE_IMMEDIATE_FLAG; /* if set, it means it's NOT immediate */
1364 opcode |= offset->reg;1364 opcode |= offset->reg;
1365 tcc_error("Using register offset to register address is not possible here");1365 tcc_error(S, "Using register offset to register address is not possible here");
1366 return;1366 return;
1367 } else if (offset->type == OP_VREG64) {1367 } else if (offset->type == OP_VREG64) {
1368 opcode |= 16;1368 opcode |= 16;
1369 opcode |= offset->reg;1369 opcode |= offset->reg;
1370 } else1370 } else
1371 expect("immediate or register");1371 expect(S, "immediate or register");
1372 1372
1373 asm_emit_unconditional_opcode((high_nibble << 28) | opcode);1373 asm_emit_unconditional_opcode(S, (high_nibble << 28) | opcode);
1374}1374}
1375 1375
1376// Almost exactly the same as asm_single_data_transfer_opcode.1376// Almost exactly the same as asm_single_data_transfer_opcode.
1377// Difference: Offsets are smaller and multiples of 4; no shifts, no STREX, ENCODE_IMMEDIATE_FLAG is inverted again.1377// Difference: Offsets are smaller and multiples of 4; no shifts, no STREX, ENCODE_IMMEDIATE_FLAG is inverted again.
1378static void asm_coprocessor_data_transfer_opcode(TCCState *s1, int token)1378static void asm_coprocessor_data_transfer_opcode(TCCState *S, int token)
1379{1379{
1380 Operand ops[3];1380 Operand ops[3];
1381 uint8_t coprocessor;1381 uint8_t coprocessor;
@@ -1389,61 +1389,61 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *s1, int token) · 7 unmodified lines
1389 // Note: ldc p2, c0, [r4, #4]! ; pre-indexed: r0 = *(int*)(r4+4); r4 = r4+41389 // Note: ldc p2, c0, [r4, #4]! ; pre-indexed: r0 = *(int*)(r4+4); r4 = r4+4
1390 // Note: ldc p3, c0, [r4], #4 ; post-indexed: r0 = *(int*)(r4+0); r4 = r4+41390 // Note: ldc p3, c0, [r4], #4 ; post-indexed: r0 = *(int*)(r4+0); r4 = r4+4
1391 1391
1392 if (tok >= TOK_ASM_p0 && tok <= TOK_ASM_p15) {1392 if (S->tccpp_tok >= TOK_ASM_p0 && S->tccpp_tok <= TOK_ASM_p15) {
1393 coprocessor = tok - TOK_ASM_p0;1393 coprocessor = S->tccpp_tok - TOK_ASM_p0;
1394 next();1394 next(S);
1395 } else {1395 } else {
1396 expect("'c<number>'");1396 expect(S, "'c<number>'");
1397 return;1397 return;
1398 }1398 }
1399 1399
1400 if (tok == ',')1400 if (S->tccpp_tok == ',')
1401 next();1401 next(S);
1402 else1402 else
1403 expect("','");1403 expect(S, "','");
1404 1404
1405 if (tok >= TOK_ASM_c0 && tok <= TOK_ASM_c15) {1405 if (S->tccpp_tok >= TOK_ASM_c0 && S->tccpp_tok <= TOK_ASM_c15) {
1406 coprocessor_destination_register = tok - TOK_ASM_c0;1406 coprocessor_destination_register = S->tccpp_tok - TOK_ASM_c0;
1407 next();1407 next(S);
1408 } else {1408 } else {
1409 expect("'c<number>'");1409 expect(S, "'c<number>'");
1410 return;1410 return;
1411 }1411 }
1412 1412
1413 if (tok == ',')1413 if (S->tccpp_tok == ',')
1414 next();1414 next(S);
1415 else1415 else
1416 expect("','");1416 expect(S, "','");
1417 1417
1418 if (tok != '[')1418 if (S->tccpp_tok != '[')
1419 expect("'['");1419 expect(S, "'['");
1420 else1420 else
1421 next(); // skip '['1421 next(S); // skip '['
1422 1422
1423 parse_operand(s1, &ops[1]);1423 parse_operand(S, &ops[1]);
1424 if (ops[1].type != OP_REG32) {1424 if (ops[1].type != OP_REG32) {
1425 expect("(first source operand) register");1425 expect(S, "(first source operand) register");
1426 return;1426 return;
1427 }1427 }
1428 if (tok == ']') {1428 if (S->tccpp_tok == ']') {
1429 next();1429 next(S);
1430 closed_bracket = 1;1430 closed_bracket = 1;
1431 // exclam = 1; // implicit in hardware; don't do it in software1431 // exclam = 1; // implicit in hardware; don't do it in software
1432 }1432 }
1433 if (tok == ',') {1433 if (S->tccpp_tok == ',') {
1434 next(); // skip ','1434 next(S); // skip ','
1435 if (tok == '-') {1435 if (S->tccpp_tok == '-') {
1436 op2_minus = 1;1436 op2_minus = 1;
1437 next();1437 next(S);
1438 }1438 }
1439 parse_operand(s1, &ops[2]);1439 parse_operand(S, &ops[2]);
1440 if (ops[2].type == OP_REG32) {1440 if (ops[2].type == OP_REG32) {
1441 if (ops[2].reg == 15) {1441 if (ops[2].reg == 15) {
1442 tcc_error("Using 'pc' for register offset in '%s' is not implemented by ARM", get_tok_str(token, NULL));1442 tcc_error(S, "Using 'pc' for register offset in '%s' is not implemented by ARM", get_tok_str(S, token, NULL));
1443 return;1443 return;
1444 }1444 }
1445 } else if (ops[2].type == OP_VREG64) {1445 } else if (ops[2].type == OP_VREG64) {
1446 tcc_error("'%s' does not support VFP register operand", get_tok_str(token, NULL));1446 tcc_error(S, "'%s' does not support VFP register operand", get_tok_str(S, token, NULL));
1447 return;1447 return;
1448 }1448 }
1449 } else {1449 } else {
@@ -1453,14 +1453,14 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *s1, int token) · 3 unmodified lines
1453 preincrement = 1; // add offset before transfer1453 preincrement = 1; // add offset before transfer
1454 }1454 }
1455 if (!closed_bracket) {1455 if (!closed_bracket) {
1456 if (tok != ']')1456 if (S->tccpp_tok != ']')
1457 expect("']'");1457 expect(S, "']'");
1458 else1458 else
1459 next(); // skip ']'1459 next(S); // skip ']'
1460 preincrement = 1; // add offset before transfer1460 preincrement = 1; // add offset before transfer
1461 if (tok == '!') {1461 if (S->tccpp_tok == '!') {
1462 exclam = 1;1462 exclam = 1;
1463 next(); // skip '!'1463 next(S); // skip '!'
1464 }1464 }
1465 }1465 }
1466 1466
@@ -1472,13 +1472,13 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *s1, int token) · 5 unmodified lines
1472 long_transfer = 1; // long transfer1472 long_transfer = 1; // long transfer
1473 /* fallthrough */1473 /* fallthrough */
1474 case TOK_ASM_ldc2:1474 case TOK_ASM_ldc2:
1475 asm_emit_coprocessor_data_transfer(0xF, coprocessor, coprocessor_destination_register, &ops[1], &ops[2], op2_minus, preincrement, exclam, long_transfer, 1);1475 asm_emit_coprocessor_data_transfer(S, 0xF, coprocessor, coprocessor_destination_register, &ops[1], &ops[2], op2_minus, preincrement, exclam, long_transfer, 1);
1476 break;1476 break;
1477 case TOK_ASM_stc2l:1477 case TOK_ASM_stc2l:
1478 long_transfer = 1; // long transfer1478 long_transfer = 1; // long transfer
1479 /* fallthrough */1479 /* fallthrough */
1480 case TOK_ASM_stc2:1480 case TOK_ASM_stc2:
1481 asm_emit_coprocessor_data_transfer(0xF, coprocessor, coprocessor_destination_register, &ops[1], &ops[2], op2_minus, preincrement, exclam, long_transfer, 0);1481 asm_emit_coprocessor_data_transfer(S, 0xF, coprocessor, coprocessor_destination_register, &ops[1], &ops[2], op2_minus, preincrement, exclam, long_transfer, 0);
1482 break;1482 break;
1483 }1483 }
1484 } else switch (ARM_INSTRUCTION_GROUP(token)) {1484 } else switch (ARM_INSTRUCTION_GROUP(token)) {
@@ -1486,16 +1486,16 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *s1, int token) · 1 unmodified line
1486 long_transfer = 1;1486 long_transfer = 1;
1487 /* fallthrough */1487 /* fallthrough */
1488 case TOK_ASM_stceq:1488 case TOK_ASM_stceq:
1489 asm_emit_coprocessor_data_transfer(condition_code_of_token(token), coprocessor, coprocessor_destination_register, &ops[1], &ops[2], op2_minus, preincrement, exclam, long_transfer, 0);1489 asm_emit_coprocessor_data_transfer(S, condition_code_of_token(S, token), coprocessor, coprocessor_destination_register, &ops[1], &ops[2], op2_minus, preincrement, exclam, long_transfer, 0);
1490 break;1490 break;
1491 case TOK_ASM_ldcleq:1491 case TOK_ASM_ldcleq:
1492 long_transfer = 1;1492 long_transfer = 1;
1493 /* fallthrough */1493 /* fallthrough */
1494 case TOK_ASM_ldceq:1494 case TOK_ASM_ldceq:
1495 asm_emit_coprocessor_data_transfer(condition_code_of_token(token), coprocessor, coprocessor_destination_register, &ops[1], &ops[2], op2_minus, preincrement, exclam, long_transfer, 1);1495 asm_emit_coprocessor_data_transfer(S, condition_code_of_token(S, token), coprocessor, coprocessor_destination_register, &ops[1], &ops[2], op2_minus, preincrement, exclam, long_transfer, 1);
1496 break;1496 break;
1497 default:1497 default:
1498 expect("coprocessor data transfer instruction");1498 expect(S, "coprocessor data transfer instruction");
1499 }1499 }
1500}1500}
1501 1501
@@ -1503,7 +1503,7 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *s1, int token) · 1 unmodified line
1503#define CP_SINGLE_PRECISION_FLOAT 101503#define CP_SINGLE_PRECISION_FLOAT 10
1504#define CP_DOUBLE_PRECISION_FLOAT 111504#define CP_DOUBLE_PRECISION_FLOAT 11
1505 1505
1506static void asm_floating_point_single_data_transfer_opcode(TCCState *s1, int token)1506static void asm_floating_point_single_data_transfer_opcode(TCCState *S, int token)
1507{1507{
1508 Operand ops[3];1508 Operand ops[3];
1509 uint8_t coprocessor = 0;1509 uint8_t coprocessor = 0;
@@ -1513,7 +1513,7 @@ static void asm_floating_point_single_data_transfer_opcode(TCCState *s1, int tok · 3 unmodified lines
1513 // Note: Not allowed: vldr p2, c0, [r4, #4]! ; pre-indexed: r0 = *(int*)(r4+4); r4 = r4+41513 // Note: Not allowed: vldr p2, c0, [r4, #4]! ; pre-indexed: r0 = *(int*)(r4+4); r4 = r4+4
1514 // Note: Not allowed: vldr p3, c0, [r4], #4 ; post-indexed: r0 = *(int*)(r4+0); r4 = r4+41514 // Note: Not allowed: vldr p3, c0, [r4], #4 ; post-indexed: r0 = *(int*)(r4+0); r4 = r4+4
1515 1515
1516 parse_operand(s1, &ops[0]);1516 parse_operand(S, &ops[0]);
1517 if (ops[0].type == OP_VREG32) {1517 if (ops[0].type == OP_VREG32) {
1518 coprocessor = CP_SINGLE_PRECISION_FLOAT;1518 coprocessor = CP_SINGLE_PRECISION_FLOAT;
1519 coprocessor_destination_register = ops[0].reg;1519 coprocessor_destination_register = ops[0].reg;
@@ -1522,32 +1522,32 @@ static void asm_floating_point_single_data_transfer_opcode(TCCState *s1, int tok · 2 unmodified lines
1522 } else if (ops[0].type == OP_VREG64) {1522 } else if (ops[0].type == OP_VREG64) {
1523 coprocessor = CP_DOUBLE_PRECISION_FLOAT;1523 coprocessor = CP_DOUBLE_PRECISION_FLOAT;
1524 coprocessor_destination_register = ops[0].reg;1524 coprocessor_destination_register = ops[0].reg;
1525 next();1525 next(S);
1526 } else {1526 } else {
1527 expect("floating point register");1527 expect(S, "floating point register");
1528 return;1528 return;
1529 }1529 }
1530 1530
1531 if (tok == ',')1531 if (S->tccpp_tok == ',')
1532 next();1532 next(S);
1533 else1533 else
1534 expect("','");1534 expect(S, "','");
1535 1535
1536 if (tok != '[')1536 if (S->tccpp_tok != '[')
1537 expect("'['");1537 expect(S, "'['");
1538 else1538 else
1539 next(); // skip '['1539 next(S); // skip '['
1540 1540
1541 parse_operand(s1, &ops[1]);1541 parse_operand(S, &ops[1]);
1542 if (ops[1].type != OP_REG32) {1542 if (ops[1].type != OP_REG32) {
1543 expect("(first source operand) register");1543 expect(S, "(first source operand) register");
1544 return;1544 return;
1545 }1545 }
1546 if (tok == ',') {1546 if (S->tccpp_tok == ',') {
1547 next(); // skip ','1547 next(S); // skip ','
1548 parse_operand(s1, &ops[2]);1548 parse_operand(S, &ops[2]);
1549 if (ops[2].type != OP_IM8 && ops[2].type != OP_IM8N) {1549 if (ops[2].type != OP_IM8 && ops[2].type != OP_IM8N) {
1550 expect("immediate offset");1550 expect(S, "immediate offset");
1551 return;1551 return;
1552 }1552 }
1553 } else {1553 } else {
@@ -1555,24 +1555,24 @@ static void asm_floating_point_single_data_transfer_opcode(TCCState *s1, int tok · 1 unmodified line
1555 ops[2].type = OP_IM8;1555 ops[2].type = OP_IM8;
1556 ops[2].e.v = 0;1556 ops[2].e.v = 0;
1557 }1557 }
1558 if (tok != ']')1558 if (S->tccpp_tok != ']')
1559 expect("']'");1559 expect(S, "']'");
1560 else1560 else
1561 next(); // skip ']'1561 next(S); // skip ']'
1562 1562
1563 switch (ARM_INSTRUCTION_GROUP(token)) {1563 switch (ARM_INSTRUCTION_GROUP(token)) {
1564 case TOK_ASM_vldreq:1564 case TOK_ASM_vldreq:
1565 asm_emit_coprocessor_data_transfer(condition_code_of_token(token), coprocessor, coprocessor_destination_register, &ops[1], &ops[2], 0, 1, 0, long_transfer, 1);1565 asm_emit_coprocessor_data_transfer(S, condition_code_of_token(S, token), coprocessor, coprocessor_destination_register, &ops[1], &ops[2], 0, 1, 0, long_transfer, 1);
1566 break;1566 break;
1567 case TOK_ASM_vstreq:1567 case TOK_ASM_vstreq:
1568 asm_emit_coprocessor_data_transfer(condition_code_of_token(token), coprocessor, coprocessor_destination_register, &ops[1], &ops[2], 0, 1, 0, long_transfer, 0);1568 asm_emit_coprocessor_data_transfer(S, condition_code_of_token(S, token), coprocessor, coprocessor_destination_register, &ops[1], &ops[2], 0, 1, 0, long_transfer, 0);
1569 break;1569 break;
1570 default:1570 default:
1571 expect("floating point data transfer instruction");1571 expect(S, "floating point data transfer instruction");
1572 }1572 }
1573}1573}
1574 1574
1575static void asm_floating_point_block_data_transfer_opcode(TCCState *s1, int token)1575static void asm_floating_point_block_data_transfer_opcode(TCCState *S, int token)
1576{1576{
1577 uint8_t coprocessor = 0;1577 uint8_t coprocessor = 0;
1578 int first_regset_register;1578 int first_regset_register;
@@ -1592,56 +1592,56 @@ static void asm_floating_point_block_data_transfer_opcode(TCCState *s1, int toke · 13 unmodified lines
1592 op0_exclam = 1;1592 op0_exclam = 1;
1593 break;1593 break;
1594 default:1594 default:
1595 parse_operand(s1, &ops[0]);1595 parse_operand(S, &ops[0]);
1596 if (tok == '!') {1596 if (S->tccpp_tok == '!') {
1597 op0_exclam = 1;1597 op0_exclam = 1;
1598 next(); // skip '!'1598 next(S); // skip '!'
1599 }1599 }
1600 if (tok == ',')1600 if (S->tccpp_tok == ',')
1601 next(); // skip comma1601 next(S); // skip comma
1602 else {1602 else {
1603 expect("','");1603 expect(S, "','");
1604 return;1604 return;
1605 }1605 }
1606 }1606 }
1607 1607
1608 if (tok != '{') {1608 if (S->tccpp_tok != '{') {
1609 expect("'{'");1609 expect(S, "'{'");
1610 return;1610 return;
1611 }1611 }
1612 next(); // skip '{'1612 next(S); // skip '{'
1613 first_regset_register = asm_parse_vfp_regvar(tok, 1);1613 first_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, 1);
1614 if ((first_regset_register = asm_parse_vfp_regvar(tok, 1)) != -1) {1614 if ((first_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, 1)) != -1) {
1615 coprocessor = CP_DOUBLE_PRECISION_FLOAT;1615 coprocessor = CP_DOUBLE_PRECISION_FLOAT;
1616 next();1616 next(S);
1617 } else if ((first_regset_register = asm_parse_vfp_regvar(tok, 0)) != -1) {1617 } else if ((first_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, 0)) != -1) {
1618 coprocessor = CP_SINGLE_PRECISION_FLOAT;1618 coprocessor = CP_SINGLE_PRECISION_FLOAT;
1619 next();1619 next(S);
1620 } else {1620 } else {
1621 expect("floating-point register");1621 expect(S, "floating-point register");
1622 return;1622 return;
1623 }1623 }
1624 1624
1625 if (tok == '-') {1625 if (S->tccpp_tok == '-') {
1626 next();1626 next(S);
1627 if ((last_regset_register = asm_parse_vfp_regvar(tok, coprocessor == CP_DOUBLE_PRECISION_FLOAT)) != -1)1627 if ((last_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, coprocessor == CP_DOUBLE_PRECISION_FLOAT)) != -1)
1628 next();1628 next(S);
1629 else {1629 else {
1630 expect("floating-point register");1630 expect(S, "floating-point register");
1631 return;1631 return;
1632 }1632 }
1633 } else1633 } else
1634 last_regset_register = first_regset_register;1634 last_regset_register = first_regset_register;
1635 1635
1636 if (last_regset_register < first_regset_register) {1636 if (last_regset_register < first_regset_register) {
1637 tcc_error("registers will be processed in ascending order by hardware--but are not specified in ascending order here");1637 tcc_error(S, "registers will be processed in ascending order by hardware--but are not specified in ascending order here");
1638 return;1638 return;
1639 }1639 }
1640 if (tok != '}') {1640 if (S->tccpp_tok != '}') {
1641 expect("'}'");1641 expect(S, "'}'");
1642 return;1642 return;
1643 }1643 }
1644 next(); // skip '}'1644 next(S); // skip '}'
1645 1645
1646 // Note: 0 (one down) is not implemented by us regardless.1646 // Note: 0 (one down) is not implemented by us regardless.
1647 regset_item_count = last_regset_register - first_regset_register + 1;1647 regset_item_count = last_regset_register - first_regset_register + 1;
@@ -1672,23 +1672,23 @@ static void asm_floating_point_block_data_transfer_opcode(TCCState *s1, int toke · 24 unmodified lines
1672 preincrement = 1;1672 preincrement = 1;
1673 break;1673 break;
1674 default:1674 default:
1675 expect("floating point block data transfer instruction");1675 expect(S, "floating point block data transfer instruction");
1676 return;1676 return;
1677 }1677 }
1678 if (ops[0].type != OP_REG32)1678 if (ops[0].type != OP_REG32)
1679 expect("(first operand) register");1679 expect(S, "(first operand) register");
1680 else if (ops[0].reg == 15)1680 else if (ops[0].reg == 15)
1681 tcc_error("'%s' does not support 'pc' as operand", get_tok_str(token, NULL));1681 tcc_error(S, "'%s' does not support 'pc' as operand", get_tok_str(S, token, NULL));
1682 else if (!op0_exclam && ARM_INSTRUCTION_GROUP(token) != TOK_ASM_vldmeq && ARM_INSTRUCTION_GROUP(token) != TOK_ASM_vldmiaeq && ARM_INSTRUCTION_GROUP(token) != TOK_ASM_vstmeq && ARM_INSTRUCTION_GROUP(token) != TOK_ASM_vstmiaeq)1682 else if (!op0_exclam && ARM_INSTRUCTION_GROUP(token) != TOK_ASM_vldmeq && ARM_INSTRUCTION_GROUP(token) != TOK_ASM_vldmiaeq && ARM_INSTRUCTION_GROUP(token) != TOK_ASM_vstmeq && ARM_INSTRUCTION_GROUP(token) != TOK_ASM_vstmiaeq)
1683 tcc_error("first operand of '%s' should have an exclamation mark", get_tok_str(token, NULL));1683 tcc_error(S, "first operand of '%s' should have an exclamation mark", get_tok_str(S, token, NULL));
1684 else1684 else
1685 asm_emit_coprocessor_data_transfer(condition_code_of_token(token), coprocessor, first_regset_register, &ops[0], &offset, 0, preincrement, op0_exclam, extra_register_bit, load);1685 asm_emit_coprocessor_data_transfer(S, condition_code_of_token(S, token), coprocessor, first_regset_register, &ops[0], &offset, 0, preincrement, op0_exclam, extra_register_bit, load);
1686}1686}
1687 1687
1688#define VMOV_FRACTIONAL_DIGITS 71688#define VMOV_FRACTIONAL_DIGITS 7
1689#define VMOV_ONE 10000000 /* pow(10, VMOV_FRACTIONAL_DIGITS) */1689#define VMOV_ONE 10000000 /* pow(10, VMOV_FRACTIONAL_DIGITS) */
1690 1690
1691static uint32_t vmov_parse_fractional_part(const char* s)1691static uint32_t vmov_parse_fractional_part(TCCState* S, const char* s)
1692{1692{
1693 uint32_t result = 0;1693 uint32_t result = 0;
1694 int i;1694 int i;
@@ -1701,7 +1701,7 @@ static uint32_t vmov_parse_fractional_part(const char* s) · 6 unmodified lines
1701 }1701 }
1702 }1702 }
1703 if (*s)1703 if (*s)
1704 expect("decimal numeral");1704 expect(S, "decimal numeral");
1705 return result;1705 return result;
1706}1706}
1707 1707
@@ -1720,34 +1720,34 @@ static int vmov_linear_approx_index(uint32_t beginning, uint32_t end, uint32_t v · 12 unmodified lines
1720 return -1;1720 return -1;
1721}1721}
1722 1722
1723static uint32_t vmov_parse_immediate_value() {1723static uint32_t vmov_parse_immediate_value(TCCState* S) {
1724 uint32_t value;1724 uint32_t value;
1725 unsigned long integral_value;1725 unsigned long integral_value;
1726 const char *p;1726 const char *p;
1727 1727
1728 if (tok != TOK_PPNUM) {1728 if (S->tccpp_tok != TOK_PPNUM) {
1729 expect("immediate value");1729 expect(S, "immediate value");
1730 return 0;1730 return 0;
1731 }1731 }
1732 p = tokc.str.data;1732 p = S->tccpp_tokc.str.data;
1733 errno = 0;1733 errno = 0;
1734 integral_value = strtoul(p, (char **)&p, 0);1734 integral_value = strtoul(p, (char **)&p, 0);
1735 1735
1736 if (errno || integral_value >= 32) {1736 if (errno || integral_value >= 32) {
1737 tcc_error("invalid floating-point immediate value");1737 tcc_error(S, "invalid floating-point immediate value");
1738 return 0;1738 return 0;
1739 }1739 }
1740 1740
1741 value = (uint32_t) integral_value * VMOV_ONE;1741 value = (uint32_t) integral_value * VMOV_ONE;
1742 if (*p == '.') {1742 if (*p == '.') {
1743 ++p;1743 ++p;
1744 value += vmov_parse_fractional_part(p);1744 value += vmov_parse_fractional_part(S, p);
1745 }1745 }
1746 next();1746 next(S);
1747 return value;1747 return value;
1748}1748}
1749 1749
1750static uint8_t vmov_encode_immediate_value(uint32_t value)1750static uint8_t vmov_encode_immediate_value(TCCState* S, uint32_t value)
1751{1751{
1752 uint32_t limit;1752 uint32_t limit;
1753 uint32_t end = 0;1753 uint32_t end = 0;
@@ -1767,7 +1767,7 @@ static uint8_t vmov_encode_immediate_value(uint32_t value) · 13 unmodified lines
1767 limit >>= 1;1767 limit >>= 1;
1768 }1768 }
1769 if (r == -1 || value < beginning || value > end) {1769 if (r == -1 || value < beginning || value > end) {
1770 tcc_error("invalid decimal number for vmov: %d", value);1770 tcc_error(S, "invalid decimal number for vmov: %d", value);
1771 return 0;1771 return 0;
1772 }1772 }
1773 n = vmov_linear_approx_index(beginning, end, value);1773 n = vmov_linear_approx_index(beginning, end, value);
@@ -1775,7 +1775,7 @@ static uint8_t vmov_encode_immediate_value(uint32_t value) · 1 unmodified line
1775}1775}
1776 1776
1777// Not standalone.1777// Not standalone.
1778static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *s1, int token, uint8_t coprocessor, uint8_t CRd) {1778static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *S, int token, uint8_t coprocessor, uint8_t CRd) {
1779 uint8_t opcode1 = 0;1779 uint8_t opcode1 = 0;
1780 uint8_t opcode2 = 0;1780 uint8_t opcode2 = 0;
1781 uint8_t operands[3] = {0, 0, 0};1781 uint8_t operands[3] = {0, 0, 0};
@@ -1785,14 +1785,14 @@ static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *s · 3 unmodified lines
1785 1785
1786 operands[0] = CRd;1786 operands[0] = CRd;
1787 1787
1788 if (tok == '#' || tok == '$') {1788 if (S->tccpp_tok == '#' || S->tccpp_tok == '$') {
1789 next();1789 next(S);
1790 }1790 }
1791 if (tok == '-') {1791 if (S->tccpp_tok == '-') {
1792 op_minus = 1;1792 op_minus = 1;
1793 next();1793 next(S);
1794 }1794 }
1795 immediate_value = vmov_parse_immediate_value();1795 immediate_value = vmov_parse_immediate_value(S);
1796 1796
1797 opcode1 = 11; // "Other" instruction1797 opcode1 = 11; // "Other" instruction
1798 switch (ARM_INSTRUCTION_GROUP(token)) {1798 switch (ARM_INSTRUCTION_GROUP(token)) {
@@ -1801,7 +1801,7 @@ static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *s · 2 unmodified lines
1801 opcode2 = 2;1801 opcode2 = 2;
1802 operands[1] = 5;1802 operands[1] = 5;
1803 if (immediate_value) {1803 if (immediate_value) {
1804 expect("Immediate value 0");1804 expect(S, "Immediate value 0");
1805 return;1805 return;
1806 }1806 }
1807 break;1807 break;
@@ -1810,7 +1810,7 @@ static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *s · 2 unmodified lines
1810 opcode2 = 6;1810 opcode2 = 6;
1811 operands[1] = 5;1811 operands[1] = 5;
1812 if (immediate_value) {1812 if (immediate_value) {
1813 expect("Immediate value 0");1813 expect(S, "Immediate value 0");
1814 return;1814 return;
1815 }1815 }
1816 break;1816 break;
@@ -1821,12 +1821,12 @@ static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *s · 4 unmodified lines
1821 operands[1] = 0x8;1821 operands[1] = 0x8;
1822 else1822 else
1823 operands[1] = 0x0;1823 operands[1] = 0x0;
1824 code = vmov_encode_immediate_value(immediate_value);1824 code = vmov_encode_immediate_value(S, immediate_value);
1825 operands[1] |= code >> 4;1825 operands[1] |= code >> 4;
1826 operands[2] = code & 0xF;1826 operands[2] = code & 0xF;
1827 break;1827 break;
1828 default:1828 default:
1829 expect("known floating point with immediate instruction");1829 expect(S, "known floating point with immediate instruction");
1830 return;1830 return;
1831 }1831 }
1832 1832
@@ -1836,17 +1836,17 @@ static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *s · 3 unmodified lines
1836 operands[0] >>= 1;1836 operands[0] >>= 1;
1837 }1837 }
1838 1838
1839 asm_emit_coprocessor_opcode(condition_code_of_token(token), coprocessor, opcode1, operands[0], operands[1], operands[2], opcode2, 0);1839 asm_emit_coprocessor_opcode(S, condition_code_of_token(S, token), coprocessor, opcode1, operands[0], operands[1], operands[2], opcode2, 0);
1840}1840}
1841 1841
1842static void asm_floating_point_reg_arm_reg_transfer_opcode_tail(TCCState *s1, int token, int coprocessor, int nb_arm_regs, int nb_ops, Operand ops[3]) {1842static void asm_floating_point_reg_arm_reg_transfer_opcode_tail(TCCState *S, int token, int coprocessor, int nb_arm_regs, int nb_ops, Operand ops[3]) {
1843 uint8_t opcode1 = 0;1843 uint8_t opcode1 = 0;
1844 uint8_t opcode2 = 0;1844 uint8_t opcode2 = 0;
1845 switch (coprocessor) {1845 switch (coprocessor) {
1846 case CP_SINGLE_PRECISION_FLOAT:1846 case CP_SINGLE_PRECISION_FLOAT:
1847 // "vmov.f32 r2, s3" or "vmov.f32 s3, r2"1847 // "vmov.f32 r2, s3" or "vmov.f32 s3, r2"
1848 if (nb_ops != 2 || nb_arm_regs != 1) {1848 if (nb_ops != 2 || nb_arm_regs != 1) {
1849 tcc_error("vmov.f32 only implemented for one VFP register operand and one ARM register operands");1849 tcc_error(S, "vmov.f32 only implemented for one VFP register operand and one ARM register operands");
1850 return;1850 return;
1851 }1851 }
1852 if (ops[0].type != OP_REG32) { // determine mode: load or store1852 if (ops[0].type != OP_REG32) { // determine mode: load or store
@@ -1869,11 +1869,11 @@ static void asm_floating_point_reg_arm_reg_transfer_opcode_tail(TCCState *s1, in · 16 unmodified lines
1869 ops[0].reg >>= 1;1869 ops[0].reg >>= 1;
1870 }1870 }
1871 1871
1872 asm_emit_coprocessor_opcode(condition_code_of_token(token), coprocessor, opcode1, ops[0].reg, (ops[1].type == OP_IM8) ? ops[1].e.v : ops[1].reg, 0x10, opcode2, 0);1872 asm_emit_coprocessor_opcode(S, condition_code_of_token(S, token), coprocessor, opcode1, ops[0].reg, (ops[1].type == OP_IM8) ? ops[1].e.v : ops[1].reg, 0x10, opcode2, 0);
1873 break;1873 break;
1874 case CP_DOUBLE_PRECISION_FLOAT:1874 case CP_DOUBLE_PRECISION_FLOAT:
1875 if (nb_ops != 3 || nb_arm_regs != 2) {1875 if (nb_ops != 3 || nb_arm_regs != 2) {
1876 tcc_error("vmov.f32 only implemented for one VFP register operand and two ARM register operands");1876 tcc_error(S, "vmov.f32 only implemented for one VFP register operand and two ARM register operands");
1877 return;1877 return;
1878 }1878 }
1879 // Determine whether it's a store into a VFP register (vmov "d1, r2, r3") rather than "vmov r2, r3, d1"1879 // Determine whether it's a store into a VFP register (vmov "d1, r2, r3") rather than "vmov r2, r3, d1"
@@ -1886,23 +1886,23 @@ static void asm_floating_point_reg_arm_reg_transfer_opcode_tail(TCCState *s1, in · 6 unmodified lines
1886 memcpy(&ops[1], &ops[2], sizeof(ops[1]));1886 memcpy(&ops[1], &ops[2], sizeof(ops[1]));
1887 memcpy(&ops[2], &temp, sizeof(ops[2]));1887 memcpy(&ops[2], &temp, sizeof(ops[2]));
1888 } else {1888 } else {
1889 tcc_error("vmov.f64 only implemented for one VFP register operand and two ARM register operands");1889 tcc_error(S, "vmov.f64 only implemented for one VFP register operand and two ARM register operands");
1890 return;1890 return;
1891 }1891 }
1892 } else if (ops[0].type != OP_REG32 || ops[1].type != OP_REG32 || ops[2].type != OP_VREG64) {1892 } else if (ops[0].type != OP_REG32 || ops[1].type != OP_REG32 || ops[2].type != OP_VREG64) {
1893 tcc_error("vmov.f64 only implemented for one VFP register operand and two ARM register operands");1893 tcc_error(S, "vmov.f64 only implemented for one VFP register operand and two ARM register operands");
1894 return;1894 return;
1895 } else {1895 } else {
1896 opcode1 |= 1;1896 opcode1 |= 1;
1897 }1897 }
1898 asm_emit_coprocessor_data_transfer(condition_code_of_token(token), coprocessor, ops[0].reg, &ops[1], &ops[2], 0, 0, 0, 1, opcode1);1898 asm_emit_coprocessor_data_transfer(S, condition_code_of_token(S, token), coprocessor, ops[0].reg, &ops[1], &ops[2], 0, 0, 0, 1, opcode1);
1899 break;1899 break;
1900 default:1900 default:
1901 tcc_internal_error("unknown coprocessor");1901 tcc_internal_error(S, "unknown coprocessor");
1902 }1902 }
1903}1903}
1904 1904
1905static void asm_floating_point_vcvt_data_processing_opcode(TCCState *s1, int token) {1905static void asm_floating_point_vcvt_data_processing_opcode(TCCState *S, int token) {
1906 uint8_t coprocessor = 0;1906 uint8_t coprocessor = 0;
1907 Operand ops[3];1907 Operand ops[3];
1908 uint8_t opcode1 = 11;1908 uint8_t opcode1 = 11;
@@ -1928,11 +1928,11 @@ static void asm_floating_point_vcvt_data_processing_opcode(TCCState *s1, int tok · 19 unmodified lines
1928 coprocessor = CP_SINGLE_PRECISION_FLOAT;1928 coprocessor = CP_SINGLE_PRECISION_FLOAT;
1929 break;1929 break;
1930 default:1930 default:
1931 tcc_error("Unknown coprocessor for instruction '%s'", get_tok_str(token, NULL));1931 tcc_error(S, "Unknown coprocessor for instruction '%s'", get_tok_str(S, token, NULL));
1932 return;1932 return;
1933 }1933 }
1934 1934
1935 parse_operand(s1, &ops[0]);1935 parse_operand(S, &ops[0]);
1936 ops[1].type = OP_IM8;1936 ops[1].type = OP_IM8;
1937 ops[1].e.v = 8;1937 ops[1].e.v = 8;
1938 /* floating-point -> integer */1938 /* floating-point -> integer */
@@ -1956,11 +1956,11 @@ static void asm_floating_point_vcvt_data_processing_opcode(TCCState *s1, int tok · 17 unmodified lines
1956 break;1956 break;
1957 }1957 }
1958 1958
1959 if (tok == ',')1959 if (S->tccpp_tok == ',')
1960 next();1960 next(S);
1961 else1961 else
1962 expect("','");1962 expect(S, "','");
1963 parse_operand(s1, &ops[2]);1963 parse_operand(S, &ops[2]);
1964 1964
1965 switch (ARM_INSTRUCTION_GROUP(token)) {1965 switch (ARM_INSTRUCTION_GROUP(token)) {
1966 /* floating-point -> integer */1966 /* floating-point -> integer */
@@ -1990,7 +1990,7 @@ static void asm_floating_point_vcvt_data_processing_opcode(TCCState *s1, int tok · 23 unmodified lines
1990 case TOK_ASM_vcvteq_f64_f32:1990 case TOK_ASM_vcvteq_f64_f32:
1991 if (ops[0].type == OP_VREG64 && ops[2].type == OP_VREG32) {1991 if (ops[0].type == OP_VREG64 && ops[2].type == OP_VREG32) {
1992 } else {1992 } else {
1993 expect("d<number>, s<number>");1993 expect(S, "d<number>, s<number>");
1994 return;1994 return;
1995 }1995 }
1996 break;1996 break;
@@ -1998,13 +1998,13 @@ static void asm_floating_point_vcvt_data_processing_opcode(TCCState *s1, int tok · 1 unmodified line
1998 if (coprocessor == CP_SINGLE_PRECISION_FLOAT) {1998 if (coprocessor == CP_SINGLE_PRECISION_FLOAT) {
1999 if (ops[0].type == OP_VREG32 && ops[2].type == OP_VREG32) {1999 if (ops[0].type == OP_VREG32 && ops[2].type == OP_VREG32) {
2000 } else {2000 } else {
2001 expect("s<number>, s<number>");2001 expect(S, "s<number>, s<number>");
2002 return;2002 return;
2003 }2003 }
2004 } else if (coprocessor == CP_DOUBLE_PRECISION_FLOAT) {2004 } else if (coprocessor == CP_DOUBLE_PRECISION_FLOAT) {
2005 if (ops[0].type == OP_VREG32 && ops[2].type == OP_VREG64) {2005 if (ops[0].type == OP_VREG32 && ops[2].type == OP_VREG64) {
2006 } else {2006 } else {
2007 expect("s<number>, d<number>");2007 expect(S, "s<number>, d<number>");
2008 return;2008 return;
2009 }2009 }
2010 }2010 }
@@ -2020,10 +2020,10 @@ static void asm_floating_point_vcvt_data_processing_opcode(TCCState *s1, int tok · 9 unmodified lines
2020 opcode1 |= 4;2020 opcode1 |= 4;
2021 ops[0].reg >>= 1;2021 ops[0].reg >>= 1;
2022 }2022 }
2023 asm_emit_coprocessor_opcode(condition_code_of_token(token), coprocessor, opcode1, ops[0].reg, (ops[1].type == OP_IM8) ? ops[1].e.v : ops[1].reg, (ops[2].type == OP_IM8) ? ops[2].e.v : ops[2].reg, opcode2, 0);2023 asm_emit_coprocessor_opcode(S, condition_code_of_token(S, token), coprocessor, opcode1, ops[0].reg, (ops[1].type == OP_IM8) ? ops[1].e.v : ops[1].reg, (ops[2].type == OP_IM8) ? ops[2].e.v : ops[2].reg, opcode2, 0);
2024}2024}
2025 2025
2026static void asm_floating_point_data_processing_opcode(TCCState *s1, int token) {2026static void asm_floating_point_data_processing_opcode(TCCState *S, int token) {
2027 uint8_t coprocessor = CP_SINGLE_PRECISION_FLOAT;2027 uint8_t coprocessor = CP_SINGLE_PRECISION_FLOAT;
2028 uint8_t opcode1 = 0;2028 uint8_t opcode1 = 0;
2029 uint8_t opcode2 = 0; // (0 || 2) | register selection2029 uint8_t opcode2 = 0; // (0 || 2) | register selection
@@ -2078,30 +2078,30 @@ static void asm_floating_point_data_processing_opcode(TCCState *s1, int token) { · 48 unmodified lines
2078 2078
2079 for (nb_ops = 0; nb_ops < 3; ) {2079 for (nb_ops = 0; nb_ops < 3; ) {
2080 // Note: Necessary because parse_operand can't parse decimal numerals.2080 // Note: Necessary because parse_operand can't parse decimal numerals.
2081 if (nb_ops == 1 && (tok == '#' || tok == '$' || tok == TOK_PPNUM || tok == '-')) {2081 if (nb_ops == 1 && (S->tccpp_tok == '#' || S->tccpp_tok == '$' || S->tccpp_tok == TOK_PPNUM || S->tccpp_tok == '-')) {
2082 asm_floating_point_immediate_data_processing_opcode_tail(s1, token, coprocessor, ops[0].reg);2082 asm_floating_point_immediate_data_processing_opcode_tail(S, token, coprocessor, ops[0].reg);
2083 return;2083 return;
2084 }2084 }
2085 parse_operand(s1, &ops[nb_ops]);2085 parse_operand(S, &ops[nb_ops]);
2086 if (vmov && ops[nb_ops].type == OP_REG32) {2086 if (vmov && ops[nb_ops].type == OP_REG32) {
2087 ++nb_arm_regs;2087 ++nb_arm_regs;
2088 } else if (ops[nb_ops].type == OP_VREG32) {2088 } else if (ops[nb_ops].type == OP_VREG32) {
2089 if (coprocessor != CP_SINGLE_PRECISION_FLOAT) {2089 if (coprocessor != CP_SINGLE_PRECISION_FLOAT) {
2090 expect("'s<number>'");2090 expect(S, "'s<number>'");
2091 return;2091 return;
2092 }2092 }
2093 } else if (ops[nb_ops].type == OP_VREG64) {2093 } else if (ops[nb_ops].type == OP_VREG64) {
2094 if (coprocessor != CP_DOUBLE_PRECISION_FLOAT) {2094 if (coprocessor != CP_DOUBLE_PRECISION_FLOAT) {
2095 expect("'d<number>'");2095 expect(S, "'d<number>'");
2096 return;2096 return;
2097 }2097 }
2098 } else {2098 } else {
2099 expect("floating point register");2099 expect(S, "floating point register");
2100 return;2100 return;
2101 }2101 }
2102 ++nb_ops;2102 ++nb_ops;
2103 if (tok == ',')2103 if (S->tccpp_tok == ',')
2104 next();2104 next(S);
2105 else2105 else
2106 break;2106 break;
2107 }2107 }
@@ -2113,7 +2113,7 @@ static void asm_floating_point_data_processing_opcode(TCCState *s1, int token) { · 5 unmodified lines
2113 nb_ops = 3;2113 nb_ops = 3;
2114 }2114 }
2115 if (nb_ops < 3) {2115 if (nb_ops < 3) {
2116 tcc_error("Not enough operands for '%s' (%u)", get_tok_str(token, NULL), nb_ops);2116 tcc_error(S, "Not enough operands for '%s' (%u)", get_tok_str(S, token, NULL), nb_ops);
2117 return;2117 return;
2118 }2118 }
2119 }2119 }
@@ -2202,7 +2202,7 @@ static void asm_floating_point_data_processing_opcode(TCCState *s1, int token) { · 82 unmodified lines
2202 case TOK_ASM_vmoveq_f32:2202 case TOK_ASM_vmoveq_f32:
2203 case TOK_ASM_vmoveq_f64:2203 case TOK_ASM_vmoveq_f64:
2204 if (nb_arm_regs > 0) { // vmov.f32 r2, s3 or similar2204 if (nb_arm_regs > 0) { // vmov.f32 r2, s3 or similar
2205 asm_floating_point_reg_arm_reg_transfer_opcode_tail(s1, token, coprocessor, nb_arm_regs, nb_ops, ops);2205 asm_floating_point_reg_arm_reg_transfer_opcode_tail(S, token, coprocessor, nb_arm_regs, nb_ops, ops);
2206 return;2206 return;
2207 } else {2207 } else {
2208 opcode1 = 11; // "Other" instruction2208 opcode1 = 11; // "Other" instruction
@@ -2212,7 +2212,7 @@ static void asm_floating_point_data_processing_opcode(TCCState *s1, int token) { · 3 unmodified lines
2212 }2212 }
2213 break;2213 break;
2214 default:2214 default:
2215 expect("known floating point instruction");2215 expect(S, "known floating point instruction");
2216 return;2216 return;
2217 }2217 }
2218 2218
@@ -2236,10 +2236,10 @@ static void asm_floating_point_data_processing_opcode(TCCState *s1, int token) { · 17 unmodified lines
2236 }2236 }
2237 }2237 }
2238 2238
2239 asm_emit_coprocessor_opcode(condition_code_of_token(token), coprocessor, opcode1, ops[0].reg, (ops[1].type == OP_IM8) ? ops[1].e.v : ops[1].reg, (ops[2].type == OP_IM8) ? ops[2].e.v : ops[2].reg, opcode2, 0);2239 asm_emit_coprocessor_opcode(S, condition_code_of_token(S, token), coprocessor, opcode1, ops[0].reg, (ops[1].type == OP_IM8) ? ops[1].e.v : ops[1].reg, (ops[2].type == OP_IM8) ? ops[2].e.v : ops[2].reg, opcode2, 0);
2240}2240}
2241 2241
2242static void asm_floating_point_status_register_opcode(TCCState* s1, int token)2242static void asm_floating_point_status_register_opcode(TCCState* S, int token)
2243{2243{
2244 uint8_t coprocessor = CP_SINGLE_PRECISION_FLOAT;2244 uint8_t coprocessor = CP_SINGLE_PRECISION_FLOAT;
2245 uint8_t opcode;2245 uint8_t opcode;
@@ -2248,61 +2248,61 @@ static void asm_floating_point_status_register_opcode(TCCState* s1, int token) · 2 unmodified lines
2248 switch (ARM_INSTRUCTION_GROUP(token)) {2248 switch (ARM_INSTRUCTION_GROUP(token)) {
2249 case TOK_ASM_vmrseq:2249 case TOK_ASM_vmrseq:
2250 opcode = 0xf;2250 opcode = 0xf;
2251 if (tok == TOK_ASM_apsr_nzcv) {2251 if (S->tccpp_tok == TOK_ASM_apsr_nzcv) {
2252 arm_operand.type = OP_REG32;2252 arm_operand.type = OP_REG32;
2253 arm_operand.reg = 15; // not PC2253 arm_operand.reg = 15; // not PC
2254 next(); // skip apsr_nzcv2254 next(S); // skip apsr_nzcv
2255 } else {2255 } else {
2256 parse_operand(s1, &arm_operand);2256 parse_operand(S, &arm_operand);
2257 if (arm_operand.type == OP_REG32 && arm_operand.reg == 15) {2257 if (arm_operand.type == OP_REG32 && arm_operand.reg == 15) {
2258 tcc_error("'%s' does not support 'pc' as operand", get_tok_str(token, NULL));2258 tcc_error(S, "'%s' does not support 'pc' as operand", get_tok_str(S, token, NULL));
2259 return;2259 return;
2260 }2260 }
2261 }2261 }
2262 2262
2263 if (tok != ',')2263 if (S->tccpp_tok != ',')
2264 expect("','");2264 expect(S, "','");
2265 else2265 else
2266 next(); // skip ','2266 next(S); // skip ','
2267 vfp_sys_reg = asm_parse_vfp_status_regvar(tok);2267 vfp_sys_reg = asm_parse_vfp_status_regvar(S->tccpp_tok);
2268 next(); // skip vfp sys reg2268 next(S); // skip vfp sys reg
2269 if (arm_operand.type == OP_REG32 && arm_operand.reg == 15 && vfp_sys_reg != 1) {2269 if (arm_operand.type == OP_REG32 && arm_operand.reg == 15 && vfp_sys_reg != 1) {
2270 tcc_error("'%s' only supports the variant 'vmrs apsr_nzcv, fpscr' here", get_tok_str(token, NULL));2270 tcc_error(S, "'%s' only supports the variant 'vmrs apsr_nzcv, fpscr' here", get_tok_str(S, token, NULL));
2271 return;2271 return;
2272 }2272 }
2273 break;2273 break;
2274 case TOK_ASM_vmsreq:2274 case TOK_ASM_vmsreq:
2275 opcode = 0xe;2275 opcode = 0xe;
2276 vfp_sys_reg = asm_parse_vfp_status_regvar(tok);2276 vfp_sys_reg = asm_parse_vfp_status_regvar(S->tccpp_tok);
2277 next(); // skip vfp sys reg2277 next(S); // skip vfp sys reg
2278 if (tok != ',')2278 if (S->tccpp_tok != ',')
2279 expect("','");2279 expect(S, "','");
2280 else2280 else
2281 next(); // skip ','2281 next(S); // skip ','
2282 parse_operand(s1, &arm_operand);2282 parse_operand(S, &arm_operand);
2283 if (arm_operand.type == OP_REG32 && arm_operand.reg == 15) {2283 if (arm_operand.type == OP_REG32 && arm_operand.reg == 15) {
2284 tcc_error("'%s' does not support 'pc' as operand", get_tok_str(token, NULL));2284 tcc_error(S, "'%s' does not support 'pc' as operand", get_tok_str(S, token, NULL));
2285 return;2285 return;
2286 }2286 }
2287 break;2287 break;
2288 default:2288 default:
2289 expect("floating point status register instruction");2289 expect(S, "floating point status register instruction");
2290 return;2290 return;
2291 }2291 }
2292 if (vfp_sys_reg == -1) {2292 if (vfp_sys_reg == -1) {
2293 expect("VFP system register");2293 expect(S, "VFP system register");
2294 return;2294 return;
2295 }2295 }
2296 if (arm_operand.type != OP_REG32) {2296 if (arm_operand.type != OP_REG32) {
2297 expect("ARM register");2297 expect(S, "ARM register");
2298 return;2298 return;
2299 }2299 }
2300 asm_emit_coprocessor_opcode(condition_code_of_token(token), coprocessor, opcode, arm_operand.reg, vfp_sys_reg, 0x10, 0, 0);2300 asm_emit_coprocessor_opcode(S, condition_code_of_token(S, token), coprocessor, opcode, arm_operand.reg, vfp_sys_reg, 0x10, 0, 0);
2301}2301}
2302 2302
2303#endif2303#endif
2304 2304
2305static void asm_misc_single_data_transfer_opcode(TCCState *s1, int token)2305static void asm_misc_single_data_transfer_opcode(TCCState *S, int token)
2306{2306{
2307 Operand ops[3];2307 Operand ops[3];
2308 int exclam = 0;2308 int exclam = 0;
@@ -2322,42 +2322,42 @@ static void asm_misc_single_data_transfer_opcode(TCCState *s1, int token) · 13 unmodified lines
2322 // Here: 0 0 0 P U I W L << 202322 // Here: 0 0 0 P U I W L << 20
2323 // [compare single data transfer: 0 1 I P U B W L << 20]2323 // [compare single data transfer: 0 1 I P U B W L << 20]
2324 2324
2325 parse_operand(s1, &ops[0]);2325 parse_operand(S, &ops[0]);
2326 if (ops[0].type == OP_REG32)2326 if (ops[0].type == OP_REG32)
2327 opcode |= ENCODE_RD(ops[0].reg);2327 opcode |= ENCODE_RD(ops[0].reg);
2328 else {2328 else {
2329 expect("(destination operand) register");2329 expect(S, "(destination operand) register");
2330 return;2330 return;
2331 }2331 }
2332 if (tok != ',')2332 if (S->tccpp_tok != ',')
2333 expect("at least two arguments");2333 expect(S, "at least two arguments");
2334 else2334 else
2335 next(); // skip ','2335 next(S); // skip ','
2336 2336
2337 if (tok != '[')2337 if (S->tccpp_tok != '[')
2338 expect("'['");2338 expect(S, "'['");
2339 else2339 else
2340 next(); // skip '['2340 next(S); // skip '['
2341 2341
2342 parse_operand(s1, &ops[1]);2342 parse_operand(S, &ops[1]);
2343 if (ops[1].type == OP_REG32)2343 if (ops[1].type == OP_REG32)
2344 opcode |= ENCODE_RN(ops[1].reg);2344 opcode |= ENCODE_RN(ops[1].reg);
2345 else {2345 else {
2346 expect("(first source operand) register");2346 expect(S, "(first source operand) register");
2347 return;2347 return;
2348 }2348 }
2349 if (tok == ']') {2349 if (S->tccpp_tok == ']') {
2350 next();2350 next(S);
2351 closed_bracket = 1;2351 closed_bracket = 1;
2352 // exclam = 1; // implicit in hardware; don't do it in software2352 // exclam = 1; // implicit in hardware; don't do it in software
2353 }2353 }
2354 if (tok == ',') {2354 if (S->tccpp_tok == ',') {
2355 next(); // skip ','2355 next(S); // skip ','
2356 if (tok == '-') {2356 if (S->tccpp_tok == '-') {
2357 op2_minus = 1;2357 op2_minus = 1;
2358 next();2358 next(S);
2359 }2359 }
2360 parse_operand(s1, &ops[2]);2360 parse_operand(S, &ops[2]);
2361 } else {2361 } else {
2362 // end of input expression in brackets--assume 0 offset2362 // end of input expression in brackets--assume 0 offset
2363 ops[2].type = OP_IM8;2363 ops[2].type = OP_IM8;
@@ -2365,20 +2365,20 @@ static void asm_misc_single_data_transfer_opcode(TCCState *s1, int token) · 1 unmodified line
2365 opcode |= 1 << 24; // add offset before transfer2365 opcode |= 1 << 24; // add offset before transfer
2366 }2366 }
2367 if (!closed_bracket) {2367 if (!closed_bracket) {
2368 if (tok != ']')2368 if (S->tccpp_tok != ']')
2369 expect("']'");2369 expect(S, "']'");
2370 else2370 else
2371 next(); // skip ']'2371 next(S); // skip ']'
2372 opcode |= 1 << 24; // add offset before transfer2372 opcode |= 1 << 24; // add offset before transfer
2373 if (tok == '!') {2373 if (S->tccpp_tok == '!') {
2374 exclam = 1;2374 exclam = 1;
2375 next(); // skip '!'2375 next(S); // skip '!'
2376 }2376 }
2377 }2377 }
2378 2378
2379 if (exclam) {2379 if (exclam) {
2380 if ((opcode & (1 << 24)) == 0) {2380 if ((opcode & (1 << 24)) == 0) {
2381 tcc_error("result of '%s' would be unpredictable here", get_tok_str(token, NULL));2381 tcc_error(S, "result of '%s' would be unpredictable here", get_tok_str(S, token, NULL));
2382 return;2382 return;
2383 }2383 }
2384 opcode |= 1 << 21; // write offset back into register2384 opcode |= 1 << 21; // write offset back into register
@@ -2387,11 +2387,11 @@ static void asm_misc_single_data_transfer_opcode(TCCState *s1, int token) · 2 unmodified lines
2387 if (ops[2].type == OP_IM32 || ops[2].type == OP_IM8 || ops[2].type == OP_IM8N) {2387 if (ops[2].type == OP_IM32 || ops[2].type == OP_IM8 || ops[2].type == OP_IM8N) {
2388 int v = ops[2].e.v;2388 int v = ops[2].e.v;
2389 if (op2_minus)2389 if (op2_minus)
2390 tcc_error("minus before '#' not supported for immediate values");2390 tcc_error(S, "minus before '#' not supported for immediate values");
2391 if (v >= 0) {2391 if (v >= 0) {
2392 opcode |= 1 << 23; // up2392 opcode |= 1 << 23; // up
2393 if (v >= 0x100)2393 if (v >= 0x100)
2394 tcc_error("offset out of range for '%s'", get_tok_str(token, NULL));2394 tcc_error(S, "offset out of range for '%s'", get_tok_str(S, token, NULL));
2395 else {2395 else {
2396 // bits 11...8: immediate hi nibble2396 // bits 11...8: immediate hi nibble
2397 // bits 3...0: immediate lo nibble2397 // bits 3...0: immediate lo nibble
@@ -2400,7 +2400,7 @@ static void asm_misc_single_data_transfer_opcode(TCCState *s1, int token) · 2 unmodified lines
2400 }2400 }
2401 } else { // down2401 } else { // down
2402 if (v <= -0x100)2402 if (v <= -0x100)
2403 tcc_error("offset out of range for '%s'", get_tok_str(token, NULL));2403 tcc_error(S, "offset out of range for '%s'", get_tok_str(S, token, NULL));
2404 else {2404 else {
2405 v = -v;2405 v = -v;
2406 // bits 11...8: immediate hi nibble2406 // bits 11...8: immediate hi nibble
@@ -2415,7 +2415,7 @@ static void asm_misc_single_data_transfer_opcode(TCCState *s1, int token) · 8 unmodified lines
2415 opcode |= 1 << 23; // up2415 opcode |= 1 << 23; // up
2416 opcode |= ops[2].reg;2416 opcode |= ops[2].reg;
2417 } else2417 } else
2418 expect("register");2418 expect(S, "register");
2419 2419
2420 switch (ARM_INSTRUCTION_GROUP(token)) {2420 switch (ARM_INSTRUCTION_GROUP(token)) {
2421 case TOK_ASM_ldrsheq:2421 case TOK_ASM_ldrsheq:
@@ -2424,34 +2424,34 @@ static void asm_misc_single_data_transfer_opcode(TCCState *s1, int token) · 2 unmodified lines
2424 case TOK_ASM_ldrsbeq:2424 case TOK_ASM_ldrsbeq:
2425 opcode |= 1 << 6; // sign extend2425 opcode |= 1 << 6; // sign extend
2426 opcode |= 1 << 20; // L2426 opcode |= 1 << 20; // L
2427 asm_emit_opcode(token, opcode);2427 asm_emit_opcode(S, token, opcode);
2428 break;2428 break;
2429 case TOK_ASM_ldrheq:2429 case TOK_ASM_ldrheq:
2430 opcode |= 1 << 5; // halfword, not byte2430 opcode |= 1 << 5; // halfword, not byte
2431 opcode |= 1 << 20; // L2431 opcode |= 1 << 20; // L
2432 asm_emit_opcode(token, opcode);2432 asm_emit_opcode(S, token, opcode);
2433 break;2433 break;
2434 case TOK_ASM_strheq:2434 case TOK_ASM_strheq:
2435 opcode |= 1 << 5; // halfword, not byte2435 opcode |= 1 << 5; // halfword, not byte
2436 asm_emit_opcode(token, opcode);2436 asm_emit_opcode(S, token, opcode);
2437 break;2437 break;
2438 }2438 }
2439}2439}
2440 2440
2441/* Note: almost dupe of encbranch in arm-gen.c */2441/* Note: almost dupe of encbranch in arm-gen.c */
2442static uint32_t encbranchoffset(int pos, int addr, int fail)2442static uint32_t encbranchoffset(TCCState* S, int pos, int addr, int fail)
2443{2443{
2444 addr-=pos+8;2444 addr-=pos+8;
2445 addr/=4;2445 addr/=4;
2446 if(addr>=0x7fffff || addr<-0x800000) {2446 if(addr>=0x7fffff || addr<-0x800000) {
2447 if(fail)2447 if(fail)
2448 tcc_error("branch offset is too far");2448 tcc_error(S, "branch offset is too far");
2449 return 0;2449 return 0;
2450 }2450 }
2451 return /*not 0x0A000000|*/(addr&0xffffff);2451 return /*not 0x0A000000|*/(addr&0xffffff);
2452}2452}
2453 2453
2454static void asm_branch_opcode(TCCState *s1, int token)2454static void asm_branch_opcode(TCCState *S, int token)
2455{2455{
2456 int jmp_disp = 0;2456 int jmp_disp = 0;
2457 Operand op;2457 Operand op;
@@ -2461,63 +2461,63 @@ static void asm_branch_opcode(TCCState *s1, int token) · 3 unmodified lines
2461 switch (ARM_INSTRUCTION_GROUP(token)) {2461 switch (ARM_INSTRUCTION_GROUP(token)) {
2462 case TOK_ASM_beq:2462 case TOK_ASM_beq:
2463 case TOK_ASM_bleq:2463 case TOK_ASM_bleq:
2464 asm_expr(s1, &e);2464 asm_expr(S, &e);
2465 esym = elfsym(e.sym);2465 esym = elfsym(S, e.sym);
2466 if (!esym || esym->st_shndx != cur_text_section->sh_num) {2466 if (!esym || esym->st_shndx != cur_text_section->sh_num) {
2467 tcc_error("invalid branch target");2467 tcc_error(S, "invalid branch target");
2468 return;2468 return;
2469 }2469 }
2470 jmp_disp = encbranchoffset(ind, e.v + esym->st_value, 1);2470 jmp_disp = encbranchoffset(S, S->tccgen_ind, e.v + esym->st_value, 1);
2471 break;2471 break;
2472 default:2472 default:
2473 parse_operand(s1, &op);2473 parse_operand(S, &op);
2474 break;2474 break;
2475 }2475 }
2476 switch (ARM_INSTRUCTION_GROUP(token)) {2476 switch (ARM_INSTRUCTION_GROUP(token)) {
2477 case TOK_ASM_beq:2477 case TOK_ASM_beq:
2478 asm_emit_opcode(token, (0xa << 24) | (jmp_disp & 0xffffff));2478 asm_emit_opcode(S, token, (0xa << 24) | (jmp_disp & 0xffffff));
2479 break;2479 break;
2480 case TOK_ASM_bleq:2480 case TOK_ASM_bleq:
2481 asm_emit_opcode(token, (0xb << 24) | (jmp_disp & 0xffffff));2481 asm_emit_opcode(S, token, (0xb << 24) | (jmp_disp & 0xffffff));
2482 break;2482 break;
2483 case TOK_ASM_bxeq:2483 case TOK_ASM_bxeq:
2484 if (op.type != OP_REG32)2484 if (op.type != OP_REG32)
2485 expect("register");2485 expect(S, "register");
2486 else2486 else
2487 asm_emit_opcode(token, (0x12fff1 << 4) | op.reg);2487 asm_emit_opcode(S, token, (0x12fff1 << 4) | op.reg);
2488 break;2488 break;
2489 case TOK_ASM_blxeq:2489 case TOK_ASM_blxeq:
2490 if (op.type != OP_REG32)2490 if (op.type != OP_REG32)
2491 expect("register");2491 expect(S, "register");
2492 else2492 else
2493 asm_emit_opcode(token, (0x12fff3 << 4) | op.reg);2493 asm_emit_opcode(S, token, (0x12fff3 << 4) | op.reg);
2494 break;2494 break;
2495 default:2495 default:
2496 expect("branch instruction");2496 expect(S, "branch instruction");
2497 }2497 }
2498}2498}
2499 2499
2500ST_FUNC void asm_opcode(TCCState *s1, int token)2500ST_FUNC void asm_opcode(TCCState *S, int token)
2501{2501{
2502 while (token == TOK_LINEFEED) {2502 while (token == TOK_LINEFEED) {
2503 next();2503 next(S);
2504 token = tok;2504 token = S->tccpp_tok;
2505 }2505 }
2506 if (token == TOK_EOF)2506 if (token == TOK_EOF)
2507 return;2507 return;
2508 if (token < TOK_ASM_nopeq) { // no condition code2508 if (token < TOK_ASM_nopeq) { // no condition code
2509 switch (token) {2509 switch (token) {
2510 case TOK_ASM_cdp2:2510 case TOK_ASM_cdp2:
2511 asm_coprocessor_opcode(s1, token);2511 asm_coprocessor_opcode(S, token);
2512 return;2512 return;
2513 case TOK_ASM_ldc2:2513 case TOK_ASM_ldc2:
2514 case TOK_ASM_ldc2l:2514 case TOK_ASM_ldc2l:
2515 case TOK_ASM_stc2:2515 case TOK_ASM_stc2:
2516 case TOK_ASM_stc2l:2516 case TOK_ASM_stc2l:
2517 asm_coprocessor_data_transfer_opcode(s1, token);2517 asm_coprocessor_data_transfer_opcode(S, token);
2518 return;2518 return;
2519 default:2519 default:
2520 expect("instruction");2520 expect(S, "instruction");
2521 return;2521 return;
2522 }2522 }
2523 }2523 }
@@ -2535,22 +2535,22 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 11 unmodified lines
2535 case TOK_ASM_ldmdbeq:2535 case TOK_ASM_ldmdbeq:
2536 case TOK_ASM_stmibeq:2536 case TOK_ASM_stmibeq:
2537 case TOK_ASM_ldmibeq:2537 case TOK_ASM_ldmibeq:
2538 asm_block_data_transfer_opcode(s1, token);2538 asm_block_data_transfer_opcode(S, token);
2539 return;2539 return;
2540 case TOK_ASM_nopeq:2540 case TOK_ASM_nopeq:
2541 case TOK_ASM_wfeeq:2541 case TOK_ASM_wfeeq:
2542 case TOK_ASM_wfieq:2542 case TOK_ASM_wfieq:
2543 asm_nullary_opcode(token);2543 asm_nullary_opcode(S, token);
2544 return;2544 return;
2545 case TOK_ASM_swieq:2545 case TOK_ASM_swieq:
2546 case TOK_ASM_svceq:2546 case TOK_ASM_svceq:
2547 asm_unary_opcode(s1, token);2547 asm_unary_opcode(S, token);
2548 return;2548 return;
2549 case TOK_ASM_beq:2549 case TOK_ASM_beq:
2550 case TOK_ASM_bleq:2550 case TOK_ASM_bleq:
2551 case TOK_ASM_bxeq:2551 case TOK_ASM_bxeq:
2552 case TOK_ASM_blxeq:2552 case TOK_ASM_blxeq:
2553 asm_branch_opcode(s1, token);2553 asm_branch_opcode(S, token);
2554 return;2554 return;
2555 case TOK_ASM_clzeq:2555 case TOK_ASM_clzeq:
2556 case TOK_ASM_sxtbeq:2556 case TOK_ASM_sxtbeq:
@@ -2559,7 +2559,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 2 unmodified lines
2559 case TOK_ASM_uxtheq:2559 case TOK_ASM_uxtheq:
2560 case TOK_ASM_movteq:2560 case TOK_ASM_movteq:
2561 case TOK_ASM_movweq:2561 case TOK_ASM_movweq:
2562 asm_binary_opcode(s1, token);2562 asm_binary_opcode(S, token);
2563 return;2563 return;
2564 2564
2565 case TOK_ASM_ldreq:2565 case TOK_ASM_ldreq:
@@ -2570,14 +2570,14 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 4 unmodified lines
2570 case TOK_ASM_ldrexbeq:2570 case TOK_ASM_ldrexbeq:
2571 case TOK_ASM_strexeq:2571 case TOK_ASM_strexeq:
2572 case TOK_ASM_strexbeq:2572 case TOK_ASM_strexbeq:
2573 asm_single_data_transfer_opcode(s1, token);2573 asm_single_data_transfer_opcode(S, token);
2574 return;2574 return;
2575 2575
2576 case TOK_ASM_ldrheq:2576 case TOK_ASM_ldrheq:
2577 case TOK_ASM_ldrsheq:2577 case TOK_ASM_ldrsheq:
2578 case TOK_ASM_ldrsbeq:2578 case TOK_ASM_ldrsbeq:
2579 case TOK_ASM_strheq:2579 case TOK_ASM_strheq:
2580 asm_misc_single_data_transfer_opcode(s1, token);2580 asm_misc_single_data_transfer_opcode(S, token);
2581 return;2581 return;
2582 2582
2583 case TOK_ASM_andeq:2583 case TOK_ASM_andeq:
@@ -2612,7 +2612,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 28 unmodified lines
2612 case TOK_ASM_movseq:2612 case TOK_ASM_movseq:
2613 case TOK_ASM_bicseq:2613 case TOK_ASM_bicseq:
2614 case TOK_ASM_mvnseq:2614 case TOK_ASM_mvnseq:
2615 asm_data_processing_opcode(s1, token);2615 asm_data_processing_opcode(S, token);
2616 return;2616 return;
2617 2617
2618 case TOK_ASM_lsleq:2618 case TOK_ASM_lsleq:
@@ -2625,14 +2625,14 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 6 unmodified lines
2625 case TOK_ASM_rorseq:2625 case TOK_ASM_rorseq:
2626 case TOK_ASM_rrxseq:2626 case TOK_ASM_rrxseq:
2627 case TOK_ASM_rrxeq:2627 case TOK_ASM_rrxeq:
2628 asm_shift_opcode(s1, token);2628 asm_shift_opcode(S, token);
2629 return;2629 return;
2630 2630
2631 case TOK_ASM_muleq:2631 case TOK_ASM_muleq:
2632 case TOK_ASM_mulseq:2632 case TOK_ASM_mulseq:
2633 case TOK_ASM_mlaeq:2633 case TOK_ASM_mlaeq:
2634 case TOK_ASM_mlaseq:2634 case TOK_ASM_mlaseq:
2635 asm_multiplication_opcode(s1, token);2635 asm_multiplication_opcode(S, token);
2636 return;2636 return;
2637 2637
2638 case TOK_ASM_smulleq:2638 case TOK_ASM_smulleq:
@@ -2643,26 +2643,26 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 4 unmodified lines
2643 case TOK_ASM_smlalseq:2643 case TOK_ASM_smlalseq:
2644 case TOK_ASM_umlaleq:2644 case TOK_ASM_umlaleq:
2645 case TOK_ASM_umlalseq:2645 case TOK_ASM_umlalseq:
2646 asm_long_multiplication_opcode(s1, token);2646 asm_long_multiplication_opcode(S, token);
2647 return;2647 return;
2648 2648
2649 case TOK_ASM_cdpeq:2649 case TOK_ASM_cdpeq:
2650 case TOK_ASM_mcreq:2650 case TOK_ASM_mcreq:
2651 case TOK_ASM_mrceq:2651 case TOK_ASM_mrceq:
2652 asm_coprocessor_opcode(s1, token);2652 asm_coprocessor_opcode(S, token);
2653 return;2653 return;
2654 2654
2655 case TOK_ASM_ldceq:2655 case TOK_ASM_ldceq:
2656 case TOK_ASM_ldcleq:2656 case TOK_ASM_ldcleq:
2657 case TOK_ASM_stceq:2657 case TOK_ASM_stceq:
2658 case TOK_ASM_stcleq:2658 case TOK_ASM_stcleq:
2659 asm_coprocessor_data_transfer_opcode(s1, token);2659 asm_coprocessor_data_transfer_opcode(S, token);
2660 return;2660 return;
2661 2661
2662#if defined(TCC_ARM_VFP)2662#if defined(TCC_ARM_VFP)
2663 case TOK_ASM_vldreq:2663 case TOK_ASM_vldreq:
2664 case TOK_ASM_vstreq:2664 case TOK_ASM_vstreq:
2665 asm_floating_point_single_data_transfer_opcode(s1, token);2665 asm_floating_point_single_data_transfer_opcode(S, token);
2666 return;2666 return;
2667 2667
2668 case TOK_ASM_vmlaeq_f32:2668 case TOK_ASM_vmlaeq_f32:
@@ -2695,7 +2695,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 26 unmodified lines
2695 case TOK_ASM_vcmpeq_f64:2695 case TOK_ASM_vcmpeq_f64:
2696 case TOK_ASM_vcmpeeq_f64:2696 case TOK_ASM_vcmpeeq_f64:
2697 case TOK_ASM_vmoveq_f64:2697 case TOK_ASM_vmoveq_f64:
2698 asm_floating_point_data_processing_opcode(s1, token);2698 asm_floating_point_data_processing_opcode(S, token);
2699 return;2699 return;
2700 2700
2701 case TOK_ASM_vcvtreq_s32_f32:2701 case TOK_ASM_vcvtreq_s32_f32:
@@ -2712,7 +2712,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 10 unmodified lines
2712 case TOK_ASM_vcvteq_f32_u32:2712 case TOK_ASM_vcvteq_f32_u32:
2713 case TOK_ASM_vcvteq_f64_f32:2713 case TOK_ASM_vcvteq_f64_f32:
2714 case TOK_ASM_vcvteq_f32_f64:2714 case TOK_ASM_vcvteq_f32_f64:
2715 asm_floating_point_vcvt_data_processing_opcode(s1, token);2715 asm_floating_point_vcvt_data_processing_opcode(S, token);
2716 return;2716 return;
2717 2717
2718 case TOK_ASM_vpusheq:2718 case TOK_ASM_vpusheq:
@@ -2723,21 +2723,21 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 4 unmodified lines
2723 case TOK_ASM_vstmeq:2723 case TOK_ASM_vstmeq:
2724 case TOK_ASM_vstmiaeq:2724 case TOK_ASM_vstmiaeq:
2725 case TOK_ASM_vstmdbeq:2725 case TOK_ASM_vstmdbeq:
2726 asm_floating_point_block_data_transfer_opcode(s1, token);2726 asm_floating_point_block_data_transfer_opcode(S, token);
2727 return;2727 return;
2728 2728
2729 case TOK_ASM_vmsreq:2729 case TOK_ASM_vmsreq:
2730 case TOK_ASM_vmrseq:2730 case TOK_ASM_vmrseq:
2731 asm_floating_point_status_register_opcode(s1, token);2731 asm_floating_point_status_register_opcode(S, token);
2732 return;2732 return;
2733#endif2733#endif
2734 2734
2735 default:2735 default:
2736 expect("known instruction");2736 expect(S, "known instruction");
2737 }2737 }
2738}2738}
2739 2739
2740ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier)2740ST_FUNC void subst_asm_operand(TCCState* S, CString *add_str, SValue *sv, int modifier)
2741{2741{
2742 int r, reg, size, val;2742 int r, reg, size, val;
2743 char buf[64];2743 char buf[64];
@@ -2746,45 +2746,45 @@ ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier) · 2 unmodified lines
2746 if ((r & VT_VALMASK) == VT_CONST) {2746 if ((r & VT_VALMASK) == VT_CONST) {
2747 if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n' &&2747 if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n' &&
2748 modifier != 'P')2748 modifier != 'P')
2749 cstr_ccat(add_str, '#');2749 cstr_ccat(S, add_str, '#');
2750 if (r & VT_SYM) {2750 if (r & VT_SYM) {
2751 const char *name = get_tok_str(sv->sym->v, NULL);2751 const char *name = get_tok_str(S, sv->sym->v, NULL);
2752 if (sv->sym->v >= SYM_FIRST_ANOM) {2752 if (sv->sym->v >= SYM_FIRST_ANOM) {
2753 /* In case of anonymous symbols ("L.42", used2753 /* In case of anonymous symbols ("L.42", used
2754 for static data labels) we can't find them2754 for static data labels) we can't find them
2755 in the C symbol table when later looking up2755 in the C symbol table when later looking up
2756 this name. So enter them now into the asm label2756 this name. So enter them now into the asm label
2757 list when we still know the symbol. */2757 list when we still know the symbol. */
2758 get_asm_sym(tok_alloc(name, strlen(name))->tok, sv->sym);2758 get_asm_sym(S, tok_alloc(S, name, strlen(name))->tok, sv->sym);
2759 }2759 }
2760 if (tcc_state->leading_underscore)2760 if (S->leading_underscore)
2761 cstr_ccat(add_str, '_');2761 cstr_ccat(S, add_str, '_');
2762 cstr_cat(add_str, name, -1);2762 cstr_cat(S, add_str, name, -1);
2763 if ((uint32_t) sv->c.i == 0)2763 if ((uint32_t) sv->c.i == 0)
2764 goto no_offset;2764 goto no_offset;
2765 cstr_ccat(add_str, '+');2765 cstr_ccat(S, add_str, '+');
2766 }2766 }
2767 val = sv->c.i;2767 val = sv->c.i;
2768 if (modifier == 'n')2768 if (modifier == 'n')
2769 val = -val;2769 val = -val;
2770 snprintf(buf, sizeof(buf), "%d", (int) sv->c.i);2770 snprintf(buf, sizeof(buf), "%d", (int) sv->c.i);
2771 cstr_cat(add_str, buf, -1);2771 cstr_cat(S, add_str, buf, -1);
2772 no_offset:;2772 no_offset:;
2773 } else if ((r & VT_VALMASK) == VT_LOCAL) {2773 } else if ((r & VT_VALMASK) == VT_LOCAL) {
2774 snprintf(buf, sizeof(buf), "[fp,#%d]", (int) sv->c.i);2774 snprintf(buf, sizeof(buf), "[fp,#%d]", (int) sv->c.i);
2775 cstr_cat(add_str, buf, -1);2775 cstr_cat(S, add_str, buf, -1);
2776 } else if (r & VT_LVAL) {2776 } else if (r & VT_LVAL) {
2777 reg = r & VT_VALMASK;2777 reg = r & VT_VALMASK;
2778 if (reg >= VT_CONST)2778 if (reg >= VT_CONST)
2779 tcc_internal_error("");2779 tcc_internal_error(S, "");
2780 snprintf(buf, sizeof(buf), "[%s]",2780 snprintf(buf, sizeof(buf), "[%s]",
2781 get_tok_str(TOK_ASM_r0 + reg, NULL));2781 get_tok_str(S, TOK_ASM_r0 + reg, NULL));
2782 cstr_cat(add_str, buf, -1);2782 cstr_cat(S, add_str, buf, -1);
2783 } else {2783 } else {
2784 /* register case */2784 /* register case */
2785 reg = r & VT_VALMASK;2785 reg = r & VT_VALMASK;
2786 if (reg >= VT_CONST)2786 if (reg >= VT_CONST)
2787 tcc_internal_error("");2787 tcc_internal_error(S, "");
2788 2788
2789 /* choose register operand size */2789 /* choose register operand size */
2790 if ((sv->type.t & VT_BTYPE) == VT_BYTE ||2790 if ((sv->type.t & VT_BTYPE) == VT_BYTE ||
@@ -2808,13 +2808,13 @@ ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier) · 17 unmodified lines
2808 reg = TOK_ASM_r0 + reg;2808 reg = TOK_ASM_r0 + reg;
2809 break;2809 break;
2810 }2810 }
2811 snprintf(buf, sizeof(buf), "%s", get_tok_str(reg, NULL));2811 snprintf(buf, sizeof(buf), "%s", get_tok_str(S, reg, NULL));
2812 cstr_cat(add_str, buf, -1);2812 cstr_cat(S, add_str, buf, -1);
2813 }2813 }
2814}2814}
2815 2815
2816/* generate prolog and epilog code for asm statement */2816/* generate prolog and epilog code for asm statement */
2817ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,2817ST_FUNC void asm_gen_code(TCCState* S, ASMOperand *operands, int nb_operands,
2818 int nb_outputs, int is_output,2818 int nb_outputs, int is_output,
2819 uint8_t *clobber_regs,2819 uint8_t *clobber_regs,
2820 int out_reg)2820 int out_reg)
@@ -2844,7 +2844,7 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, · 23 unmodified lines
2844 if (!is_output) { // prolog2844 if (!is_output) { // prolog
2845 /* generate reg save code */2845 /* generate reg save code */
2846 if (saved_regset)2846 if (saved_regset)
2847 gen_le32(0xe92d0000 | saved_regset); // push {...}2847 gen_le32(S, 0xe92d0000 | saved_regset); // push {...}
2848 2848
2849 /* generate load code */2849 /* generate load code */
2850 for(i = 0; i < nb_operands; i++) {2850 for(i = 0; i < nb_operands; i++) {
@@ -2858,12 +2858,12 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, · 7 unmodified lines
2858 sv = *op->vt;2858 sv = *op->vt;
2859 sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL | VT_LVAL;2859 sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL | VT_LVAL;
2860 sv.type.t = VT_PTR;2860 sv.type.t = VT_PTR;
2861 load(op->reg, &sv);2861 load(S, op->reg, &sv);
2862 } else if (i >= nb_outputs || op->is_rw) { // not write-only2862 } else if (i >= nb_outputs || op->is_rw) { // not write-only
2863 /* load value in register */2863 /* load value in register */
2864 load(op->reg, op->vt);2864 load(S, op->reg, op->vt);
2865 if (op->is_llong)2865 if (op->is_llong)
2866 tcc_error("long long not implemented");2866 tcc_error(S, "long long not implemented");
2867 }2867 }
2868 }2868 }
2869 }2869 }
@@ -2878,29 +2878,29 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, · 8 unmodified lines
2878 sv = *op->vt;2878 sv = *op->vt;
2879 sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL;2879 sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL;
2880 sv.type.t = VT_PTR;2880 sv.type.t = VT_PTR;
2881 load(out_reg, &sv);2881 load(S, out_reg, &sv);
2882 2882
2883 sv = *op->vt;2883 sv = *op->vt;
2884 sv.r = (sv.r & ~VT_VALMASK) | out_reg;2884 sv.r = (sv.r & ~VT_VALMASK) | out_reg;
2885 store(op->reg, &sv);2885 store(S, op->reg, &sv);
2886 }2886 }
2887 } else {2887 } else {
2888 store(op->reg, op->vt);2888 store(S, op->reg, op->vt);
2889 if (op->is_llong)2889 if (op->is_llong)
2890 tcc_error("long long not implemented");2890 tcc_error(S, "long long not implemented");
2891 }2891 }
2892 }2892 }
2893 }2893 }
2894 2894
2895 /* generate reg restore code */2895 /* generate reg restore code */
2896 if (saved_regset)2896 if (saved_regset)
2897 gen_le32(0xe8bd0000 | saved_regset); // pop {...}2897 gen_le32(S, 0xe8bd0000 | saved_regset); // pop {...}
2898 }2898 }
2899}2899}
2900 2900
2901/* return the constraint priority (we allocate first the lowest2901/* return the constraint priority (we allocate first the lowest
2902 numbered constraints) */2902 numbered constraints) */
2903static inline int constraint_priority(const char *str)2903static inline int constraint_priority(TCCState* S, const char *str)
2904{2904{
2905 int priority, c, pr;2905 int priority, c, pr;
2906 2906
@@ -2927,7 +2927,7 @@ static inline int constraint_priority(const char *str) · 20 unmodified lines
2927 pr = 4;2927 pr = 4;
2928 break;2928 break;
2929 default:2929 default:
2930 tcc_error("unknown constraint '%c'", c);2930 tcc_error(S, "unknown constraint '%c'", c);
2931 pr = 0;2931 pr = 0;
2932 }2932 }
2933 if (pr > priority)2933 if (pr > priority)
@@ -2956,7 +2956,7 @@ static const char *skip_constraint_modifiers(const char *p) · 22 unmodified lines
2956 2956
2957#define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask)2957#define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask)
2958 2958
2959ST_FUNC void asm_compute_constraints(ASMOperand *operands,2959ST_FUNC void asm_compute_constraints(TCCState* S, ASMOperand *operands,
2960 int nb_operands, int nb_outputs,2960 int nb_operands, int nb_outputs,
2961 const uint8_t *clobber_regs,2961 const uint8_t *clobber_regs,
2962 int *pout_reg)2962 int *pout_reg)
@@ -3009,13 +3009,13 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 46 unmodified lines
3009 str = skip_constraint_modifiers(str);3009 str = skip_constraint_modifiers(str);
3010 if (isnum(*str) || *str == '[') {3010 if (isnum(*str) || *str == '[') {
3011 /* this is a reference to another constraint */3011 /* this is a reference to another constraint */
3012 k = find_constraint(operands, nb_operands, str, NULL);3012 k = find_constraint(S, operands, nb_operands, str, NULL);
3013 if ((unsigned) k >= i || i < nb_outputs)3013 if ((unsigned) k >= i || i < nb_outputs)
3014 tcc_error("invalid reference in constraint %d ('%s')",3014 tcc_error(S, "invalid reference in constraint %d ('%s')",
3015 i, str);3015 i, str);
3016 op->ref_index = k;3016 op->ref_index = k;
3017 if (operands[k].input_index >= 0)3017 if (operands[k].input_index >= 0)
3018 tcc_error("cannot reference twice the same operand");3018 tcc_error(S, "cannot reference twice the same operand");
3019 operands[k].input_index = i;3019 operands[k].input_index = i;
3020 op->priority = 5;3020 op->priority = 5;
3021 } else if ((op->vt->r & VT_VALMASK) == VT_LOCAL3021 } else if ((op->vt->r & VT_VALMASK) == VT_LOCAL
@@ -3024,7 +3024,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 2 unmodified lines
3024 op->priority = 1;3024 op->priority = 1;
3025 op->reg = reg;3025 op->reg = reg;
3026 } else {3026 } else {
3027 op->priority = constraint_priority(str);3027 op->priority = constraint_priority(S, str);
3028 }3028 }
3029 }3029 }
3030 3030
@@ -3073,7 +3073,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 42 unmodified lines
3073 if (op->reg >= 0) {3073 if (op->reg >= 0) {
3074 if (is_reg_allocated(op->reg))3074 if (is_reg_allocated(op->reg))
3075 tcc_error3075 tcc_error
3076 ("asm regvar requests register that's taken already");3076 (S, "asm regvar requests register that's taken already");
3077 reg = op->reg;3077 reg = op->reg;
3078 goto reg_found;3078 goto reg_found;
3079 }3079 }
@@ -3087,7 +3087,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 7 unmodified lines
3087 /* FALL THRU */3087 /* FALL THRU */
3088 case '&': // Operand is clobbered before the instruction is done using the input operands3088 case '&': // Operand is clobbered before the instruction is done using the input operands
3089 if (j >= nb_outputs)3089 if (j >= nb_outputs)
3090 tcc_error("'%c' modifier can only be applied to outputs",3090 tcc_error(S, "'%c' modifier can only be applied to outputs",
3091 c);3091 c);
3092 reg_mask = REG_IN_MASK | REG_OUT_MASK;3092 reg_mask = REG_IN_MASK | REG_OUT_MASK;
3093 goto try_next;3093 goto try_next;
@@ -3147,7 +3147,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 53 unmodified lines
3147 }3147 }
3148 break;3148 break;
3149 default:3149 default:
3150 tcc_error("asm constraint %d ('%s') could not be satisfied",3150 tcc_error(S, "asm constraint %d ('%s') could not be satisfied",
3151 j, op->constraint);3151 j, op->constraint);
3152 break;3152 break;
3153 }3153 }
@@ -3169,7 +3169,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 15 unmodified lines
3169 if (!(regs_allocated[reg] & REG_OUT_MASK))3169 if (!(regs_allocated[reg] & REG_OUT_MASK))
3170 goto reg_found2;3170 goto reg_found2;
3171 }3171 }
3172 tcc_error("could not find free output register for reloading");3172 tcc_error(S, "could not find free output register for reloading");
3173 reg_found2:3173 reg_found2:
3174 *pout_reg = reg;3174 *pout_reg = reg;
3175 break;3175 break;
@@ -3183,7 +3183,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 7 unmodified lines
3183 op = &operands[j];3183 op = &operands[j];
3184 printf("%%%d [%s]: \"%s\" r=0x%04x reg=%d\n",3184 printf("%%%d [%s]: \"%s\" r=0x%04x reg=%d\n",
3185 j,3185 j,
3186 op->id ? get_tok_str(op->id, NULL) : "",3186 op->id ? get_tok_str(S, op->id, NULL) : "",
3187 op->constraint, op->vt->r, op->reg);3187 op->constraint, op->vt->r, op->reg);
3188 }3188 }
3189 if (*pout_reg >= 0)3189 if (*pout_reg >= 0)
@@ -3191,7 +3191,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 1 unmodified line
3191#endif3191#endif
3192}3192}
3193 3193
3194ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str)3194ST_FUNC void asm_clobber(TCCState* S, uint8_t *clobber_regs, const char *str)
3195{3195{
3196 int reg;3196 int reg;
3197 TokenSym *ts;3197 TokenSym *ts;
@@ -3200,17 +3200,17 @@ ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str) · 2 unmodified lines
3200 !strcmp(str, "cc") ||3200 !strcmp(str, "cc") ||
3201 !strcmp(str, "flags"))3201 !strcmp(str, "flags"))
3202 return;3202 return;
3203 ts = tok_alloc(str, strlen(str));3203 ts = tok_alloc(S, str, strlen(str));
3204 reg = asm_parse_regvar(ts->tok);3204 reg = asm_parse_regvar(S, ts->tok);
3205 if (reg == -1) {3205 if (reg == -1) {
3206 tcc_error("invalid clobber register '%s'", str);3206 tcc_error(S, "invalid clobber register '%s'", str);
3207 }3207 }
3208 clobber_regs[reg] = 1;3208 clobber_regs[reg] = 1;
3209}3209}
3210 3210
3211/* If T refers to a register then return the register number and type.3211/* If T refers to a register then return the register number and type.
3212 Otherwise return -1. */3212 Otherwise return -1. */
3213ST_FUNC int asm_parse_regvar (int t)3213ST_FUNC int asm_parse_regvar (TCCState *S, int t)
3214{3214{
3215 if (t >= TOK_ASM_r0 && t <= TOK_ASM_pc) { /* register name */3215 if (t >= TOK_ASM_r0 && t <= TOK_ASM_pc) { /* register name */
3216 switch (t) {3216 switch (t) {
arm-gen.c+563−570
@@ -179,24 +179,17 @@ ST_DATA const int reg_classes[NB_REGS] = { · 178 unmodified lines
179static int func_sub_sp_offset, last_itod_magic;179static int func_sub_sp_offset, last_itod_magic;
180static int leaffunc;180static int leaffunc;
181 181
182#if defined(CONFIG_TCC_BCHECK)
183static addr_t func_bound_offset;
184static unsigned long func_bound_ind;
185ST_DATA int func_bound_add_epilog;
186#endif
187
188#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)182#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
189static CType float_type, double_type, func_float_type, func_double_type;183ST_FUNC void arm_init(TCCState *S)
190ST_FUNC void arm_init(struct TCCState *s)
191{184{
192 float_type.t = VT_FLOAT;185 S->armgen_float_type.t = VT_FLOAT;
193 double_type.t = VT_DOUBLE;186 S->armgen_double_type.t = VT_DOUBLE;
194 func_float_type.t = VT_FUNC;187 S->armgen_func_float_type.t = VT_FUNC;
195 func_float_type.ref = sym_push(SYM_FIELD, &float_type, FUNC_CDECL, FUNC_OLD);188 S->armgen_func_float_type.ref = sym_push(S, SYM_FIELD, &S->armgen_float_type, FUNC_CDECL, FUNC_OLD);
196 func_double_type.t = VT_FUNC;189 S->armgen_func_double_type.t = VT_FUNC;
197 func_double_type.ref = sym_push(SYM_FIELD, &double_type, FUNC_CDECL, FUNC_OLD);190 S->armgen_func_double_type.ref = sym_push(S, SYM_FIELD, &S->armgen_double_type, FUNC_CDECL, FUNC_OLD);
198 191
199 float_abi = s->float_abi;192 float_abi = S->float_abi;
200#ifndef TCC_ARM_HARDFLOAT193#ifndef TCC_ARM_HARDFLOAT
201// XXX: Works on OpenBSD194// XXX: Works on OpenBSD
202// # warning "soft float ABI currently not supported: default to softfp"195// # warning "soft float ABI currently not supported: default to softfp"
@@ -223,15 +216,15 @@ ST_FUNC void arm_init(struct TCCState *s) · 20 unmodified lines
223 216
224#define CHECK_R(r) ((r) >= TREG_R0 && (r) <= TREG_LR)217#define CHECK_R(r) ((r) >= TREG_R0 && (r) <= TREG_LR)
225 218
226static int two2mask(int a,int b) {219static int two2mask(TCCState* S, int a,int b) {
227 if (!CHECK_R(a) || !CHECK_R(b))220 if (!CHECK_R(a) || !CHECK_R(b))
228 tcc_error("compiler error! registers %i,%i is not valid",a,b);221 tcc_error(S, "compiler error! registers %i,%i is not valid",a,b);
229 return (reg_classes[a]|reg_classes[b])&~(RC_INT|RC_FLOAT);222 return (reg_classes[a]|reg_classes[b])&~(RC_INT|RC_FLOAT);
230}223}
231 224
232static int regmask(int r) {225static int regmask(TCCState* S, int r) {
233 if (!CHECK_R(r))226 if (!CHECK_R(r))
234 tcc_error("compiler error! register %i is not valid",r);227 tcc_error(S, "compiler error! register %i is not valid",r);
235 return reg_classes[r]&~(RC_INT|RC_FLOAT);228 return reg_classes[r]&~(RC_INT|RC_FLOAT);
236}229}
237 230
@@ -247,25 +240,25 @@ const char *default_elfinterp(struct TCCState *s) · 9 unmodified lines
247}240}
248#endif241#endif
249 242
250void o(uint32_t i)243void o(TCCState* S, uint32_t i)
251{244{
252 /* this is a good place to start adding big-endian support*/245 /* this is a good place to start adding big-endian support*/
253 int ind1;246 int ind1;
254 if (nocode_wanted)247 if (S->tccgen_nocode_wanted)
255 return;248 return;
256 ind1 = ind + 4;249 ind1 = S->tccgen_ind + 4;
257 if (!cur_text_section)250 if (!cur_text_section)
258 tcc_error("compiler error! This happens f.ex. if the compiler\n"251 tcc_error(S, "compiler error! This happens f.ex. if the compiler\n"
259 "can't evaluate constant expressions outside of a function.");252 "can't evaluate constant expressions outside of a function.");
260 if (ind1 > cur_text_section->data_allocated)253 if (ind1 > cur_text_section->data_allocated)
261 section_realloc(cur_text_section, ind1);254 section_realloc(S, cur_text_section, ind1);
262 cur_text_section->data[ind++] = i&255;255 cur_text_section->data[S->tccgen_ind++] = i&255;
263 i>>=8;256 i>>=8;
264 cur_text_section->data[ind++] = i&255;257 cur_text_section->data[S->tccgen_ind++] = i&255;
265 i>>=8;258 i>>=8;
266 cur_text_section->data[ind++] = i&255;259 cur_text_section->data[S->tccgen_ind++] = i&255;
267 i>>=8;260 i>>=8;
268 cur_text_section->data[ind++] = i;261 cur_text_section->data[S->tccgen_ind++] = i;
269}262}
270 263
271static uint32_t stuff_const(uint32_t op, uint32_t c)264static uint32_t stuff_const(uint32_t op, uint32_t c)
@@ -322,11 +315,11 @@ static uint32_t stuff_const(uint32_t op, uint32_t c) · 50 unmodified lines
322 315
323 316
324//only add,sub317//only add,sub
325void stuff_const_harder(uint32_t op, uint32_t v) {318void stuff_const_harder(TCCState* S, uint32_t op, uint32_t v) {
326 uint32_t x;319 uint32_t x;
327 x=stuff_const(op,v);320 x=stuff_const(op,v);
328 if(x)321 if(x)
329 o(x);322 o(S, x);
330 else {323 else {
331 uint32_t a[16], nv, no, o2, n2;324 uint32_t a[16], nv, no, o2, n2;
332 int i,j,k;325 int i,j,k;
@@ -337,8 +330,8 @@ void stuff_const_harder(uint32_t op, uint32_t v) { · 4 unmodified lines
337 for(i=0;i<12;i++)330 for(i=0;i<12;i++)
338 for(j=i<4?i+12:15;j>=i+4;j--)331 for(j=i<4?i+12:15;j>=i+4;j--)
339 if((v&(a[i]|a[j]))==v) {332 if((v&(a[i]|a[j]))==v) {
340 o(stuff_const(op,v&a[i]));333 o(S, stuff_const(op,v&a[i]));
341 o(stuff_const(o2,v&a[j]));334 o(S, stuff_const(o2,v&a[j]));
342 return;335 return;
343 }336 }
344 no=op^0xC00000;337 no=op^0xC00000;
@@ -347,17 +340,17 @@ void stuff_const_harder(uint32_t op, uint32_t v) { · 2 unmodified lines
347 for(i=0;i<12;i++)340 for(i=0;i<12;i++)
348 for(j=i<4?i+12:15;j>=i+4;j--)341 for(j=i<4?i+12:15;j>=i+4;j--)
349 if((nv&(a[i]|a[j]))==nv) {342 if((nv&(a[i]|a[j]))==nv) {
350 o(stuff_const(no,nv&a[i]));343 o(S, stuff_const(no,nv&a[i]));
351 o(stuff_const(n2,nv&a[j]));344 o(S, stuff_const(n2,nv&a[j]));
352 return;345 return;
353 }346 }
354 for(i=0;i<8;i++)347 for(i=0;i<8;i++)
355 for(j=i+4;j<12;j++)348 for(j=i+4;j<12;j++)
356 for(k=i<4?i+12:15;k>=j+4;k--)349 for(k=i<4?i+12:15;k>=j+4;k--)
357 if((v&(a[i]|a[j]|a[k]))==v) {350 if((v&(a[i]|a[j]|a[k]))==v) {
358 o(stuff_const(op,v&a[i]));351 o(S, stuff_const(op,v&a[i]));
359 o(stuff_const(o2,v&a[j]));352 o(S, stuff_const(o2,v&a[j]));
360 o(stuff_const(o2,v&a[k]));353 o(S, stuff_const(o2,v&a[k]));
361 return;354 return;
362 }355 }
363 no=op^0xC00000;356 no=op^0xC00000;
@@ -366,31 +359,31 @@ void stuff_const_harder(uint32_t op, uint32_t v) { · 2 unmodified lines
366 for(j=i+4;j<12;j++)359 for(j=i+4;j<12;j++)
367 for(k=i<4?i+12:15;k>=j+4;k--)360 for(k=i<4?i+12:15;k>=j+4;k--)
368 if((nv&(a[i]|a[j]|a[k]))==nv) {361 if((nv&(a[i]|a[j]|a[k]))==nv) {
369 o(stuff_const(no,nv&a[i]));362 o(S, stuff_const(no,nv&a[i]));
370 o(stuff_const(n2,nv&a[j]));363 o(S, stuff_const(n2,nv&a[j]));
371 o(stuff_const(n2,nv&a[k]));364 o(S, stuff_const(n2,nv&a[k]));
372 return;365 return;
373 }366 }
374 o(stuff_const(op,v&a[0]));367 o(S, stuff_const(op,v&a[0]));
375 o(stuff_const(o2,v&a[4]));368 o(S, stuff_const(o2,v&a[4]));
376 o(stuff_const(o2,v&a[8]));369 o(S, stuff_const(o2,v&a[8]));
377 o(stuff_const(o2,v&a[12]));370 o(S, stuff_const(o2,v&a[12]));
378 }371 }
379}372}
380 373
381uint32_t encbranch(int pos, int addr, int fail)374uint32_t encbranch(TCCState* S, int pos, int addr, int fail)
382{375{
383 addr-=pos+8;376 addr-=pos+8;
384 addr/=4;377 addr/=4;
385 if(addr>=0x1000000 || addr<-0x1000000) {378 if(addr>=0x1000000 || addr<-0x1000000) {
386 if(fail)379 if(fail)
387 tcc_error("FIXME: function bigger than 32MB");380 tcc_error(S, "FIXME: function bigger than 32MB");
388 return 0;381 return 0;
389 }382 }
390 return 0x0A000000|(addr&0xffffff);383 return 0x0A000000|(addr&0xffffff);
391}384}
392 385
393int decbranch(int pos)386int decbranch(TCCState* S, int pos)
394{387{
395 int x;388 int x;
396 x=*(uint32_t *)(cur_text_section->data + pos);389 x=*(uint32_t *)(cur_text_section->data + pos);
@@ -401,50 +394,50 @@ int decbranch(int pos) · 4 unmodified lines
401}394}
402 395
403/* output a symbol and patch all calls to it */396/* output a symbol and patch all calls to it */
404void gsym_addr(int t, int a)397void gsym_addr(TCCState* S, int t, int a)
405{398{
406 uint32_t *x;399 uint32_t *x;
407 int lt;400 int lt;
408 while(t) {401 while(t) {
409 x=(uint32_t *)(cur_text_section->data + t);402 x=(uint32_t *)(cur_text_section->data + t);
410 t=decbranch(lt=t);403 t=decbranch(S, lt=t);
411 if(a==lt+4)404 if(a==lt+4)
412 *x=0xE1A00000; // nop405 *x=0xE1A00000; // nop
413 else {406 else {
414 *x &= 0xff000000;407 *x &= 0xff000000;
415 *x |= encbranch(lt,a,1);408 *x |= encbranch(S, lt,a,1);
416 }409 }
417 }410 }
418}411}
419 412
420#ifdef TCC_ARM_VFP413#ifdef TCC_ARM_VFP
421static uint32_t vfpr(int r)414static uint32_t vfpr(TCCState* S, int r)
422{415{
423 if(r<TREG_F0 || r>TREG_F7)416 if(r<TREG_F0 || r>TREG_F7)
424 tcc_error("compiler error! register %i is no vfp register",r);417 tcc_error(S, "compiler error! register %i is no vfp register",r);
425 return r - TREG_F0;418 return r - TREG_F0;
426}419}
427#else420#else
428static uint32_t fpr(int r)421static uint32_t fpr(TCCState* S, int r)
429{422{
430 if(r<TREG_F0 || r>TREG_F3)423 if(r<TREG_F0 || r>TREG_F3)
431 tcc_error("compiler error! register %i is no fpa register",r);424 tcc_error(S, "compiler error! register %i is no fpa register",r);
432 return r - TREG_F0;425 return r - TREG_F0;
433}426}
434#endif427#endif
435 428
436static uint32_t intr(int r)429static uint32_t intr(TCCState* S, int r)
437{430{
438 if(r == TREG_R12)431 if(r == TREG_R12)
439 return 12;432 return 12;
440 if(r >= TREG_R0 && r <= TREG_R3)433 if(r >= TREG_R0 && r <= TREG_R3)
441 return r - TREG_R0;434 return r - TREG_R0;
442 if (!(r >= TREG_SP && r <= TREG_LR))435 if (!(r >= TREG_SP && r <= TREG_LR))
443 tcc_error("compiler error! register %i is no int register",r);436 tcc_error(S, "compiler error! register %i is no int register",r);
444 return r + (13 - TREG_SP);437 return r + (13 - TREG_SP);
445}438}
446 439
447static void calcaddr(uint32_t *base, int *off, int *sgn, int maxoff, unsigned shift)440static void calcaddr(TCCState* S, uint32_t *base, int *off, int *sgn, int maxoff, unsigned shift)
448{441{
449 if(*off>maxoff || *off&((1<<shift)-1)) {442 if(*off>maxoff || *off&((1<<shift)-1)) {
450 uint32_t x, y;443 uint32_t x, y;
@@ -455,23 +448,23 @@ static void calcaddr(uint32_t *base, int *off, int *sgn, int maxoff, unsigned sh · 4 unmodified lines
455 *base=14; // lr448 *base=14; // lr
456 y=stuff_const(x,*off&~maxoff);449 y=stuff_const(x,*off&~maxoff);
457 if(y) {450 if(y) {
458 o(y);451 o(S, y);
459 *off&=maxoff;452 *off&=maxoff;
460 return;453 return;
461 }454 }
462 y=stuff_const(x,(*off+maxoff)&~maxoff);455 y=stuff_const(x,(*off+maxoff)&~maxoff);
463 if(y) {456 if(y) {
464 o(y);457 o(S, y);
465 *sgn=!*sgn;458 *sgn=!*sgn;
466 *off=((*off+maxoff)&~maxoff)-*off;459 *off=((*off+maxoff)&~maxoff)-*off;
467 return;460 return;
468 }461 }
469 stuff_const_harder(x,*off&~maxoff);462 stuff_const_harder(S, x,*off&~maxoff);
470 *off&=maxoff;463 *off&=maxoff;
471 }464 }
472}465}
473 466
474static uint32_t mapcc(int cc)467static uint32_t mapcc(TCCState* S, int cc)
475{468{
476 switch(cc)469 switch(cc)
477 {470 {
@@ -500,11 +493,11 @@ static uint32_t mapcc(int cc) · 22 unmodified lines
500 case TOK_GT:493 case TOK_GT:
501 return 0xC0000000; /* GT */494 return 0xC0000000; /* GT */
502 }495 }
503 tcc_error("unexpected condition code");496 tcc_error(S, "unexpected condition code");
504 return 0xE0000000; /* AL */497 return 0xE0000000; /* AL */
505}498}
506 499
507static int negcc(int cc)500static int negcc(TCCState* S, int cc)
508{501{
509 switch(cc)502 switch(cc)
510 {503 {
@@ -533,44 +526,44 @@ static int negcc(int cc) · 22 unmodified lines
533 case TOK_GT:526 case TOK_GT:
534 return TOK_LE;527 return TOK_LE;
535 }528 }
536 tcc_error("unexpected condition code");529 tcc_error(S, "unexpected condition code");
537 return TOK_NE;530 return TOK_NE;
538}531}
539 532
540/* Load value into register r.533/* Load value into register r.
541 Use relative/got addressing to avoid setting DT_TEXTREL */534 Use relative/got addressing to avoid setting DT_TEXTREL */
542static void load_value(SValue *sv, int r)535static void load_value(TCCState* S, SValue *sv, int r)
543{536{
544 o(0xE59F0000|(intr(r)<<12)); /* ldr r, [pc] */537 o(S, 0xE59F0000|(intr(S, r)<<12)); /* ldr r, [pc] */
545 o(0xEA000000); /* b $+4 */538 o(S, 0xEA000000); /* b $+4 */
546#ifndef CONFIG_TCC_PIE539#ifndef CONFIG_TCC_PIE
547 if(sv->r & VT_SYM)540 if(sv->r & VT_SYM)
548 greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32);541 greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_ARM_ABS32);
549 o(sv->c.i);542 o(S, sv->c.i);
550#else543#else
551 if(sv->r & VT_SYM) {544 if(sv->r & VT_SYM) {
552 if (sv->sym->type.t & VT_STATIC) {545 if (sv->sym->type.t & VT_STATIC) {
553 greloc(cur_text_section, sv->sym, ind, R_ARM_REL32);546 greloc(cur_text_section, sv->sym, ind, R_ARM_REL32);
554 o(sv->c.i - 12);547 o(S, sv->c.i - 12);
555 o(0xe080000f | (intr(r)<<12) | (intr(r)<<16)); // add rx,rx,pc548 o(S, 0xe080000f | (intr(S, r)<<12) | (intr(S, r)<<16)); // add rx,rx,pc
556 }549 }
557 else {550 else {
558 greloc(cur_text_section, sv->sym, ind, R_ARM_GOT_PREL);551 greloc(cur_text_section, sv->sym, ind, R_ARM_GOT_PREL);
559 o(-12);552 o(S, -12);
560 o(0xe080000f | (intr(r)<<12) | (intr(r)<<16)); // add rx,rx,pc553 o(S, 0xe080000f | (intr(S, r)<<12) | (intr(S, r)<<16)); // add rx,rx,pc
561 o(0xe5900000 | (intr(r)<<12) | (intr(r)<<16)); // ldr rx,[rx]554 o(S, 0xe5900000 | (intr(S, r)<<12) | (intr(S, r)<<16)); // ldr rx,[rx]
562 if (sv->c.i)555 if (sv->c.i)
563 stuff_const_harder(0xe2800000 | (intr(r)<<12) | (intr(r)<<16),556 stuff_const_harder(S, 0xe2800000 | (intr(S, r)<<12) | (intr(S, r)<<16),
564 sv->c.i);557 sv->c.i);
565 }558 }
566 }559 }
567 else560 else
568 o(sv->c.i);561 o(S, sv->c.i);
569#endif562#endif
570}563}
571 564
572/* load 'r' from value 'sv' */565/* load 'r' from value 'sv' */
573void load(int r, SValue *sv)566void load(TCCState* S, int r, SValue *sv)
574{567{
575 int v, ft, fc, fr, sign;568 int v, ft, fc, fr, sign;
576 uint32_t op;569 uint32_t op;
@@ -594,7 +587,7 @@ void load(int r, SValue *sv) · 17 unmodified lines
594 v1.type.t = VT_PTR;587 v1.type.t = VT_PTR;
595 v1.r = VT_LOCAL | VT_LVAL;588 v1.r = VT_LOCAL | VT_LVAL;
596 v1.c.i = sv->c.i;589 v1.c.i = sv->c.i;
597 load(TREG_LR, &v1);590 load(S, TREG_LR, &v1);
598 base = 14; /* lr */591 base = 14; /* lr */
599 fc=sign=0;592 fc=sign=0;
600 v=VT_LOCAL;593 v=VT_LOCAL;
@@ -603,25 +596,25 @@ void load(int r, SValue *sv) · 2 unmodified lines
603 v1.r = fr&~VT_LVAL;596 v1.r = fr&~VT_LVAL;
604 v1.c.i = sv->c.i;597 v1.c.i = sv->c.i;
605 v1.sym=sv->sym;598 v1.sym=sv->sym;
606 load(TREG_LR, &v1);599 load(S, TREG_LR, &v1);
607 base = 14; /* lr */600 base = 14; /* lr */
608 fc=sign=0;601 fc=sign=0;
609 v=VT_LOCAL;602 v=VT_LOCAL;
610 } else if(v < VT_CONST) {603 } else if(v < VT_CONST) {
611 base=intr(v);604 base=intr(S, v);
612 fc=sign=0;605 fc=sign=0;
613 v=VT_LOCAL;606 v=VT_LOCAL;
614 }607 }
615 if(v == VT_LOCAL) {608 if(v == VT_LOCAL) {
616 if(is_float(ft)) {609 if(is_float(ft)) {
617 calcaddr(&base,&fc,&sign,1020,2);610 calcaddr(S, &base,&fc,&sign,1020,2);
618#ifdef TCC_ARM_VFP611#ifdef TCC_ARM_VFP
619 op=0xED100A00; /* flds */612 op=0xED100A00; /* flds */
620 if(!sign)613 if(!sign)
621 op|=0x800000;614 op|=0x800000;
622 if ((ft & VT_BTYPE) != VT_FLOAT)615 if ((ft & VT_BTYPE) != VT_FLOAT)
623 op|=0x100; /* flds -> fldd */616 op|=0x100; /* flds -> fldd */
624 o(op|(vfpr(r)<<12)|(fc>>2)|(base<<16));617 o(S, op|(vfpr(S, r)<<12)|(fc>>2)|(base<<16));
625#else618#else
626 op=0xED100100;619 op=0xED100100;
627 if(!sign)620 if(!sign)
@@ -635,11 +628,11 @@ void load(int r, SValue *sv) · 7 unmodified lines
635 else if ((ft & VT_BTYPE) == VT_LDOUBLE)628 else if ((ft & VT_BTYPE) == VT_LDOUBLE)
636 op|=0x400000;629 op|=0x400000;
637#endif630#endif
638 o(op|(fpr(r)<<12)|(fc>>2)|(base<<16));631 o(S, op|(fpr(S, r)<<12)|(fc>>2)|(base<<16));
639#endif632#endif
640 } else if((ft & (VT_BTYPE|VT_UNSIGNED)) == VT_BYTE633 } else if((ft & (VT_BTYPE|VT_UNSIGNED)) == VT_BYTE
641 || (ft & VT_BTYPE) == VT_SHORT) {634 || (ft & VT_BTYPE) == VT_SHORT) {
642 calcaddr(&base,&fc,&sign,255,0);635 calcaddr(S, &base,&fc,&sign,255,0);
643 op=0xE1500090;636 op=0xE1500090;
644 if ((ft & VT_BTYPE) == VT_SHORT)637 if ((ft & VT_BTYPE) == VT_SHORT)
645 op|=0x20;638 op|=0x20;
@@ -647,63 +640,63 @@ void load(int r, SValue *sv) · 1 unmodified line
647 op|=0x40;640 op|=0x40;
648 if(!sign)641 if(!sign)
649 op|=0x800000;642 op|=0x800000;
650 o(op|(intr(r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf));643 o(S, op|(intr(S, r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf));
651 } else {644 } else {
652 calcaddr(&base,&fc,&sign,4095,0);645 calcaddr(S, &base,&fc,&sign,4095,0);
653 op=0xE5100000;646 op=0xE5100000;
654 if(!sign)647 if(!sign)
655 op|=0x800000;648 op|=0x800000;
656 if ((ft & VT_BTYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_BOOL)649 if ((ft & VT_BTYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_BOOL)
657 op|=0x400000;650 op|=0x400000;
658 o(op|(intr(r)<<12)|fc|(base<<16));651 o(S, op|(intr(S, r)<<12)|fc|(base<<16));
659 }652 }
660 return;653 return;
661 }654 }
662 } else {655 } else {
663 if (v == VT_CONST) {656 if (v == VT_CONST) {
664 op=stuff_const(0xE3A00000|(intr(r)<<12),sv->c.i);657 op=stuff_const(0xE3A00000|(intr(S, r)<<12),sv->c.i);
665 if (fr & VT_SYM || !op)658 if (fr & VT_SYM || !op)
666 load_value(sv, r);659 load_value(S, sv, r);
667 else660 else
668 o(op);661 o(S, op);
669 return;662 return;
670 } else if (v == VT_LOCAL) {663 } else if (v == VT_LOCAL) {
671 op=stuff_const(0xE28B0000|(intr(r)<<12),sv->c.i);664 op=stuff_const(0xE28B0000|(intr(S, r)<<12),sv->c.i);
672 if (fr & VT_SYM || !op) {665 if (fr & VT_SYM || !op) {
673 load_value(sv, r);666 load_value(S, sv, r);
674 o(0xE08B0000|(intr(r)<<12)|intr(r));667 o(S, 0xE08B0000|(intr(S, r)<<12)|intr(S, r));
675 } else668 } else
676 o(op);669 o(S, op);
677 return;670 return;
678 } else if(v == VT_CMP) {671 } else if(v == VT_CMP) {
679 o(mapcc(sv->c.i)|0x3A00001|(intr(r)<<12));672 o(S, mapcc(S, sv->c.i)|0x3A00001|(intr(S, r)<<12));
680 o(mapcc(negcc(sv->c.i))|0x3A00000|(intr(r)<<12));673 o(S, mapcc(S, negcc(S, sv->c.i))|0x3A00000|(intr(S, r)<<12));
681 return;674 return;
682 } else if (v == VT_JMP || v == VT_JMPI) {675 } else if (v == VT_JMP || v == VT_JMPI) {
683 int t;676 int t;
684 t = v & 1;677 t = v & 1;
685 o(0xE3A00000|(intr(r)<<12)|t);678 o(S, 0xE3A00000|(intr(S, r)<<12)|t);
686 o(0xEA000000);679 o(S, 0xEA000000);
687 gsym(sv->c.i);680 gsym(S, sv->c.i);
688 o(0xE3A00000|(intr(r)<<12)|(t^1));681 o(S, 0xE3A00000|(intr(S, r)<<12)|(t^1));
689 return;682 return;
690 } else if (v < VT_CONST) {683 } else if (v < VT_CONST) {
691 if(is_float(ft))684 if(is_float(ft))
692#ifdef TCC_ARM_VFP685#ifdef TCC_ARM_VFP
693 o(0xEEB00A40|(vfpr(r)<<12)|vfpr(v)|T2CPR(ft)); /* fcpyX */686 o(S, 0xEEB00A40|(vfpr(S, r)<<12)|vfpr(S, v)|T2CPR(ft)); /* fcpyX */
694#else687#else
695 o(0xEE008180|(fpr(r)<<12)|fpr(v));688 o(S, 0xEE008180|(fpr(S, r)<<12)|fpr(S, v));
696#endif689#endif
697 else690 else
698 o(0xE1A00000|(intr(r)<<12)|intr(v));691 o(S, 0xE1A00000|(intr(S, r)<<12)|intr(S, v));
699 return;692 return;
700 }693 }
701 }694 }
702 tcc_error("load unimplemented!");695 tcc_error(S, "load unimplemented!");
703}696}
704 697
705/* store register 'r' in lvalue 'v' */698/* store register 'r' in lvalue 'v' */
706void store(int r, SValue *sv)699void store(TCCState* S, int r, SValue *sv)
707{700{
708 SValue v1;701 SValue v1;
709 int v, ft, fc, fr, sign;702 int v, ft, fc, fr, sign;
@@ -724,7 +717,7 @@ void store(int r, SValue *sv) · 14 unmodified lines
724 if (fr & VT_LVAL || fr == VT_LOCAL) {717 if (fr & VT_LVAL || fr == VT_LOCAL) {
725 uint32_t base = 0xb; /* fp */718 uint32_t base = 0xb; /* fp */
726 if(v < VT_CONST) {719 if(v < VT_CONST) {
727 base=intr(v);720 base=intr(S, v);
728 v=VT_LOCAL;721 v=VT_LOCAL;
729 fc=sign=0;722 fc=sign=0;
730 } else if(v == VT_CONST) {723 } else if(v == VT_CONST) {
@@ -732,21 +725,21 @@ void store(int r, SValue *sv) · 1 unmodified line
732 v1.r = fr&~VT_LVAL;725 v1.r = fr&~VT_LVAL;
733 v1.c.i = sv->c.i;726 v1.c.i = sv->c.i;
734 v1.sym=sv->sym;727 v1.sym=sv->sym;
735 load(TREG_LR, &v1);728 load(S, TREG_LR, &v1);
736 base = 14; /* lr */729 base = 14; /* lr */
737 fc=sign=0;730 fc=sign=0;
738 v=VT_LOCAL;731 v=VT_LOCAL;
739 }732 }
740 if(v == VT_LOCAL) {733 if(v == VT_LOCAL) {
741 if(is_float(ft)) {734 if(is_float(ft)) {
742 calcaddr(&base,&fc,&sign,1020,2);735 calcaddr(S, &base,&fc,&sign,1020,2);
743#ifdef TCC_ARM_VFP736#ifdef TCC_ARM_VFP
744 op=0xED000A00; /* fsts */737 op=0xED000A00; /* fsts */
745 if(!sign)738 if(!sign)
746 op|=0x800000;739 op|=0x800000;
747 if ((ft & VT_BTYPE) != VT_FLOAT)740 if ((ft & VT_BTYPE) != VT_FLOAT)
748 op|=0x100; /* fsts -> fstd */741 op|=0x100; /* fsts -> fstd */
749 o(op|(vfpr(r)<<12)|(fc>>2)|(base<<16));742 o(S, op|(vfpr(S, r)<<12)|(fc>>2)|(base<<16));
750#else743#else
751 op=0xED000100;744 op=0xED000100;
752 if(!sign)745 if(!sign)
@@ -760,138 +753,138 @@ void store(int r, SValue *sv) · 7 unmodified lines
760 if ((ft & VT_BTYPE) == VT_LDOUBLE)753 if ((ft & VT_BTYPE) == VT_LDOUBLE)
761 op|=0x400000;754 op|=0x400000;
762#endif755#endif
763 o(op|(fpr(r)<<12)|(fc>>2)|(base<<16));756 o(S, op|(fpr(S, r)<<12)|(fc>>2)|(base<<16));
764#endif757#endif
765 return;758 return;
766 } else if((ft & VT_BTYPE) == VT_SHORT) {759 } else if((ft & VT_BTYPE) == VT_SHORT) {
767 calcaddr(&base,&fc,&sign,255,0);760 calcaddr(S, &base,&fc,&sign,255,0);
768 op=0xE14000B0;761 op=0xE14000B0;
769 if(!sign)762 if(!sign)
770 op|=0x800000;763 op|=0x800000;
771 o(op|(intr(r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf));764 o(S, op|(intr(S, r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf));
772 } else {765 } else {
773 calcaddr(&base,&fc,&sign,4095,0);766 calcaddr(S, &base,&fc,&sign,4095,0);
774 op=0xE5000000;767 op=0xE5000000;
775 if(!sign)768 if(!sign)
776 op|=0x800000;769 op|=0x800000;
777 if ((ft & VT_BTYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_BOOL)770 if ((ft & VT_BTYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_BOOL)
778 op|=0x400000;771 op|=0x400000;
779 o(op|(intr(r)<<12)|fc|(base<<16));772 o(S, op|(intr(S, r)<<12)|fc|(base<<16));
780 }773 }
781 return;774 return;
782 }775 }
783 }776 }
784 tcc_error("store unimplemented");777 tcc_error(S, "store unimplemented");
785}778}
786 779
787static void gadd_sp(int val)780static void gadd_sp(TCCState* S, int val)
788{781{
789 stuff_const_harder(0xE28DD000,val);782 stuff_const_harder(S, 0xE28DD000,val);
790}783}
791 784
792/* 'is_jmp' is '1' if it is a jump */785/* 'is_jmp' is '1' if it is a jump */
793static void gcall_or_jmp(int is_jmp)786static void gcall_or_jmp(TCCState* S, int is_jmp)
794{787{
795 int r;788 int r;
796 uint32_t x;789 uint32_t x;
797 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {790 if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
798 /* constant case */791 /* constant case */
799 if(vtop->r & VT_SYM){792 if(S->tccgen_vtop->r & VT_SYM){
800 x=encbranch(ind,ind+vtop->c.i,0);793 x=encbranch(S, S->tccgen_ind, S->tccgen_ind+S->tccgen_vtop->c.i,0);
801 if(x) {794 if(x) {
802 /* relocation case */795 /* relocation case */
803 greloc(cur_text_section, vtop->sym, ind, R_ARM_PC24);796 greloc(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind, R_ARM_PC24);
804 o(x|(is_jmp?0xE0000000:0xE1000000));797 o(S, x|(is_jmp?0xE0000000:0xE1000000));
805 } else {798 } else {
806 r = TREG_LR;799 r = TREG_LR;
807 load_value(vtop, r);800 load_value(S, S->tccgen_vtop, r);
808 if(is_jmp)801 if(is_jmp)
809 o(0xE1A0F000 | intr(r)); // mov pc, r802 o(S, 0xE1A0F000 | intr(S, r)); // mov pc, r
810 else803 else
811 o(0xe12fff30 | intr(r)); // blx r804 o(S, 0xe12fff30 | intr(S, r)); // blx r
812 }805 }
813 }else{806 }else{
814 if(!is_jmp)807 if(!is_jmp)
815 o(0xE28FE004); // add lr,pc,#4808 o(S, 0xE28FE004); // add lr,pc,#4
816 o(0xE51FF004); // ldr pc,[pc,#-4]809 o(S, 0xE51FF004); // ldr pc,[pc,#-4]
817 o(vtop->c.i);810 o(S, S->tccgen_vtop->c.i);
818 }811 }
819 } else {812 } else {
820 /* otherwise, indirect call */813 /* otherwise, indirect call */
821#ifdef CONFIG_TCC_BCHECK814#ifdef CONFIG_TCC_BCHECK
822 vtop->r &= ~VT_MUSTBOUND;815 S->tccgen_vtop->r &= ~VT_MUSTBOUND;
823#endif816#endif
824 r = gv(RC_INT);817 r = gv(S, RC_INT);
825 if(!is_jmp)818 if(!is_jmp)
826 o(0xE1A0E00F); // mov lr,pc819 o(S, 0xE1A0E00F); // mov lr,pc
827 o(0xE1A0F000|intr(r)); // mov pc,r820 o(S, 0xE1A0F000|intr(S, r)); // mov pc,r
828 }821 }
829}822}
830 823
831#if defined(CONFIG_TCC_BCHECK)824#if defined(CONFIG_TCC_BCHECK)
832 825
833static void gen_bounds_call(int v)826static void gen_bounds_call(TCCState* S, int v)
834{827{
835 Sym *sym = external_helper_sym(v);828 Sym *sym = external_helper_sym(S, v);
836 829
837 greloc(cur_text_section, sym, ind, R_ARM_PC24);830 greloc(S, cur_text_section, sym, S->tccgen_ind, R_ARM_PC24);
838 o(0xebfffffe);831 o(S, 0xebfffffe);
839}832}
840 833
841static void gen_bounds_prolog(void)834static void gen_bounds_prolog(TCCState* S)
842{835{
843 /* leave some room for bound checking code */836 /* leave some room for bound checking code */
844 func_bound_offset = lbounds_section->data_offset;837 S->func_bound_offset = lbounds_section->data_offset;
845 func_bound_ind = ind;838 S->func_bound_ind = S->tccgen_ind;
846 func_bound_add_epilog = 0;839 S->func_bound_add_epilog = 0;
847 o(0xe1a00000); /* ld r0,lbounds_section->data_offset */840 o(S, 0xe1a00000); /* ld r0,lbounds_section->data_offset */
848 o(0xe1a00000);841 o(S, 0xe1a00000);
849 o(0xe1a00000);842 o(S, 0xe1a00000);
850 o(0xe1a00000);843 o(S, 0xe1a00000);
851 o(0xe1a00000); /* call __bound_local_new */844 o(S, 0xe1a00000); /* call __bound_local_new */
852}845}
853 846
854static void gen_bounds_epilog(void)847static void gen_bounds_epilog(TCCState* S)
855{848{
856 addr_t saved_ind;849 addr_t saved_ind;
857 addr_t *bounds_ptr;850 addr_t *bounds_ptr;
858 Sym *sym_data;851 Sym *sym_data;
859 int offset_modified = func_bound_offset != lbounds_section->data_offset;852 int offset_modified = S->func_bound_offset != lbounds_section->data_offset;
860 853
861 if (!offset_modified && !func_bound_add_epilog)854 if (!offset_modified && !S->func_bound_add_epilog)
862 return;855 return;
863 856
864 /* add end of table info */857 /* add end of table info */
865 bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));858 bounds_ptr = section_ptr_add(S, lbounds_section, sizeof(addr_t));
866 *bounds_ptr = 0;859 *bounds_ptr = 0;
867 860
868 sym_data = get_sym_ref(&char_pointer_type, lbounds_section,861 sym_data = get_sym_ref(S, &S->tccgen_char_pointer_type, lbounds_section,
869 func_bound_offset, lbounds_section->data_offset);862 S->func_bound_offset, lbounds_section->data_offset);
870 863
871 /* generate bound local allocation */864 /* generate bound local allocation */
872 if (offset_modified) {865 if (offset_modified) {
873 saved_ind = ind;866 saved_ind = S->tccgen_ind;
874 ind = func_bound_ind;867 S->tccgen_ind = S->func_bound_ind;
875 o(0xe59f0000); /* ldr r0, [pc] */868 o(S, 0xe59f0000); /* ldr r0, [pc] */
876 o(0xea000000); /* b $+4 */869 o(S, 0xea000000); /* b $+4 */
877 greloc(cur_text_section, sym_data, ind, R_ARM_REL32);870 greloc(S, cur_text_section, sym_data, S->tccgen_ind, R_ARM_REL32);
878 o(-12); /* lbounds_section->data_offset */871 o(S, -12); /* lbounds_section->data_offset */
879 o(0xe080000f); /* add r0,r0,pc */872 o(S, 0xe080000f); /* add r0,r0,pc */
880 gen_bounds_call(TOK___bound_local_new);873 gen_bounds_call(S, TOK___bound_local_new);
881 ind = saved_ind;874 S->tccgen_ind = saved_ind;
882 }875 }
883 876
884 /* generate bound check local freeing */877 /* generate bound check local freeing */
885 o(0xe92d0003); /* push {r0,r1} */878 o(S, 0xe92d0003); /* push {r0,r1} */
886 o(0xed2d0b02); /* vpush {d0} */879 o(S, 0xed2d0b02); /* vpush {d0} */
887 o(0xe59f0000); /* ldr r0, [pc] */880 o(S, 0xe59f0000); /* ldr r0, [pc] */
888 o(0xea000000); /* b $+4 */881 o(S, 0xea000000); /* b $+4 */
889 greloc(cur_text_section, sym_data, ind, R_ARM_REL32);882 greloc(S, cur_text_section, sym_data, S->tccgen_ind, R_ARM_REL32);
890 o(-12); /* lbounds_section->data_offset */883 o(S, -12); /* lbounds_section->data_offset */
891 o(0xe080000f); /* add r0,r0,pc */884 o(S, 0xe080000f); /* add r0,r0,pc */
892 gen_bounds_call(TOK___bound_local_delete);885 gen_bounds_call(S, TOK___bound_local_delete);
893 o(0xecbd0b02); /* vpop {d0} */886 o(S, 0xecbd0b02); /* vpop {d0} */
894 o(0xe8bd0003); /* pop {r0,r1} */887 o(S, 0xe8bd0003); /* pop {r0,r1} */
895}888}
896#endif889#endif
897 890
@@ -1077,7 +1070,7 @@ static void add_param_plan(struct plan* plan, int cls, int start, int end, SValu · 179 unmodified lines
1077 Note: this function allocated an array in plan->pplans with tcc_malloc. It1070 Note: this function allocated an array in plan->pplans with tcc_malloc. It
1078 is the responsibility of the caller to free this array once used (ie not1071 is the responsibility of the caller to free this array once used (ie not
1079 before copy_params). */1072 before copy_params). */
1080static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo)1073static int assign_regs(TCCState *S, int nb_args, int float_abi, struct plan *plan, int *todo)
1081{1074{
1082 int i, size, align;1075 int i, size, align;
1083 int ncrn /* next core register number */, nsaa /* next stacked argument address*/;1076 int ncrn /* next core register number */, nsaa /* next stacked argument address*/;
@@ -1088,12 +1081,12 @@ static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo) · 4 unmodified lines
1088 1081
1089 for(i = nb_args; i-- ;) {1082 for(i = nb_args; i-- ;) {
1090 int j, start_vfpreg = 0;1083 int j, start_vfpreg = 0;
1091 CType type = vtop[-i].type;1084 CType type = S->tccgen_vtop[-i].type;
1092 type.t &= ~VT_ARRAY;1085 type.t &= ~VT_ARRAY;
1093 size = type_size(&type, &align);1086 size = type_size(&type, &align);
1094 size = (size + 3) & ~3;1087 size = (size + 3) & ~3;
1095 align = (align + 3) & ~3;1088 align = (align + 3) & ~3;
1096 switch(vtop[-i].type.t & VT_BTYPE) {1089 switch(S->tccgen_vtop[-i].type.t & VT_BTYPE) {
1097 case VT_STRUCT:1090 case VT_STRUCT:
1098 case VT_FLOAT:1091 case VT_FLOAT:
1099 case VT_DOUBLE:1092 case VT_DOUBLE:
@@ -1101,15 +1094,15 @@ static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo) · 1 unmodified line
1101 if (float_abi == ARM_HARD_FLOAT) {1094 if (float_abi == ARM_HARD_FLOAT) {
1102 int is_hfa = 0; /* Homogeneous float aggregate */1095 int is_hfa = 0; /* Homogeneous float aggregate */
1103 1096
1104 if (is_float(vtop[-i].type.t)1097 if (is_float(S->tccgen_vtop[-i].type.t)
1105 || (is_hfa = is_hgen_float_aggr(&vtop[-i].type))) {1098 || (is_hfa = is_hgen_float_aggr(&S->tccgen_vtop[-i].type))) {
1106 int end_vfpreg;1099 int end_vfpreg;
1107 1100
1108 start_vfpreg = assign_vfpreg(&avregs, align, size);1101 start_vfpreg = assign_vfpreg(&avregs, align, size);
1109 end_vfpreg = start_vfpreg + ((size - 1) >> 2);1102 end_vfpreg = start_vfpreg + ((size - 1) >> 2);
1110 if (start_vfpreg >= 0) {1103 if (start_vfpreg >= 0) {
1111 add_param_plan(plan, is_hfa ? VFP_STRUCT_CLASS : VFP_CLASS,1104 add_param_plan(plan, is_hfa ? VFP_STRUCT_CLASS : VFP_CLASS,
1112 start_vfpreg, end_vfpreg, &vtop[-i]);1105 start_vfpreg, end_vfpreg, &S->tccgen_vtop[-i]);
1113 continue;1106 continue;
1114 } else1107 } else
1115 break;1108 break;
@@ -1122,7 +1115,7 @@ static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo) · 6 unmodified lines
1122 * CORE_STRUCT_CLASS or the first of STACK_CLASS. */1115 * CORE_STRUCT_CLASS or the first of STACK_CLASS. */
1123 for (j = ncrn; j < 4 && j < ncrn + size / 4; j++)1116 for (j = ncrn; j < 4 && j < ncrn + size / 4; j++)
1124 *todo|=(1<<j);1117 *todo|=(1<<j);
1125 add_param_plan(plan, CORE_STRUCT_CLASS, ncrn, j, &vtop[-i]);1118 add_param_plan(plan, CORE_STRUCT_CLASS, ncrn, j, &S->tccgen_vtop[-i]);
1126 ncrn += size/4;1119 ncrn += size/4;
1127 if (ncrn > 4)1120 if (ncrn > 4)
1128 nsaa = (ncrn - 4) * 4;1121 nsaa = (ncrn - 4) * 4;
@@ -1133,20 +1126,20 @@ static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo) · 4 unmodified lines
1133 continue;1126 continue;
1134 default:1127 default:
1135 if (ncrn < 4) {1128 if (ncrn < 4) {
1136 int is_long = (vtop[-i].type.t & VT_BTYPE) == VT_LLONG;1129 int is_long = (S->tccgen_vtop[-i].type.t & VT_BTYPE) == VT_LLONG;
1137 1130
1138 if (is_long) {1131 if (is_long) {
1139 ncrn = (ncrn + 1) & -2;1132 ncrn = (ncrn + 1) & -2;
1140 if (ncrn == 4)1133 if (ncrn == 4)
1141 break;1134 break;
1142 }1135 }
1143 add_param_plan(plan, CORE_CLASS, ncrn, ncrn + is_long, &vtop[-i]);1136 add_param_plan(plan, CORE_CLASS, ncrn, ncrn + is_long, &S->tccgen_vtop[-i]);
1144 ncrn += 1 + is_long;1137 ncrn += 1 + is_long;
1145 continue;1138 continue;
1146 }1139 }
1147 }1140 }
1148 nsaa = (nsaa + (align - 1)) & ~(align - 1);1141 nsaa = (nsaa + (align - 1)) & ~(align - 1);
1149 add_param_plan(plan, STACK_CLASS, nsaa, nsaa + size, &vtop[-i]);1142 add_param_plan(plan, STACK_CLASS, nsaa, nsaa + size, &S->tccgen_vtop[-i]);
1150 nsaa += size; /* size already rounded up before */1143 nsaa += size; /* size already rounded up before */
1151 }1144 }
1152 return nsaa;1145 return nsaa;
@@ -1160,7 +1153,7 @@ static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo) · 7 unmodified lines
1160 todo: a bitmap indicating what core reg will hold a parameter1153 todo: a bitmap indicating what core reg will hold a parameter
1161 1154
1162 Returns the number of SValue added by this function on the value stack */1155 Returns the number of SValue added by this function on the value stack */
1163static int copy_params(int nb_args, struct plan *plan, int todo)1156static int copy_params(TCCState* S, int nb_args, struct plan *plan, int todo)
1164{1157{
1165 int size, align, r, i, nb_extra_sval = 0;1158 int size, align, r, i, nb_extra_sval = 0;
1166 struct param_plan *pplan;1159 struct param_plan *pplan;
@@ -1189,7 +1182,7 @@ again: · 22 unmodified lines
1189 && (i != CORE_CLASS || pplan->sval->r < VT_CONST))1182 && (i != CORE_CLASS || pplan->sval->r < VT_CONST))
1190 continue;1183 continue;
1191 1184
1192 vpushv(pplan->sval);1185 vpushv(S, pplan->sval);
1193 pplan->sval->r = pplan->sval->r2 = VT_CONST; /* disable entry */1186 pplan->sval->r = pplan->sval->r2 = VT_CONST; /* disable entry */
1194 switch(i) {1187 switch(i) {
1195 case STACK_CLASS:1188 case STACK_CLASS:
@@ -1204,16 +1197,16 @@ again: · 8 unmodified lines
1204 padding = pplan->start - pplan->prev->end;1197 padding = pplan->start - pplan->prev->end;
1205 size += padding; /* Add padding if any */1198 size += padding; /* Add padding if any */
1206 /* allocate the necessary size on stack */1199 /* allocate the necessary size on stack */
1207 gadd_sp(-size);1200 gadd_sp(S, -size);
1208 /* generate structure store */1201 /* generate structure store */
1209 r = get_reg(RC_INT);1202 r = get_reg(S, RC_INT);
1210 o(0xE28D0000|(intr(r)<<12)|padding); /* add r, sp, padding */1203 o(S, 0xE28D0000|(intr(S, r)<<12)|padding); /* add r, sp, padding */
1211 vset(&vtop->type, r | VT_LVAL, 0);1204 vset(S, &S->tccgen_vtop->type, r | VT_LVAL, 0);
1212 vswap();1205 vswap(S);
1213 /* XXX: optimize. Save all register because memcpy can use them */1206 /* XXX: optimize. Save all register because memcpy can use them */
1214 o(0xED2D0A00|(0&1)<<22|(0>>1)<<12|16); /* vpush {s0-s15} */1207 o(S, 0xED2D0A00|(0&1)<<22|(0>>1)<<12|16); /* vpush {s0-s15} */
1215 vstore(); /* memcpy to current sp + potential padding */1208 vstore(S); /* memcpy to current sp + potential padding */
1216 o(0xECBD0A00|(0&1)<<22|(0>>1)<<12|16); /* vpop {s0-s15} */1209 o(S, 0xECBD0A00|(0&1)<<22|(0>>1)<<12|16); /* vpop {s0-s15} */
1217 1210
1218 /* Homogeneous float aggregate are loaded to VFP registers1211 /* Homogeneous float aggregate are loaded to VFP registers
1219 immediately since there is no way of loading data in multiple1212 immediately since there is no way of loading data in multiple
@@ -1222,23 +1215,23 @@ again: · 2 unmodified lines
1222 if (i == VFP_STRUCT_CLASS) {1215 if (i == VFP_STRUCT_CLASS) {
1223 int first = pplan->start, nb = pplan->end - first + 1;1216 int first = pplan->start, nb = pplan->end - first + 1;
1224 /* vpop.32 {pplan->start, ..., pplan->end} */1217 /* vpop.32 {pplan->start, ..., pplan->end} */
1225 o(0xECBD0A00|(first&1)<<22|(first>>1)<<12|nb);1218 o(S, 0xECBD0A00|(first&1)<<22|(first>>1)<<12|nb);
1226 /* No need to write the register used to a SValue since VFP regs1219 /* No need to write the register used to a SValue since VFP regs
1227 cannot be used for gcall_or_jmp */1220 cannot be used for gcall_or_jmp */
1228 }1221 }
1229 } else {1222 } else {
1230 if (is_float(pplan->sval->type.t)) {1223 if (is_float(pplan->sval->type.t)) {
1231#ifdef TCC_ARM_VFP1224#ifdef TCC_ARM_VFP
1232 r = vfpr(gv(RC_FLOAT)) << 12;1225 r = vfpr(S, gv(S, RC_FLOAT)) << 12;
1233 if ((pplan->sval->type.t & VT_BTYPE) == VT_FLOAT)1226 if ((pplan->sval->type.t & VT_BTYPE) == VT_FLOAT)
1234 size = 4;1227 size = 4;
1235 else {1228 else {
1236 size = 8;1229 size = 8;
1237 r |= 0x101; /* vpush.32 -> vpush.64 */1230 r |= 0x101; /* vpush.32 -> vpush.64 */
1238 }1231 }
1239 o(0xED2D0A01 + r); /* vpush */1232 o(S, 0xED2D0A01 + r); /* vpush */
1240#else1233#else
1241 r = fpr(gv(RC_FLOAT)) << 12;1234 r = fpr(S, gv(S, RC_FLOAT)) << 12;
1242 if ((pplan->sval->type.t & VT_BTYPE) == VT_FLOAT)1235 if ((pplan->sval->type.t & VT_BTYPE) == VT_FLOAT)
1243 size = 4;1236 size = 4;
1244 else if ((pplan->sval->type.t & VT_BTYPE) == VT_DOUBLE)1237 else if ((pplan->sval->type.t & VT_BTYPE) == VT_DOUBLE)
@@ -1251,49 +1244,49 @@ again: · 6 unmodified lines
1251 else if(size == 8)1244 else if(size == 8)
1252 r|=0x8000;1245 r|=0x8000;
1253 1246
1254 o(0xED2D0100|r|(size>>2)); /* some kind of vpush for FPA */1247 o(S, 0xED2D0100|r|(size>>2)); /* some kind of vpush for FPA */
1255#endif1248#endif
1256 } else {1249 } else {
1257 /* simple type (currently always same size) */1250 /* simple type (currently always same size) */
1258 /* XXX: implicit cast ? */1251 /* XXX: implicit cast ? */
1259 size=4;1252 size=4;
1260 if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) {1253 if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) {
1261 lexpand();1254 lexpand(S);
1262 size = 8;1255 size = 8;
1263 r = gv(RC_INT);1256 r = gv(S, RC_INT);
1264 o(0xE52D0004|(intr(r)<<12)); /* push r */1257 o(S, 0xE52D0004|(intr(S, r)<<12)); /* push r */
1265 vtop--;1258 S->tccgen_vtop--;
1266 }1259 }
1267 r = gv(RC_INT);1260 r = gv(S, RC_INT);
1268 o(0xE52D0004|(intr(r)<<12)); /* push r */1261 o(S, 0xE52D0004|(intr(S, r)<<12)); /* push r */
1269 }1262 }
1270 if (i == STACK_CLASS && pplan->prev)1263 if (i == STACK_CLASS && pplan->prev)
1271 gadd_sp(pplan->prev->end - pplan->start); /* Add padding if any */1264 gadd_sp(S, pplan->prev->end - pplan->start); /* Add padding if any */
1272 }1265 }
1273 break;1266 break;
1274 1267
1275 case VFP_CLASS:1268 case VFP_CLASS:
1276 gv(regmask(TREG_F0 + (pplan->start >> 1)));1269 gv(S, regmask(S, TREG_F0 + (pplan->start >> 1)));
1277 if (pplan->start & 1) { /* Must be in upper part of double register */1270 if (pplan->start & 1) { /* Must be in upper part of double register */
1278 o(0xEEF00A40|((pplan->start>>1)<<12)|(pplan->start>>1)); /* vmov.f32 s(n+1), sn */1271 o(S, 0xEEF00A40|((pplan->start>>1)<<12)|(pplan->start>>1)); /* vmov.f32 s(n+1), sn */
1279 vtop->r = VT_CONST; /* avoid being saved on stack by gv for next float */1272 S->tccgen_vtop->r = VT_CONST; /* avoid being saved on stack by gv for next float */
1280 }1273 }
1281 break;1274 break;
1282 1275
1283 case CORE_CLASS:1276 case CORE_CLASS:
1284 if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) {1277 if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) {
1285 lexpand();1278 lexpand(S);
1286 gv(regmask(pplan->end));1279 gv(S, regmask(S, pplan->end));
1287 pplan->sval->r2 = vtop->r;1280 pplan->sval->r2 = S->tccgen_vtop->r;
1288 vtop--;1281 S->tccgen_vtop--;
1289 }1282 }
1290 gv(regmask(pplan->start));1283 gv(S, regmask(S, pplan->start));
1291 /* Mark register as used so that gcall_or_jmp use another one1284 /* Mark register as used so that gcall_or_jmp use another one
1292 (regs >=4 are free as never used to pass parameters) */1285 (regs >=4 are free as never used to pass parameters) */
1293 pplan->sval->r = vtop->r;1286 pplan->sval->r = S->tccgen_vtop->r;
1294 break;1287 break;
1295 }1288 }
1296 vtop--;1289 S->tccgen_vtop--;
1297 }1290 }
1298 }1291 }
1299 1292
@@ -1304,10 +1297,10 @@ again: · 4 unmodified lines
1304 1297
1305 /* Manually free remaining registers since next parameters are loaded1298 /* Manually free remaining registers since next parameters are loaded
1306 * manually, without the help of gv(int). */1299 * manually, without the help of gv(int). */
1307 save_regs(nb_args);1300 save_regs(S, nb_args);
1308 1301
1309 if(todo) {1302 if(todo) {
1310 o(0xE8BD0000|todo); /* pop {todo} */1303 o(S, 0xE8BD0000|todo); /* pop {todo} */
1311 for(pplan = plan->clsplans[CORE_STRUCT_CLASS]; pplan; pplan = pplan->prev) {1304 for(pplan = plan->clsplans[CORE_STRUCT_CLASS]; pplan; pplan = pplan->prev) {
1312 int r;1305 int r;
1313 pplan->sval->r = pplan->start;1306 pplan->sval->r = pplan->start;
@@ -1318,8 +1311,8 @@ again: · 4 unmodified lines
1318 for (r = pplan->start + 1; r <= pplan->end; r++) {1311 for (r = pplan->start + 1; r <= pplan->end; r++) {
1319 if (todo & (1 << r)) {1312 if (todo & (1 << r)) {
1320 nb_extra_sval++;1313 nb_extra_sval++;
1321 vpushi(0);1314 vpushi(S, 0);
1322 vtop->r = r;1315 S->tccgen_vtop->r = r;
1323 }1316 }
1324 }1317 }
1325 }1318 }
@@ -1330,7 +1323,7 @@ again: · 4 unmodified lines
1330/* Generate function call. The function address is pushed first, then1323/* Generate function call. The function address is pushed first, then
1331 all the parameters in call order. This functions pops all the1324 all the parameters in call order. This functions pops all the
1332 parameters and the function address. */1325 parameters and the function address. */
1333void gfunc_call(int nb_args)1326void gfunc_call(TCCState* S, int nb_args)
1334{1327{
1335 int r, args_size;1328 int r, args_size;
1336 int def_float_abi = float_abi;1329 int def_float_abi = float_abi;
@@ -1341,62 +1334,62 @@ void gfunc_call(int nb_args) · 4 unmodified lines
1341#endif1334#endif
1342 1335
1343#ifdef CONFIG_TCC_BCHECK1336#ifdef CONFIG_TCC_BCHECK
1344 if (tcc_state->do_bounds_check)1337 if (S->do_bounds_check)
1345 gbound_args(nb_args);1338 gbound_args(S, nb_args);
1346#endif1339#endif
1347 1340
1348#ifdef TCC_ARM_EABI1341#ifdef TCC_ARM_EABI
1349 if (float_abi == ARM_HARD_FLOAT) {1342 if (float_abi == ARM_HARD_FLOAT) {
1350 variadic = (vtop[-nb_args].type.ref->f.func_type == FUNC_ELLIPSIS);1343 variadic = (S->tccgen_vtop[-nb_args].type.ref->f.func_type == FUNC_ELLIPSIS);
1351 if (variadic || floats_in_core_regs(&vtop[-nb_args]))1344 if (variadic || floats_in_core_regs(&S->tccgen_vtop[-nb_args]))
1352 float_abi = ARM_SOFTFP_FLOAT;1345 float_abi = ARM_SOFTFP_FLOAT;
1353 }1346 }
1354#endif1347#endif
1355 /* cannot let cpu flags if other instruction are generated. Also avoid leaving1348 /* cannot let cpu flags if other instruction are generated. Also avoid leaving
1356 VT_JMP anywhere except on the top of the stack because it would complicate1349 VT_JMP anywhere except on the top of the stack because it would complicate
1357 the code generator. */1350 the code generator. */
1358 r = vtop->r & VT_VALMASK;1351 r = S->tccgen_vtop->r & VT_VALMASK;
1359 if (r == VT_CMP || (r & ~1) == VT_JMP)1352 if (r == VT_CMP || (r & ~1) == VT_JMP)
1360 gv(RC_INT);1353 gv(S, RC_INT);
1361 1354
1362 memset(&plan, 0, sizeof plan);1355 memset(&plan, 0, sizeof plan);
1363 if (nb_args)1356 if (nb_args)
1364 plan.pplans = tcc_malloc(nb_args * sizeof(*plan.pplans));1357 plan.pplans = tcc_malloc(S, nb_args * sizeof(*plan.pplans));
1365 1358
1366 args_size = assign_regs(nb_args, float_abi, &plan, &todo);1359 args_size = assign_regs(S, nb_args, float_abi, &plan, &todo);
1367 1360
1368#ifdef TCC_ARM_EABI1361#ifdef TCC_ARM_EABI
1369 if (args_size & 7) { /* Stack must be 8 byte aligned at fct call for EABI */1362 if (args_size & 7) { /* Stack must be 8 byte aligned at fct call for EABI */
1370 args_size = (args_size + 7) & ~7;1363 args_size = (args_size + 7) & ~7;
1371 o(0xE24DD004); /* sub sp, sp, #4 */1364 o(S, 0xE24DD004); /* sub sp, sp, #4 */
1372 }1365 }
1373#endif1366#endif
1374 1367
1375 nb_args += copy_params(nb_args, &plan, todo);1368 nb_args += copy_params(S, nb_args, &plan, todo);
1376 tcc_free(plan.pplans);1369 tcc_free(S, plan.pplans);
1377 1370
1378 /* Move fct SValue on top as required by gcall_or_jmp */1371 /* Move fct SValue on top as required by gcall_or_jmp */
1379 vrotb(nb_args + 1);1372 vrotb(S, nb_args + 1);
1380 gcall_or_jmp(0);1373 gcall_or_jmp(S, 0);
1381 if (args_size)1374 if (args_size)
1382 gadd_sp(args_size); /* pop all parameters passed on the stack */1375 gadd_sp(S, args_size); /* pop all parameters passed on the stack */
1383#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)1376#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
1384 if(float_abi == ARM_SOFTFP_FLOAT && is_float(vtop->type.ref->type.t)) {1377 if(float_abi == ARM_SOFTFP_FLOAT && is_float(S->tccgen_vtop->type.ref->type.t)) {
1385 if((vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) {1378 if((S->tccgen_vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) {
1386 o(0xEE000A10); /*vmov s0, r0 */1379 o(S, 0xEE000A10); /*vmov s0, r0 */
1387 } else {1380 } else {
1388 o(0xEE000B10); /* vmov.32 d0[0], r0 */1381 o(S, 0xEE000B10); /* vmov.32 d0[0], r0 */
1389 o(0xEE201B10); /* vmov.32 d0[1], r1 */1382 o(S, 0xEE201B10); /* vmov.32 d0[1], r1 */
1390 }1383 }
1391 }1384 }
1392#endif1385#endif
1393 vtop -= nb_args + 1; /* Pop all params and fct address from value stack */1386 S->tccgen_vtop -= nb_args + 1; /* Pop all params and fct address from value stack */
1394 leaffunc = 0; /* we are calling a function, so we aren't in a leaf function */1387 leaffunc = 0; /* we are calling a function, so we aren't in a leaf function */
1395 float_abi = def_float_abi;1388 float_abi = def_float_abi;
1396}1389}
1397 1390
1398/* generate function prolog of type 't' */1391/* generate function prolog of type 't' */
1399void gfunc_prolog(Sym *func_sym)1392void gfunc_prolog(TCCState* S, Sym *func_sym)
1400{1393{
1401 CType *func_type = &func_sym->type;1394 CType *func_type = &func_sym->type;
1402 Sym *sym,*sym2;1395 Sym *sym,*sym2;
@@ -1411,17 +1404,17 @@ void gfunc_prolog(Sym *func_sym) · 8 unmodified lines
1411 sym = func_type->ref;1404 sym = func_type->ref;
1412 1405
1413 n = nf = 0;1406 n = nf = 0;
1414 if ((func_vt.t & VT_BTYPE) == VT_STRUCT &&1407 if ((S->tccgen_func_vt.t & VT_BTYPE) == VT_STRUCT &&
1415 !gfunc_sret(&func_vt, func_var, &ret_type, &align, &rs))1408 !gfunc_sret(&S->tccgen_func_vt, S->tccgen_func_var, &ret_type, &align, &rs))
1416 {1409 {
1417 n++;1410 n++;
1418 struct_ret = 1;1411 struct_ret = 1;
1419 func_vc = 12; /* Offset from fp of the place to store the result */1412 S->tccgen_func_vc = 12; /* Offset from fp of the place to store the result */
1420 }1413 }
1421 for(sym2 = sym->next; sym2 && (n < 4 || nf < 16); sym2 = sym2->next) {1414 for(sym2 = sym->next; sym2 && (n < 4 || nf < 16); sym2 = sym2->next) {
1422 size = type_size(&sym2->type, &align);1415 size = type_size(&sym2->type, &align);
1423#ifdef TCC_ARM_EABI1416#ifdef TCC_ARM_EABI
1424 if (float_abi == ARM_HARD_FLOAT && !func_var &&1417 if (float_abi == ARM_HARD_FLOAT && !S->tccgen_func_var &&
1425 (is_float(sym2->type.t) || is_hgen_float_aggr(&sym2->type))) {1418 (is_float(sym2->type.t) || is_hgen_float_aggr(&sym2->type))) {
1426 int tmpnf = assign_vfpreg(&avregs, align, size);1419 int tmpnf = assign_vfpreg(&avregs, align, size);
1427 tmpnf += (size + 3) / 4;1420 tmpnf += (size + 3) / 4;
@@ -1431,8 +1424,8 @@ void gfunc_prolog(Sym *func_sym) · 3 unmodified lines
1431 if (n < 4)1424 if (n < 4)
1432 n += (size + 3) / 4;1425 n += (size + 3) / 4;
1433 }1426 }
1434 o(0xE1A0C00D); /* mov ip,sp */1427 o(S, 0xE1A0C00D); /* mov ip,sp */
1435 if (func_var)1428 if (S->tccgen_func_var)
1436 n=4;1429 n=4;
1437 if (n) {1430 if (n) {
1438 if(n>4)1431 if(n>4)
@@ -1440,22 +1433,22 @@ void gfunc_prolog(Sym *func_sym) · 1 unmodified line
1440#ifdef TCC_ARM_EABI1433#ifdef TCC_ARM_EABI
1441 n=(n+1)&-2;1434 n=(n+1)&-2;
1442#endif1435#endif
1443 o(0xE92D0000|((1<<n)-1)); /* save r0-r4 on stack if needed */1436 o(S, 0xE92D0000|((1<<n)-1)); /* save r0-r4 on stack if needed */
1444 }1437 }
1445 if (nf) {1438 if (nf) {
1446 if (nf>16)1439 if (nf>16)
1447 nf=16;1440 nf=16;
1448 nf=(nf+1)&-2; /* nf => HARDFLOAT => EABI */1441 nf=(nf+1)&-2; /* nf => HARDFLOAT => EABI */
1449 o(0xED2D0A00|nf); /* save s0-s15 on stack if needed */1442 o(S, 0xED2D0A00|nf); /* save s0-s15 on stack if needed */
1450 }1443 }
1451 o(0xE92D5800); /* save fp, ip, lr */1444 o(S, 0xE92D5800); /* save fp, ip, lr */
1452 o(0xE1A0B00D); /* mov fp, sp */1445 o(S, 0xE1A0B00D); /* mov fp, sp */
1453 func_sub_sp_offset = ind;1446 func_sub_sp_offset = S->tccgen_ind;
1454 o(0xE1A00000); /* nop, leave space for stack adjustment in epilog */1447 o(S, 0xE1A00000); /* nop, leave space for stack adjustment in epilog */
1455 1448
1456#ifdef TCC_ARM_EABI1449#ifdef TCC_ARM_EABI
1457 if (float_abi == ARM_HARD_FLOAT) {1450 if (float_abi == ARM_HARD_FLOAT) {
1458 func_vc += nf * 4;1451 S->tccgen_func_vc += nf * 4;
1459 memset(&avregs, 0, sizeof avregs);1452 memset(&avregs, 0, sizeof avregs);
1460 }1453 }
1461#endif1454#endif
@@ -1467,7 +1460,7 @@ void gfunc_prolog(Sym *func_sym) · 5 unmodified lines
1467 size = (size + 3) >> 2;1460 size = (size + 3) >> 2;
1468 align = (align + 3) & ~3;1461 align = (align + 3) & ~3;
1469#ifdef TCC_ARM_EABI1462#ifdef TCC_ARM_EABI
1470 if (float_abi == ARM_HARD_FLOAT && !func_var && (is_float(sym->type.t)1463 if (float_abi == ARM_HARD_FLOAT && !S->tccgen_func_var && (is_float(sym->type.t)
1471 || is_hgen_float_aggr(&sym->type))) {1464 || is_hgen_float_aggr(&sym->type))) {
1472 int fpn = assign_vfpreg(&avregs, align, size << 2);1465 int fpn = assign_vfpreg(&avregs, align, size << 2);
1473 if (fpn >= 0)1466 if (fpn >= 0)
@@ -1492,42 +1485,42 @@ from_stack: · 18 unmodified lines
1492 addr = (n + nf + sn) * 4;1485 addr = (n + nf + sn) * 4;
1493 sn += size;1486 sn += size;
1494 }1487 }
1495 sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL,1488 sym_push(S, sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL,
1496 addr + 12);1489 addr + 12);
1497 }1490 }
1498 last_itod_magic=0;1491 last_itod_magic=0;
1499 leaffunc = 1;1492 leaffunc = 1;
1500 loc = 0;1493 S->tccgen_loc = 0;
1501#ifdef CONFIG_TCC_BCHECK1494#ifdef CONFIG_TCC_BCHECK
1502 if (tcc_state->do_bounds_check)1495 if (S->do_bounds_check)
1503 gen_bounds_prolog();1496 gen_bounds_prolog(S);
1504#endif1497#endif
1505}1498}
1506 1499
1507/* generate function epilog */1500/* generate function epilog */
1508void gfunc_epilog(void)1501void gfunc_epilog(TCCState* S)
1509{1502{
1510 uint32_t x;1503 uint32_t x;
1511 int diff;1504 int diff;
1512 1505
1513#ifdef CONFIG_TCC_BCHECK1506#ifdef CONFIG_TCC_BCHECK
1514 if (tcc_state->do_bounds_check)1507 if (S->do_bounds_check)
1515 gen_bounds_epilog();1508 gen_bounds_epilog(S);
1516#endif1509#endif
1517 /* Copy float return value to core register if base standard is used and1510 /* Copy float return value to core register if base standard is used and
1518 float computation is made with VFP */1511 float computation is made with VFP */
1519#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)1512#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
1520 if ((float_abi == ARM_SOFTFP_FLOAT || func_var) && is_float(func_vt.t)) {1513 if ((float_abi == ARM_SOFTFP_FLOAT || S->tccgen_func_var) && is_float(S->tccgen_func_vt.t)) {
1521 if((func_vt.t & VT_BTYPE) == VT_FLOAT)1514 if((S->tccgen_func_vt.t & VT_BTYPE) == VT_FLOAT)
1522 o(0xEE100A10); /* fmrs r0, s0 */1515 o(S, 0xEE100A10); /* fmrs r0, s0 */
1523 else {1516 else {
1524 o(0xEE100B10); /* fmrdl r0, d0 */1517 o(S, 0xEE100B10); /* fmrdl r0, d0 */
1525 o(0xEE301B10); /* fmrdh r1, d0 */1518 o(S, 0xEE301B10); /* fmrdh r1, d0 */
1526 }1519 }
1527 }1520 }
1528#endif1521#endif
1529 o(0xE89BA800); /* restore fp, sp, pc */1522 o(S, 0xE89BA800); /* restore fp, sp, pc */
1530 diff = (-loc + 3) & -4;1523 diff = (-S->tccgen_loc + 3) & -4;
1531#ifdef TCC_ARM_EABI1524#ifdef TCC_ARM_EABI
1532 if(!leaffunc)1525 if(!leaffunc)
1533 diff = ((diff + 11) & -8) - 4;1526 diff = ((diff + 11) & -8) - 4;
@@ -1538,74 +1531,74 @@ void gfunc_epilog(void) · 4 unmodified lines
1538 *(uint32_t *)(cur_text_section->data + func_sub_sp_offset) = x;1531 *(uint32_t *)(cur_text_section->data + func_sub_sp_offset) = x;
1539 else {1532 else {
1540 int addr;1533 int addr;
1541 addr=ind;1534 addr=S->tccgen_ind;
1542 o(0xE59FC004); /* ldr ip,[pc+4] */1535 o(S, 0xE59FC004); /* ldr ip,[pc+4] */
1543 o(0xE04BD00C); /* sub sp,fp,ip */1536 o(S, 0xE04BD00C); /* sub sp,fp,ip */
1544 o(0xE1A0F00E); /* mov pc,lr */1537 o(S, 0xE1A0F00E); /* mov pc,lr */
1545 o(diff);1538 o(S, diff);
1546 *(uint32_t *)(cur_text_section->data + func_sub_sp_offset) = 0xE1000000|encbranch(func_sub_sp_offset,addr,1);1539 *(uint32_t *)(cur_text_section->data + func_sub_sp_offset) = 0xE1000000|encbranch(S, func_sub_sp_offset,addr,1);
1547 }1540 }
1548 }1541 }
1549}1542}
1550 1543
1551ST_FUNC void gen_fill_nops(int bytes)1544ST_FUNC void gen_fill_nops(TCCState* S, int bytes)
1552{1545{
1553 if ((bytes & 3))1546 if ((bytes & 3))
1554 tcc_error("alignment of code section not multiple of 4");1547 tcc_error(S, "alignment of code section not multiple of 4");
1555 while (bytes > 0) {1548 while (bytes > 0) {
1556 o(0xE1A00000);1549 o(S, 0xE1A00000);
1557 bytes -= 4;1550 bytes -= 4;
1558 }1551 }
1559}1552}
1560 1553
1561/* generate a jump to a label */1554/* generate a jump to a label */
1562ST_FUNC int gjmp(int t)1555ST_FUNC int gjmp(TCCState* S, int t)
1563{1556{
1564 int r;1557 int r;
1565 if (nocode_wanted)1558 if (S->tccgen_nocode_wanted)
1566 return t;1559 return t;
1567 r=ind;1560 r=S->tccgen_ind;
1568 o(0xE0000000|encbranch(r,t,1));1561 o(S, 0xE0000000|encbranch(S, r,t,1));
1569 return r;1562 return r;
1570}1563}
1571 1564
1572/* generate a jump to a fixed address */1565/* generate a jump to a fixed address */
1573ST_FUNC void gjmp_addr(int a)1566ST_FUNC void gjmp_addr(TCCState* S, int a)
1574{1567{
1575 gjmp(a);1568 gjmp(S, a);
1576}1569}
1577 1570
1578ST_FUNC int gjmp_cond(int op, int t)1571ST_FUNC int gjmp_cond(TCCState* S, int op, int t)
1579{1572{
1580 int r;1573 int r;
1581 if (nocode_wanted)1574 if (S->tccgen_nocode_wanted)
1582 return t;1575 return t;
1583 r=ind;1576 r=S->tccgen_ind;
1584 op=mapcc(op);1577 op=mapcc(S, op);
1585 op|=encbranch(r,t,1);1578 op|=encbranch(S, r,t,1);
1586 o(op);1579 o(S, op);
1587 return r;1580 return r;
1588}1581}
1589 1582
1590ST_FUNC int gjmp_append(int n, int t)1583ST_FUNC int gjmp_append(TCCState* S, int n, int t)
1591{1584{
1592 uint32_t *x;1585 uint32_t *x;
1593 int p,lp;1586 int p,lp;
1594 if(n) {1587 if(n) {
1595 p = n;1588 p = n;
1596 do {1589 do {
1597 p = decbranch(lp=p);1590 p = decbranch(S, lp=p);
1598 } while(p);1591 } while(p);
1599 x = (uint32_t *)(cur_text_section->data + lp);1592 x = (uint32_t *)(cur_text_section->data + lp);
1600 *x &= 0xff000000;1593 *x &= 0xff000000;
1601 *x |= encbranch(lp,t,1);1594 *x |= encbranch(S, lp,t,1);
1602 t = n;1595 t = n;
1603 }1596 }
1604 return t;1597 return t;
1605}1598}
1606 1599
1607/* generate an integer binary operation */1600/* generate an integer binary operation */
1608void gen_opi(int op)1601void gen_opi(TCCState* S, int op)
1609{1602{
1610 int c, func = 0;1603 int c, func = 0;
1611 uint32_t opc = 0, r, fr;1604 uint32_t opc = 0, r, fr;
@@ -1650,11 +1643,11 @@ void gen_opi(int op) · 38 unmodified lines
1650 c=1;1643 c=1;
1651 break;1644 break;
1652 case '*':1645 case '*':
1653 gv2(RC_INT, RC_INT);1646 gv2(S, RC_INT, RC_INT);
1654 r = vtop[-1].r;1647 r = S->tccgen_vtop[-1].r;
1655 fr = vtop[0].r;1648 fr = S->tccgen_vtop[0].r;
1656 vtop--;1649 S->tccgen_vtop--;
1657 o(0xE0000090|(intr(r)<<16)|(intr(r)<<8)|intr(fr));1650 o(S, 0xE0000090|(intr(S, r)<<16)|(intr(S, r)<<8)|intr(S, fr));
1658 return;1651 return;
1659 case TOK_SHL:1652 case TOK_SHL:
1660 opc = 0;1653 opc = 0;
@@ -1696,12 +1689,12 @@ void gen_opi(int op) · 35 unmodified lines
1696 c=3;1689 c=3;
1697 break;1690 break;
1698 case TOK_UMULL:1691 case TOK_UMULL:
1699 gv2(RC_INT, RC_INT);1692 gv2(S, RC_INT, RC_INT);
1700 r=intr(vtop[-1].r2=get_reg(RC_INT));1693 r=intr(S, S->tccgen_vtop[-1].r2=get_reg(S, RC_INT));
1701 c=vtop[-1].r;1694 c=S->tccgen_vtop[-1].r;
1702 vtop[-1].r=get_reg_ex(RC_INT,regmask(c));1695 S->tccgen_vtop[-1].r=get_reg_ex(S, RC_INT,regmask(S, c));
1703 vtop--;1696 S->tccgen_vtop--;
1704 o(0xE0800090|(r<<16)|(intr(vtop->r)<<12)|(intr(c)<<8)|intr(vtop[1].r));1697 o(S, 0xE0800090|(r<<16)|(intr(S, S->tccgen_vtop->r)<<12)|(intr(S, c)<<8)|intr(S, S->tccgen_vtop[1].r));
1705 return;1698 return;
1706 default:1699 default:
1707 opc = 0x15;1700 opc = 0x15;
@@ -1710,128 +1703,128 @@ void gen_opi(int op) · 2 unmodified lines
1710 }1703 }
1711 switch(c) {1704 switch(c) {
1712 case 1:1705 case 1:
1713 if((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {1706 if((S->tccgen_vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1714 if(opc == 4 || opc == 5 || opc == 0xc) {1707 if(opc == 4 || opc == 5 || opc == 0xc) {
1715 vswap();1708 vswap(S);
1716 opc|=2; // sub -> rsb1709 opc|=2; // sub -> rsb
1717 }1710 }
1718 }1711 }
1719 if ((vtop->r & VT_VALMASK) == VT_CMP ||1712 if ((S->tccgen_vtop->r & VT_VALMASK) == VT_CMP ||
1720 (vtop->r & (VT_VALMASK & ~1)) == VT_JMP)1713 (S->tccgen_vtop->r & (VT_VALMASK & ~1)) == VT_JMP)
1721 gv(RC_INT);1714 gv(S, RC_INT);
1722 vswap();1715 vswap(S);
1723 c=intr(gv(RC_INT));1716 c=intr(S, gv(S, RC_INT));
1724 vswap();1717 vswap(S);
1725 opc=0xE0000000|(opc<<20);1718 opc=0xE0000000|(opc<<20);
1726 if((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {1719 if((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1727 uint32_t x;1720 uint32_t x;
1728 x=stuff_const(opc|0x2000000|(c<<16),vtop->c.i);1721 x=stuff_const(opc|0x2000000|(c<<16),S->tccgen_vtop->c.i);
1729 if(x) {1722 if(x) {
1730 if ((x & 0xfff00000) == 0xe3500000) // cmp rx,#c1723 if ((x & 0xfff00000) == 0xe3500000) // cmp rx,#c
1731 o(x);1724 o(S, x);
1732 else {1725 else {
1733 r=intr(vtop[-1].r=get_reg_ex(RC_INT,regmask(vtop[-1].r)));1726 r=intr(S, S->tccgen_vtop[-1].r=get_reg_ex(S, RC_INT,regmask(S, S->tccgen_vtop[-1].r)));
1734 o(x|(r<<12));1727 o(S, x|(r<<12));
1735 }1728 }
1736 goto done;1729 goto done;
1737 }1730 }
1738 }1731 }
1739 fr=intr(gv(RC_INT));1732 fr=intr(S, gv(S, RC_INT));
1740#ifdef CONFIG_TCC_BCHECK1733#ifdef CONFIG_TCC_BCHECK
1741 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {1734 if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
1742 vswap();1735 vswap(S);
1743 c=intr(gv(RC_INT));1736 c=intr(S, gv(S, RC_INT));
1744 vswap();1737 vswap(S);
1745 }1738 }
1746#endif1739#endif
1747 if ((opc & 0xfff00000) == 0xe1500000) // cmp rx,ry1740 if ((opc & 0xfff00000) == 0xe1500000) // cmp rx,ry
1748 o(opc|(c<<16)|fr);1741 o(S, opc|(c<<16)|fr);
1749 else {1742 else {
1750 r=intr(vtop[-1].r=get_reg_ex(RC_INT,two2mask(vtop->r,vtop[-1].r)));1743 r=intr(S, S->tccgen_vtop[-1].r=get_reg_ex(S, RC_INT,two2mask(S, S->tccgen_vtop->r,S->tccgen_vtop[-1].r)));
1751 o(opc|(c<<16)|(r<<12)|fr);1744 o(S, opc|(c<<16)|(r<<12)|fr);
1752 }1745 }
1753done:1746done:
1754 vtop--;1747 S->tccgen_vtop--;
1755 if (op >= TOK_ULT && op <= TOK_GT)1748 if (op >= TOK_ULT && op <= TOK_GT)
1756 vset_VT_CMP(op);1749 vset_VT_CMP(S, op);
1757 break;1750 break;
1758 case 2:1751 case 2:
1759 opc=0xE1A00000|(opc<<5);1752 opc=0xE1A00000|(opc<<5);
1760 if ((vtop->r & VT_VALMASK) == VT_CMP ||1753 if ((S->tccgen_vtop->r & VT_VALMASK) == VT_CMP ||
1761 (vtop->r & (VT_VALMASK & ~1)) == VT_JMP)1754 (S->tccgen_vtop->r & (VT_VALMASK & ~1)) == VT_JMP)
1762 gv(RC_INT);1755 gv(S, RC_INT);
1763 vswap();1756 vswap(S);
1764 r=intr(gv(RC_INT));1757 r=intr(S, gv(S, RC_INT));
1765 vswap();1758 vswap(S);
1766 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {1759 if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1767 fr=intr(vtop[-1].r=get_reg_ex(RC_INT,regmask(vtop[-1].r)));1760 fr=intr(S, S->tccgen_vtop[-1].r=get_reg_ex(S, RC_INT,regmask(S, S->tccgen_vtop[-1].r)));
1768 c = vtop->c.i & 0x1f;1761 c = S->tccgen_vtop->c.i & 0x1f;
1769 o(opc|r|(c<<7)|(fr<<12));1762 o(S, opc|r|(c<<7)|(fr<<12));
1770 } else {1763 } else {
1771 fr=intr(gv(RC_INT));1764 fr=intr(S, gv(S, RC_INT));
1772#ifdef CONFIG_TCC_BCHECK1765#ifdef CONFIG_TCC_BCHECK
1773 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {1766 if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
1774 vswap();1767 vswap(S);
1775 r=intr(gv(RC_INT));1768 r=intr(S, gv(S, RC_INT));
1776 vswap();1769 vswap(S);
1777 }1770 }
1778#endif1771#endif
1779 c=intr(vtop[-1].r=get_reg_ex(RC_INT,two2mask(vtop->r,vtop[-1].r)));1772 c=intr(S, S->tccgen_vtop[-1].r=get_reg_ex(S, RC_INT,two2mask(S, S->tccgen_vtop->r,S->tccgen_vtop[-1].r)));
1780 o(opc|r|(c<<12)|(fr<<8)|0x10);1773 o(S, opc|r|(c<<12)|(fr<<8)|0x10);
1781 }1774 }
1782 vtop--;1775 S->tccgen_vtop--;
1783 break;1776 break;
1784 case 3:1777 case 3:
1785 vpush_helper_func(func);1778 vpush_helper_func(S, func);
1786 vrott(3);1779 vrott(S, 3);
1787 gfunc_call(2);1780 gfunc_call(S, 2);
1788 vpushi(0);1781 vpushi(S, 0);
1789 vtop->r = retreg;1782 S->tccgen_vtop->r = retreg;
1790 break;1783 break;
1791 default:1784 default:
1792 tcc_error("gen_opi %i unimplemented!",op);1785 tcc_error(S, "gen_opi %i unimplemented!",op);
1793 }1786 }
1794}1787}
1795 1788
1796#ifdef TCC_ARM_VFP1789#ifdef TCC_ARM_VFP
1797static int is_zero(int i)1790static int is_zero(TCCState* S, int i)
1798{1791{
1799 if((vtop[i].r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)1792 if((S->tccgen_vtop[i].r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1800 return 0;1793 return 0;
1801 if (vtop[i].type.t == VT_FLOAT)1794 if (S->tccgen_vtop[i].type.t == VT_FLOAT)
1802 return (vtop[i].c.f == 0.f);1795 return (S->tccgen_vtop[i].c.f == 0.f);
1803 else if (vtop[i].type.t == VT_DOUBLE)1796 else if (S->tccgen_vtop[i].type.t == VT_DOUBLE)
1804 return (vtop[i].c.d == 0.0);1797 return (S->tccgen_vtop[i].c.d == 0.0);
1805 return (vtop[i].c.ld == 0.l);1798 return (S->tccgen_vtop[i].c.ld == 0.l);
1806}1799}
1807 1800
1808/* generate a floating point operation 'v = t1 op t2' instruction. The1801/* generate a floating point operation 'v = t1 op t2' instruction. The
1809 * two operands are guaranteed to have the same floating point type */1802 * two operands are guaranteed to have the same floating point type */
1810void gen_opf(int op)1803void gen_opf(TCCState* S, int op)
1811{1804{
1812 uint32_t x;1805 uint32_t x;
1813 int fneg=0,r;1806 int fneg=0,r;
1814 x=0xEE000A00|T2CPR(vtop->type.t);1807 x=0xEE000A00|T2CPR(S->tccgen_vtop->type.t);
1815 switch(op) {1808 switch(op) {
1816 case '+':1809 case '+':
1817 if(is_zero(-1))1810 if(is_zero(S, -1))
1818 vswap();1811 vswap(S);
1819 if(is_zero(0)) {1812 if(is_zero(S, 0)) {
1820 vtop--;1813 S->tccgen_vtop--;
1821 return;1814 return;
1822 }1815 }
1823 x|=0x300000;1816 x|=0x300000;
1824 break;1817 break;
1825 case '-':1818 case '-':
1826 x|=0x300040;1819 x|=0x300040;
1827 if(is_zero(0)) {1820 if(is_zero(S, 0)) {
1828 vtop--;1821 S->tccgen_vtop--;
1829 return;1822 return;
1830 }1823 }
1831 if(is_zero(-1)) {1824 if(is_zero(S, -1)) {
1832 x|=0x810000; /* fsubX -> fnegX */1825 x|=0x810000; /* fsubX -> fnegX */
1833 vswap();1826 vswap(S);
1834 vtop--;1827 S->tccgen_vtop--;
1835 fneg=1;1828 fneg=1;
1836 }1829 }
1837 break;1830 break;
@@ -1843,11 +1836,11 @@ void gen_opf(int op) · 5 unmodified lines
1843 break;1836 break;
1844 default:1837 default:
1845 if(op < TOK_ULT || op > TOK_GT) {1838 if(op < TOK_ULT || op > TOK_GT) {
1846 tcc_error("unknown fp op %x!",op);1839 tcc_error(S, "unknown fp op %x!",op);
1847 return;1840 return;
1848 }1841 }
1849 if(is_zero(-1)) {1842 if(is_zero(S, -1)) {
1850 vswap();1843 vswap(S);
1851 switch(op) {1844 switch(op) {
1852 case TOK_LT: op=TOK_GT; break;1845 case TOK_LT: op=TOK_GT; break;
1853 case TOK_GE: op=TOK_ULE; break;1846 case TOK_GE: op=TOK_ULE; break;
@@ -1858,16 +1851,16 @@ void gen_opf(int op) · 4 unmodified lines
1858 x|=0xB40040; /* fcmpX */1851 x|=0xB40040; /* fcmpX */
1859 if(op!=TOK_EQ && op!=TOK_NE)1852 if(op!=TOK_EQ && op!=TOK_NE)
1860 x|=0x80; /* fcmpX -> fcmpeX */1853 x|=0x80; /* fcmpX -> fcmpeX */
1861 if(is_zero(0)) {1854 if(is_zero(S, 0)) {
1862 vtop--;1855 S->tccgen_vtop--;
1863 o(x|0x10000|(vfpr(gv(RC_FLOAT))<<12)); /* fcmp(e)X -> fcmp(e)zX */1856 o(S, x|0x10000|(vfpr(S, gv(S, RC_FLOAT))<<12)); /* fcmp(e)X -> fcmp(e)zX */
1864 } else {1857 } else {
1865 gv2(RC_FLOAT,RC_FLOAT);1858 gv2(S, RC_FLOAT,RC_FLOAT);
1866 x|=vfpr(vtop[0].r);1859 x|=vfpr(S, S->tccgen_vtop[0].r);
1867 o(x|(vfpr(vtop[-1].r) << 12));1860 o(S, x|(vfpr(S, S->tccgen_vtop[-1].r) << 12));
1868 vtop--;1861 S->tccgen_vtop--;
1869 }1862 }
1870 o(0xEEF1FA10); /* fmstat */1863 o(S, 0xEEF1FA10); /* fmstat */
1871 1864
1872 switch(op) {1865 switch(op) {
1873 case TOK_LE: op=TOK_ULE; break;1866 case TOK_LE: op=TOK_ULE; break;
@@ -1875,46 +1868,46 @@ void gen_opf(int op) · 1 unmodified line
1875 case TOK_UGE: op=TOK_GE; break;1868 case TOK_UGE: op=TOK_GE; break;
1876 case TOK_UGT: op=TOK_GT; break;1869 case TOK_UGT: op=TOK_GT; break;
1877 }1870 }
1878 vset_VT_CMP(op);1871 vset_VT_CMP(S, op);
1879 return;1872 return;
1880 }1873 }
1881 r=gv(RC_FLOAT);1874 r=gv(S, RC_FLOAT);
1882 x|=vfpr(r);1875 x|=vfpr(S, r);
1883 r=regmask(r);1876 r=regmask(S, r);
1884 if(!fneg) {1877 if(!fneg) {
1885 int r2;1878 int r2;
1886 vswap();1879 vswap(S);
1887 r2=gv(RC_FLOAT);1880 r2=gv(S, RC_FLOAT);
1888 x|=vfpr(r2)<<16;1881 x|=vfpr(S, r2)<<16;
1889 r|=regmask(r2);1882 r|=regmask(S, r2);
1890#ifdef CONFIG_TCC_BCHECK1883#ifdef CONFIG_TCC_BCHECK
1891 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {1884 if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
1892 vswap();1885 vswap(S);
1893 r=gv(RC_FLOAT);1886 r=gv(S, RC_FLOAT);
1894 vswap();1887 vswap(S);
1895 x=(x&~0xf)|vfpr(r);1888 x=(x&~0xf)|vfpr(S, r);
1896 }1889 }
1897#endif1890#endif
1898 }1891 }
1899 vtop->r=get_reg_ex(RC_FLOAT,r);1892 S->tccgen_vtop->r=get_reg_ex(S, RC_FLOAT,r);
1900 if(!fneg)1893 if(!fneg)
1901 vtop--;1894 S->tccgen_vtop--;
1902 o(x|(vfpr(vtop->r)<<12));1895 o(S, x|(vfpr(S, S->tccgen_vtop->r)<<12));
1903}1896}
1904 1897
1905#else1898#else
1906static uint32_t is_fconst()1899static uint32_t is_fconst(TCCState* S)
1907{1900{
1908 long double f;1901 long double f;
1909 uint32_t r;1902 uint32_t r;
1910 if((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)1903 if((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1911 return 0;1904 return 0;
1912 if (vtop->type.t == VT_FLOAT)1905 if (S->tccgen_vtop->type.t == VT_FLOAT)
1913 f = vtop->c.f;1906 f = S->tccgen_vtop->c.f;
1914 else if (vtop->type.t == VT_DOUBLE)1907 else if (S->tccgen_vtop->type.t == VT_DOUBLE)
1915 f = vtop->c.d;1908 f = S->tccgen_vtop->c.d;
1916 else1909 else
1917 f = vtop->c.ld;1910 f = S->tccgen_vtop->c.ld;
1918 if(!ieee_finite(f))1911 if(!ieee_finite(f))
1919 return 0;1912 return 0;
1920 r=0x8;1913 r=0x8;
@@ -1943,45 +1936,45 @@ static uint32_t is_fconst() · 22 unmodified lines
1943 1936
1944/* generate a floating point operation 'v = t1 op t2' instruction. The1937/* generate a floating point operation 'v = t1 op t2' instruction. The
1945 two operands are guaranteed to have the same floating point type */1938 two operands are guaranteed to have the same floating point type */
1946void gen_opf(int op)1939void gen_opf(TCCState* S, int op)
1947{1940{
1948 uint32_t x, r, r2, c1, c2;1941 uint32_t x, r, r2, c1, c2;
1949 //fputs("gen_opf\n",stderr);1942 //fputs("gen_opf\n",stderr);
1950 vswap();1943 vswap(S);
1951 c1 = is_fconst();1944 c1 = is_fconst(S);
1952 vswap();1945 vswap(S);
1953 c2 = is_fconst();1946 c2 = is_fconst(S);
1954 x=0xEE000100;1947 x=0xEE000100;
1955#if LDOUBLE_SIZE == 81948#if LDOUBLE_SIZE == 8
1956 if ((vtop->type.t & VT_BTYPE) != VT_FLOAT)1949 if ((S->tccgen_vtop->type.t & VT_BTYPE) != VT_FLOAT)
1957 x|=0x80;1950 x|=0x80;
1958#else1951#else
1959 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)1952 if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_DOUBLE)
1960 x|=0x80;1953 x|=0x80;
1961 else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE)1954 else if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LDOUBLE)
1962 x|=0x80000;1955 x|=0x80000;
1963#endif1956#endif
1964 switch(op)1957 switch(op)
1965 {1958 {
1966 case '+':1959 case '+':
1967 if(!c2) {1960 if(!c2) {
1968 vswap();1961 vswap(S);
1969 c2=c1;1962 c2=c1;
1970 }1963 }
1971 vswap();1964 vswap(S);
1972 r=fpr(gv(RC_FLOAT));1965 r=fpr(S, gv(S, RC_FLOAT));
1973 vswap();1966 vswap(S);
1974 if(c2) {1967 if(c2) {
1975 if(c2>0xf)1968 if(c2>0xf)
1976 x|=0x200000; // suf1969 x|=0x200000; // suf
1977 r2=c2&0xf;1970 r2=c2&0xf;
1978 } else {1971 } else {
1979 r2=fpr(gv(RC_FLOAT));1972 r2=fpr(S, gv(S, RC_FLOAT));
1980#ifdef CONFIG_TCC_BCHECK1973#ifdef CONFIG_TCC_BCHECK
1981 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {1974 if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
1982 vswap();1975 vswap(S);
1983 r=fpr(gv(RC_FLOAT));1976 r=fpr(S, gv(S, RC_FLOAT));
1984 vswap();1977 vswap(S);
1985 }1978 }
1986#endif1979#endif
1987 }1980 }
@@ -1991,46 +1984,46 @@ void gen_opf(int op) · 3 unmodified lines
1991 if(c2<=0xf)1984 if(c2<=0xf)
1992 x|=0x200000; // suf1985 x|=0x200000; // suf
1993 r2=c2&0xf;1986 r2=c2&0xf;
1994 vswap();1987 vswap(S);
1995 r=fpr(gv(RC_FLOAT));1988 r=fpr(S, gv(S, RC_FLOAT));
1996 vswap();1989 vswap(S);
1997 } else if(c1 && c1<=0xf) {1990 } else if(c1 && c1<=0xf) {
1998 x|=0x300000; // rsf1991 x|=0x300000; // rsf
1999 r2=c1;1992 r2=c1;
2000 r=fpr(gv(RC_FLOAT));1993 r=fpr(S, gv(S, RC_FLOAT));
2001 vswap();1994 vswap(S);
2002 } else {1995 } else {
2003 x|=0x200000; // suf1996 x|=0x200000; // suf
2004 vswap();1997 vswap(S);
2005 r=fpr(gv(RC_FLOAT));1998 r=fpr(S, gv(S, RC_FLOAT));
2006 vswap();1999 vswap(S);
2007 r2=fpr(gv(RC_FLOAT));2000 r2=fpr(S, gv(S, RC_FLOAT));
2008#ifdef CONFIG_TCC_BCHECK2001#ifdef CONFIG_TCC_BCHECK
2009 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {2002 if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
2010 vswap();2003 vswap(S);
2011 r=fpr(gv(RC_FLOAT));2004 r=fpr(S, gv(S, RC_FLOAT));
2012 vswap();2005 vswap(S);
2013 }2006 }
2014#endif2007#endif
2015 }2008 }
2016 break;2009 break;
2017 case '*':2010 case '*':
2018 if(!c2 || c2>0xf) {2011 if(!c2 || c2>0xf) {
2019 vswap();2012 vswap(S);
2020 c2=c1;2013 c2=c1;
2021 }2014 }
2022 vswap();2015 vswap(S);
2023 r=fpr(gv(RC_FLOAT));2016 r=fpr(S, gv(S, RC_FLOAT));
2024 vswap();2017 vswap(S);
2025 if(c2 && c2<=0xf)2018 if(c2 && c2<=0xf)
2026 r2=c2;2019 r2=c2;
2027 else {2020 else {
2028 r2=fpr(gv(RC_FLOAT));2021 r2=fpr(S, gv(S, RC_FLOAT));
2029#ifdef CONFIG_TCC_BCHECK2022#ifdef CONFIG_TCC_BCHECK
2030 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {2023 if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
2031 vswap();2024 vswap(S);
2032 r=fpr(gv(RC_FLOAT));2025 r=fpr(S, gv(S, RC_FLOAT));
2033 vswap();2026 vswap(S);
2034 }2027 }
2035#endif2028#endif
2036 }2029 }
@@ -2040,25 +2033,25 @@ void gen_opf(int op) · 3 unmodified lines
2040 if(c2 && c2<=0xf) {2033 if(c2 && c2<=0xf) {
2041 x|=0x400000; // dvf2034 x|=0x400000; // dvf
2042 r2=c2;2035 r2=c2;
2043 vswap();2036 vswap(S);
2044 r=fpr(gv(RC_FLOAT));2037 r=fpr(S, gv(S, RC_FLOAT));
2045 vswap();2038 vswap(S);
2046 } else if(c1 && c1<=0xf) {2039 } else if(c1 && c1<=0xf) {
2047 x|=0x500000; // rdf2040 x|=0x500000; // rdf
2048 r2=c1;2041 r2=c1;
2049 r=fpr(gv(RC_FLOAT));2042 r=fpr(S, gv(S, RC_FLOAT));
2050 vswap();2043 vswap(S);
2051 } else {2044 } else {
2052 x|=0x400000; // dvf2045 x|=0x400000; // dvf
2053 vswap();2046 vswap(S);
2054 r=fpr(gv(RC_FLOAT));2047 r=fpr(S, gv(S, RC_FLOAT));
2055 vswap();2048 vswap(S);
2056 r2=fpr(gv(RC_FLOAT));2049 r2=fpr(S, gv(S, RC_FLOAT));
2057#ifdef CONFIG_TCC_BCHECK2050#ifdef CONFIG_TCC_BCHECK
2058 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {2051 if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
2059 vswap();2052 vswap(S);
2060 r=fpr(gv(RC_FLOAT));2053 r=fpr(S, gv(S, RC_FLOAT));
2061 vswap();2054 vswap(S);
2062 }2055 }
2063#endif2056#endif
2064 }2057 }
@@ -2073,7 +2066,7 @@ void gen_opf(int op) · 8 unmodified lines
2073 case TOK_UGE:2066 case TOK_UGE:
2074 case TOK_ULE:2067 case TOK_ULE:
2075 case TOK_UGT:2068 case TOK_UGT:
2076 tcc_error("unsigned comparison on floats?");2069 tcc_error(S, "unsigned comparison on floats?");
2077 break;2070 break;
2078 case TOK_LT:2071 case TOK_LT:
2079 op=TOK_Nset;2072 op=TOK_Nset;
@@ -2088,7 +2081,7 @@ void gen_opf(int op) · 8 unmodified lines
2088 }2081 }
2089 if(c1 && !c2) {2082 if(c1 && !c2) {
2090 c2=c1;2083 c2=c1;
2091 vswap();2084 vswap(S);
2092 switch(op) {2085 switch(op) {
2093 case TOK_Nset:2086 case TOK_Nset:
2094 op=TOK_GT;2087 op=TOK_GT;
@@ -2104,86 +2097,86 @@ void gen_opf(int op) · 9 unmodified lines
2104 break;2097 break;
2105 }2098 }
2106 }2099 }
2107 vswap();2100 vswap(S);
2108 r=fpr(gv(RC_FLOAT));2101 r=fpr(S, gv(S, RC_FLOAT));
2109 vswap();2102 vswap(S);
2110 if(c2) {2103 if(c2) {
2111 if(c2>0xf)2104 if(c2>0xf)
2112 x|=0x200000;2105 x|=0x200000;
2113 r2=c2&0xf;2106 r2=c2&0xf;
2114 } else {2107 } else {
2115 r2=fpr(gv(RC_FLOAT));2108 r2=fpr(S, gv(S, RC_FLOAT));
2116#ifdef CONFIG_TCC_BCHECK2109#ifdef CONFIG_TCC_BCHECK
2117 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {2110 if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
2118 vswap();2111 vswap(S);
2119 r=fpr(gv(RC_FLOAT));2112 r=fpr(S, gv(S, RC_FLOAT));
2120 vswap();2113 vswap(S);
2121 }2114 }
2122#endif2115#endif
2123 }2116 }
2124 --vtop;2117 --S->tccgen_vtop;
2125 vset_VT_CMP(op);2118 vset_VT_CMP(S, op);
2126 ++vtop;2119 ++S->tccgen_vtop;
2127 } else {2120 } else {
2128 tcc_error("unknown fp op %x!",op);2121 tcc_error(S, "unknown fp op %x!",op);
2129 return;2122 return;
2130 }2123 }
2131 }2124 }
2132 if(vtop[-1].r == VT_CMP)2125 if(S->tccgen_vtop[-1].r == VT_CMP)
2133 c1=15;2126 c1=15;
2134 else {2127 else {
2135 c1=vtop->r;2128 c1=S->tccgen_vtop->r;
2136 if(r2&0x8)2129 if(r2&0x8)
2137 c1=vtop[-1].r;2130 c1=S->tccgen_vtop[-1].r;
2138 vtop[-1].r=get_reg_ex(RC_FLOAT,two2mask(vtop[-1].r,c1));2131 S->tccgen_vtop[-1].r=get_reg_ex(S, RC_FLOAT,two2mask(S, S->tccgen_vtop[-1].r,c1));
2139 c1=fpr(vtop[-1].r);2132 c1=fpr(S, S->tccgen_vtop[-1].r);
2140 }2133 }
2141 vtop--;2134 S->tccgen_vtop--;
2142 o(x|(r<<16)|(c1<<12)|r2);2135 o(S, x|(r<<16)|(c1<<12)|r2);
2143}2136}
2144#endif2137#endif
2145 2138
2146/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'2139/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
2147 and 'long long' cases. */2140 and 'long long' cases. */
2148ST_FUNC void gen_cvt_itof(int t)2141ST_FUNC void gen_cvt_itof(TCCState* S, int t)
2149{2142{
2150 uint32_t r, r2;2143 uint32_t r, r2;
2151 int bt;2144 int bt;
2152 bt=vtop->type.t & VT_BTYPE;2145 bt=S->tccgen_vtop->type.t & VT_BTYPE;
2153 if(bt == VT_INT || bt == VT_SHORT || bt == VT_BYTE) {2146 if(bt == VT_INT || bt == VT_SHORT || bt == VT_BYTE) {
2154#ifndef TCC_ARM_VFP2147#ifndef TCC_ARM_VFP
2155 uint32_t dsize = 0;2148 uint32_t dsize = 0;
2156#endif2149#endif
2157 r=intr(gv(RC_INT));2150 r=intr(S, gv(S, RC_INT));
2158#ifdef TCC_ARM_VFP2151#ifdef TCC_ARM_VFP
2159 r2=vfpr(vtop->r=get_reg(RC_FLOAT));2152 r2=vfpr(S, S->tccgen_vtop->r=get_reg(S, RC_FLOAT));
2160 o(0xEE000A10|(r<<12)|(r2<<16)); /* fmsr */2153 o(S, 0xEE000A10|(r<<12)|(r2<<16)); /* fmsr */
2161 r2|=r2<<12;2154 r2|=r2<<12;
2162 if(!(vtop->type.t & VT_UNSIGNED))2155 if(!(S->tccgen_vtop->type.t & VT_UNSIGNED))
2163 r2|=0x80; /* fuitoX -> fsituX */2156 r2|=0x80; /* fuitoX -> fsituX */
2164 o(0xEEB80A40|r2|T2CPR(t)); /* fYitoX*/2157 o(S, 0xEEB80A40|r2|T2CPR(t)); /* fYitoX*/
2165#else2158#else
2166 r2=fpr(vtop->r=get_reg(RC_FLOAT));2159 r2=fpr(S, S->tccgen_vtop->r=get_reg(S, RC_FLOAT));
2167 if((t & VT_BTYPE) != VT_FLOAT)2160 if((t & VT_BTYPE) != VT_FLOAT)
2168 dsize=0x80; /* flts -> fltd */2161 dsize=0x80; /* flts -> fltd */
2169 o(0xEE000110|dsize|(r2<<16)|(r<<12)); /* flts */2162 o(S, 0xEE000110|dsize|(r2<<16)|(r<<12)); /* flts */
2170 if((vtop->type.t & (VT_UNSIGNED|VT_BTYPE)) == (VT_UNSIGNED|VT_INT)) {2163 if((S->tccgen_vtop->type.t & (VT_UNSIGNED|VT_BTYPE)) == (VT_UNSIGNED|VT_INT)) {
2171 uint32_t off = 0;2164 uint32_t off = 0;
2172 o(0xE3500000|(r<<12)); /* cmp */2165 o(S, 0xE3500000|(r<<12)); /* cmp */
2173 r=fpr(get_reg(RC_FLOAT));2166 r=fpr(S, get_reg(S, RC_FLOAT));
2174 if(last_itod_magic) {2167 if(last_itod_magic) {
2175 off=ind+8-last_itod_magic;2168 off=S->tccgen_ind+8-last_itod_magic;
2176 off/=4;2169 off/=4;
2177 if(off>255)2170 if(off>255)
2178 off=0;2171 off=0;
2179 }2172 }
2180 o(0xBD1F0100|(r<<12)|off); /* ldflts */2173 o(S, 0xBD1F0100|(r<<12)|off); /* ldflts */
2181 if(!off) {2174 if(!off) {
2182 o(0xEA000000); /* b */2175 o(S, 0xEA000000); /* b */
2183 last_itod_magic=ind;2176 last_itod_magic=S->tccgen_ind;
2184 o(0x4F800000); /* 4294967296.0f */2177 o(S, 0x4F800000); /* 4294967296.0f */
2185 }2178 }
2186 o(0xBE000100|dsize|(r2<<16)|(r2<<12)|r); /* adflt */2179 o(S, 0xBE000100|dsize|(r2<<16)|(r2<<12)|r); /* adflt */
2187 }2180 }
2188#endif2181#endif
2189 return;2182 return;
@@ -2191,15 +2184,15 @@ ST_FUNC void gen_cvt_itof(int t) · 1 unmodified line
2191 int func;2184 int func;
2192 CType *func_type = 0;2185 CType *func_type = 0;
2193 if((t & VT_BTYPE) == VT_FLOAT) {2186 if((t & VT_BTYPE) == VT_FLOAT) {
2194 func_type = &func_float_type;2187 func_type = &S->armgen_func_float_type;
2195 if(vtop->type.t & VT_UNSIGNED)2188 if(S->tccgen_vtop->type.t & VT_UNSIGNED)
2196 func=TOK___floatundisf;2189 func=TOK___floatundisf;
2197 else2190 else
2198 func=TOK___floatdisf;2191 func=TOK___floatdisf;
2199#if LDOUBLE_SIZE != 82192#if LDOUBLE_SIZE != 8
2200 } else if((t & VT_BTYPE) == VT_LDOUBLE) {2193 } else if((t & VT_BTYPE) == VT_LDOUBLE) {
2201 func_type = &func_ldouble_type;2194 func_type = &S->armgen_func_ldouble_type;
2202 if(vtop->type.t & VT_UNSIGNED)2195 if(S->tccgen_vtop->type.t & VT_UNSIGNED)
2203 func=TOK___floatundixf;2196 func=TOK___floatundixf;
2204 else2197 else
2205 func=TOK___floatdixf;2198 func=TOK___floatdixf;
@@ -2207,39 +2200,39 @@ ST_FUNC void gen_cvt_itof(int t) · 1 unmodified line
2207#else2200#else
2208 } else if((t & VT_BTYPE) == VT_DOUBLE || (t & VT_BTYPE) == VT_LDOUBLE) {2201 } else if((t & VT_BTYPE) == VT_DOUBLE || (t & VT_BTYPE) == VT_LDOUBLE) {
2209#endif2202#endif
2210 func_type = &func_double_type;2203 func_type = &S->armgen_func_double_type;
2211 if(vtop->type.t & VT_UNSIGNED)2204 if(S->tccgen_vtop->type.t & VT_UNSIGNED)
2212 func=TOK___floatundidf;2205 func=TOK___floatundidf;
2213 else2206 else
2214 func=TOK___floatdidf;2207 func=TOK___floatdidf;
2215 }2208 }
2216 if(func_type) {2209 if(func_type) {
2217 vpushsym(func_type, external_helper_sym(func));2210 vpushsym(S, func_type, external_helper_sym(S, func));
2218 vswap();2211 vswap(S);
2219 gfunc_call(1);2212 gfunc_call(S, 1);
2220 vpushi(0);2213 vpushi(S, 0);
2221 vtop->r=TREG_F0;2214 S->tccgen_vtop->r=TREG_F0;
2222 return;2215 return;
2223 }2216 }
2224 }2217 }
2225 tcc_error("unimplemented gen_cvt_itof %x!",vtop->type.t);2218 tcc_error(S, "unimplemented gen_cvt_itof %x!",S->tccgen_vtop->type.t);
2226}2219}
2227 2220
2228/* convert fp to int 't' type */2221/* convert fp to int 't' type */
2229void gen_cvt_ftoi(int t)2222void gen_cvt_ftoi(TCCState* S, int t)
2230{2223{
2231 uint32_t r, r2;2224 uint32_t r, r2;
2232 int u, func = 0;2225 int u, func = 0;
2233 u=t&VT_UNSIGNED;2226 u=t&VT_UNSIGNED;
2234 t&=VT_BTYPE;2227 t&=VT_BTYPE;
2235 r2=vtop->type.t & VT_BTYPE;2228 r2=S->tccgen_vtop->type.t & VT_BTYPE;
2236 if(t==VT_INT) {2229 if(t==VT_INT) {
2237#ifdef TCC_ARM_VFP2230#ifdef TCC_ARM_VFP
2238 r=vfpr(gv(RC_FLOAT));2231 r=vfpr(S, gv(S, RC_FLOAT));
2239 u=u?0:0x10000;2232 u=u?0:0x10000;
2240 o(0xEEBC0AC0|(r<<12)|r|T2CPR(r2)|u); /* ftoXizY */2233 o(S, 0xEEBC0AC0|(r<<12)|r|T2CPR(r2)|u); /* ftoXizY */
2241 r2=intr(vtop->r=get_reg(RC_INT));2234 r2=intr(S, S->tccgen_vtop->r=get_reg(S, RC_INT));
2242 o(0xEE100A10|(r<<16)|(r2<<12));2235 o(S, 0xEE100A10|(r<<16)|(r2<<12));
2243 return;2236 return;
2244#else2237#else
2245 if(u) {2238 if(u) {
@@ -2254,9 +2247,9 @@ void gen_cvt_ftoi(int t) · 8 unmodified lines
2254#endif2247#endif
2255 func=TOK___fixunsdfsi;2248 func=TOK___fixunsdfsi;
2256 } else {2249 } else {
2257 r=fpr(gv(RC_FLOAT));2250 r=fpr(S, gv(S, RC_FLOAT));
2258 r2=intr(vtop->r=get_reg(RC_INT));2251 r2=intr(S, S->tccgen_vtop->r=get_reg(S, RC_INT));
2259 o(0xEE100170|(r2<<12)|r);2252 o(S, 0xEE100170|(r2<<12)|r);
2260 return;2253 return;
2261 }2254 }
2262#endif2255#endif
@@ -2273,93 +2266,93 @@ void gen_cvt_ftoi(int t) · 10 unmodified lines
2273 func=TOK___fixdfdi;2266 func=TOK___fixdfdi;
2274 }2267 }
2275 if(func) {2268 if(func) {
2276 vpush_helper_func(func);2269 vpush_helper_func(S, func);
2277 vswap();2270 vswap(S);
2278 gfunc_call(1);2271 gfunc_call(S, 1);
2279 vpushi(0);2272 vpushi(S, 0);
2280 if(t == VT_LLONG)2273 if(t == VT_LLONG)
2281 vtop->r2 = REG_IRE2;2274 S->tccgen_vtop->r2 = REG_IRE2;
2282 vtop->r = REG_IRET;2275 S->tccgen_vtop->r = REG_IRET;
2283 return;2276 return;
2284 }2277 }
2285 tcc_error("unimplemented gen_cvt_ftoi!");2278 tcc_error(S, "unimplemented gen_cvt_ftoi!");
2286}2279}
2287 2280
2288/* convert from one floating point type to another */2281/* convert from one floating point type to another */
2289void gen_cvt_ftof(int t)2282void gen_cvt_ftof(TCCState* S, int t)
2290{2283{
2291#ifdef TCC_ARM_VFP2284#ifdef TCC_ARM_VFP
2292 if(((vtop->type.t & VT_BTYPE) == VT_FLOAT) != ((t & VT_BTYPE) == VT_FLOAT)) {2285 if(((S->tccgen_vtop->type.t & VT_BTYPE) == VT_FLOAT) != ((t & VT_BTYPE) == VT_FLOAT)) {
2293 uint32_t r = vfpr(gv(RC_FLOAT));2286 uint32_t r = vfpr(S, gv(S, RC_FLOAT));
2294 o(0xEEB70AC0|(r<<12)|r|T2CPR(vtop->type.t));2287 o(S, 0xEEB70AC0|(r<<12)|r|T2CPR(S->tccgen_vtop->type.t));
2295 }2288 }
2296#else2289#else
2297 /* all we have to do on i386 and FPA ARM is to put the float in a register */2290 /* all we have to do on i386 and FPA ARM is to put the float in a register */
2298 gv(RC_FLOAT);2291 gv(S, RC_FLOAT);
2299#endif2292#endif
2300}2293}
2301 2294
2302/* increment tcov counter */2295/* increment tcov counter */
2303ST_FUNC void gen_increment_tcov (SValue *sv)2296ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv)
2304{2297{
2305 int r1, r2;2298 int r1, r2;
2306 2299
2307 vpushv(sv);2300 vpushv(S, sv);
2308 vtop->r = r1 = get_reg(RC_INT);2301 S->tccgen_vtop->r = r1 = get_reg(S, RC_INT);
2309 r2 = get_reg(RC_INT);2302 r2 = get_reg(S, RC_INT);
2310 o(0xE59F0000 | (intr(r1)<<12)); // ldr r1,[pc]2303 o(S, 0xE59F0000 | (intr(S, r1)<<12)); // ldr r1,[pc]
2311 o(0xEA000000); // b $+42304 o(S, 0xEA000000); // b $+4
2312 greloc(cur_text_section, sv->sym, ind, R_ARM_REL32);2305 greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_ARM_REL32);
2313 o(-12);2306 o(S, -12);
2314 o(0xe080000f | (intr(r1)<<16) | (intr(r1)<<12)); // add r1,r1,pc2307 o(S, 0xe080000f | (intr(S, r1)<<16) | (intr(S, r1)<<12)); // add r1,r1,pc
2315 o(0xe5900000 | (intr(r1)<<16) | (intr(r2)<<12)); // ldr r2, [r1]2308 o(S, 0xe5900000 | (intr(S, r1)<<16) | (intr(S, r2)<<12)); // ldr r2, [r1]
2316 o(0xe2900001 | (intr(r2)<<16) | (intr(r2)<<12)); // adds r2, r2, #12309 o(S, 0xe2900001 | (intr(S, r2)<<16) | (intr(S, r2)<<12)); // adds r2, r2, #1
2317 o(0xe5800000 | (intr(r1)<<16) | (intr(r2)<<12)); // str r2, [r1]2310 o(S, 0xe5800000 | (intr(S, r1)<<16) | (intr(S, r2)<<12)); // str r2, [r1]
2318 o(0xe2800004 | (intr(r1)<<16) | (intr(r1)<<12)); // add r1, r1, #42311 o(S, 0xe2800004 | (intr(S, r1)<<16) | (intr(S, r1)<<12)); // add r1, r1, #4
2319 o(0xe5900000 | (intr(r1)<<16) | (intr(r2)<<12)); // ldr r2, [r1]2312 o(S, 0xe5900000 | (intr(S, r1)<<16) | (intr(S, r2)<<12)); // ldr r2, [r1]
2320 o(0xe2a00000 | (intr(r2)<<16) | (intr(r2)<<12)); // adc r2, r2, #02313 o(S, 0xe2a00000 | (intr(S, r2)<<16) | (intr(S, r2)<<12)); // adc r2, r2, #0
2321 o(0xe5800000 | (intr(r1)<<16) | (intr(r2)<<12)); // str r2, [r1]2314 o(S, 0xe5800000 | (intr(S, r1)<<16) | (intr(S, r2)<<12)); // str r2, [r1]
2322 vpop();2315 vpop(S);
2323}2316}
2324 2317
2325/* computed goto support */2318/* computed goto support */
2326void ggoto(void)2319void ggoto(TCCState* S)
2327{2320{
2328 gcall_or_jmp(1);2321 gcall_or_jmp(S, 1);
2329 vtop--;2322 S->tccgen_vtop--;
2330}2323}
2331 2324
2332/* Save the stack pointer onto the stack and return the location of its address */2325/* Save the stack pointer onto the stack and return the location of its address */
2333ST_FUNC void gen_vla_sp_save(int addr) {2326ST_FUNC void gen_vla_sp_save(TCCState* S, int addr) {
2334 SValue v;2327 SValue v;
2335 v.type.t = VT_PTR;2328 v.type.t = VT_PTR;
2336 v.r = VT_LOCAL | VT_LVAL;2329 v.r = VT_LOCAL | VT_LVAL;
2337 v.c.i = addr;2330 v.c.i = addr;
2338 store(TREG_SP, &v);2331 store(S, TREG_SP, &v);
2339}2332}
2340 2333
2341/* Restore the SP from a location on the stack */2334/* Restore the SP from a location on the stack */
2342ST_FUNC void gen_vla_sp_restore(int addr) {2335ST_FUNC void gen_vla_sp_restore(TCCState* S, int addr) {
2343 SValue v;2336 SValue v;
2344 v.type.t = VT_PTR;2337 v.type.t = VT_PTR;
2345 v.r = VT_LOCAL | VT_LVAL;2338 v.r = VT_LOCAL | VT_LVAL;
2346 v.c.i = addr;2339 v.c.i = addr;
2347 load(TREG_SP, &v);2340 load(S, TREG_SP, &v);
2348}2341}
2349 2342
2350/* Subtract from the stack pointer, and push the resulting value onto the stack */2343/* Subtract from the stack pointer, and push the resulting value onto the stack */
2351ST_FUNC void gen_vla_alloc(CType *type, int align) {2344ST_FUNC void gen_vla_alloc(TCCState* S, CType *type, int align) {
2352 int r;2345 int r;
2353#if defined(CONFIG_TCC_BCHECK)2346#if defined(CONFIG_TCC_BCHECK)
2354 if (tcc_state->do_bounds_check)2347 if (S->do_bounds_check)
2355 vpushv(vtop);2348 vpushv(S, S->tccgen_vtop);
2356#endif2349#endif
2357 r = intr(gv(RC_INT));2350 r = intr(S, gv(S, RC_INT));
2358#if defined(CONFIG_TCC_BCHECK)2351#if defined(CONFIG_TCC_BCHECK)
2359 if (tcc_state->do_bounds_check)2352 if (S->do_bounds_check)
2360 o(0xe2800001 | (r<<16)|(r<<12)); /* add r,r,#1 */2353 o(S, 0xe2800001 | (r<<16)|(r<<12)); /* add r,r,#1 */
2361#endif2354#endif
2362 o(0xE04D0000|(r<<12)|r); /* sub r, sp, r */2355 o(S, 0xE04D0000|(r<<12)|r); /* sub r, sp, r */
2363#ifdef TCC_ARM_EABI2356#ifdef TCC_ARM_EABI
2364 if (align < 8)2357 if (align < 8)
2365 align = 8;2358 align = 8;
@@ -2368,19 +2361,19 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) { · 2 unmodified lines
2368 align = 4;2361 align = 4;
2369#endif2362#endif
2370 if (align & (align - 1))2363 if (align & (align - 1))
2371 tcc_error("alignment is not a power of 2: %i", align);2364 tcc_error(S, "alignment is not a power of 2: %i", align);
2372 o(stuff_const(0xE3C0D000|(r<<16), align - 1)); /* bic sp, r, #align-1 */2365 o(S, stuff_const(0xE3C0D000|(r<<16), align - 1)); /* bic sp, r, #align-1 */
2373 vpop();2366 vpop(S);
2374#if defined(CONFIG_TCC_BCHECK)2367#if defined(CONFIG_TCC_BCHECK)
2375 if (tcc_state->do_bounds_check) {2368 if (S->do_bounds_check) {
2376 vpushi(0);2369 vpushi(S, 0);
2377 vtop->r = TREG_R0;2370 S->tccgen_vtop->r = TREG_R0;
2378 o(0xe1a0000d | (vtop->r << 12)); // mov r0,sp2371 o(S, 0xe1a0000d | (S->tccgen_vtop->r << 12)); // mov r0,sp
2379 vswap();2372 vswap(S);
2380 vpush_helper_func(TOK___bound_new_region);2373 vpush_helper_func(S, TOK___bound_new_region);
2381 vrott(3);2374 vrott(S, 3);
2382 gfunc_call(2);2375 gfunc_call(S, 2);
2383 func_bound_add_epilog = 1;2376 S->func_bound_add_epilog = 1;
2384 }2377 }
2385#endif2378#endif
2386}2379}
arm-link.c+32−32
@@ -107,9 +107,9 @@ int gotplt_entry_type (int reloc_type) · 106 unmodified lines
107}107}
108 108
109#ifndef TCC_TARGET_PE109#ifndef TCC_TARGET_PE
110ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)110ST_FUNC unsigned create_plt_entry(TCCState *S, unsigned got_offset, struct sym_attr *attr)
111{111{
112 Section *plt = s1->plt;112 Section *plt = S->plt;
113 uint8_t *p;113 uint8_t *p;
114 unsigned plt_offset;114 unsigned plt_offset;
115 115
@@ -119,7 +119,7 @@ ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_ · 3 unmodified lines
119 /* empty PLT: create PLT0 entry that push address of call site and119 /* empty PLT: create PLT0 entry that push address of call site and
120 jump to ld.so resolution routine (GOT + 8) */120 jump to ld.so resolution routine (GOT + 8) */
121 if (plt->data_offset == 0) {121 if (plt->data_offset == 0) {
122 p = section_ptr_add(plt, 20);122 p = section_ptr_add(S, plt, 20);
123 write32le(p, 0xe52de004); /* push {lr} */123 write32le(p, 0xe52de004); /* push {lr} */
124 write32le(p+4, 0xe59fe004); /* ldr lr, [pc, #4] */124 write32le(p+4, 0xe59fe004); /* ldr lr, [pc, #4] */
125 write32le(p+8, 0xe08fe00e); /* add lr, pc, lr */125 write32le(p+8, 0xe08fe00e); /* add lr, pc, lr */
@@ -129,11 +129,11 @@ ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_ · 3 unmodified lines
129 plt_offset = plt->data_offset;129 plt_offset = plt->data_offset;
130 130
131 if (attr->plt_thumb_stub) {131 if (attr->plt_thumb_stub) {
132 p = section_ptr_add(plt, 4);132 p = section_ptr_add(S, plt, 4);
133 write32le(p, 0x4778); /* bx pc */133 write32le(p, 0x4778); /* bx pc */
134 write32le(p+2, 0x46c0); /* nop */134 write32le(p+2, 0x46c0); /* nop */
135 }135 }
136 p = section_ptr_add(plt, 16);136 p = section_ptr_add(S, plt, 16);
137 /* save GOT offset for relocate_plt */137 /* save GOT offset for relocate_plt */
138 write32le(p + 4, got_offset);138 write32le(p + 4, got_offset);
139 return plt_offset;139 return plt_offset;
@@ -141,22 +141,22 @@ ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_ · 1 unmodified line
141 141
142/* relocate the PLT: compute addresses and offsets in the PLT now that final142/* relocate the PLT: compute addresses and offsets in the PLT now that final
143 address for PLT and GOT are known (see fill_program_header) */143 address for PLT and GOT are known (see fill_program_header) */
144ST_FUNC void relocate_plt(TCCState *s1)144ST_FUNC void relocate_plt(TCCState *S)
145{145{
146 uint8_t *p, *p_end;146 uint8_t *p, *p_end;
147 147
148 if (!s1->plt)148 if (!S->plt)
149 return;149 return;
150 150
151 p = s1->plt->data;151 p = S->plt->data;
152 p_end = p + s1->plt->data_offset;152 p_end = p + S->plt->data_offset;
153 153
154 if (p < p_end) {154 if (p < p_end) {
155 int x = s1->got->sh_addr - s1->plt->sh_addr - 12;155 int x = S->got->sh_addr - S->plt->sh_addr - 12;
156 write32le(s1->plt->data + 16, x - 4);156 write32le(S->plt->data + 16, x - 4);
157 p += 20;157 p += 20;
158 while (p < p_end) {158 while (p < p_end) {
159 unsigned off = x + read32le(p + 4) + (s1->plt->data - p) + 4;159 unsigned off = x + read32le(p + 4) + (S->plt->data - p) + 4;
160 if (read32le(p) == 0x46c04778) /* PLT Thumb stub present */160 if (read32le(p) == 0x46c04778) /* PLT Thumb stub present */
161 p += 4;161 p += 4;
162 write32le(p, 0xe28fc200 | ((off >> 28) & 0xf)); // add ip, pc, #0xN0000000162 write32le(p, 0xe28fc200 | ((off >> 28) & 0xf)); // add ip, pc, #0xN0000000
@@ -167,17 +167,17 @@ ST_FUNC void relocate_plt(TCCState *s1) · 4 unmodified lines
167 }167 }
168 }168 }
169 169
170 if (s1->plt->reloc) {170 if (S->plt->reloc) {
171 ElfW_Rel *rel;171 ElfW_Rel *rel;
172 p = s1->got->data;172 p = S->got->data;
173 for_each_elem(s1->plt->reloc, 0, rel, ElfW_Rel) {173 for_each_elem(S->plt->reloc, 0, rel, ElfW_Rel) {
174 write32le(p + rel->r_offset, s1->plt->sh_addr);174 write32le(p + rel->r_offset, S->plt->sh_addr);
175 }175 }
176 }176 }
177}177}
178#endif178#endif
179 179
180void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)180void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
181{181{
182 ElfW(Sym) *sym;182 ElfW(Sym) *sym;
183 int sym_index, esym_index;183 int sym_index, esym_index;
@@ -212,7 +212,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 28 unmodified lines
212 h = x & 2;212 h = x & 2;
213 th_ko = (x & 3) && (!blx_avail || !is_call);213 th_ko = (x & 3) && (!blx_avail || !is_call);
214 if (th_ko || x >= 0x2000000 || x < -0x2000000)214 if (th_ko || x >= 0x2000000 || x < -0x2000000)
215 tcc_error("can't relocate value at %x,%d",addr, type);215 tcc_error(S, "can't relocate value at %x,%d",addr, type);
216 x >>= 2;216 x >>= 2;
217 x &= 0xffffff;217 x &= 0xffffff;
218 /* Only reached if blx is avail and it is a call */218 /* Only reached if blx is avail and it is a call */
@@ -255,7 +255,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 36 unmodified lines
255 255
256 /* Relocation infos */256 /* Relocation infos */
257 to_thumb = val & 1;257 to_thumb = val & 1;
258 plt = s1->plt;258 plt = S->plt;
259 to_plt = (val >= plt->sh_addr) &&259 to_plt = (val >= plt->sh_addr) &&
260 (val < plt->sh_addr + plt->data_offset);260 (val < plt->sh_addr + plt->data_offset);
261 is_call = (type == R_ARM_THM_PC22);261 is_call = (type == R_ARM_THM_PC22);
@@ -267,10 +267,10 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 5 unmodified lines
267 Section *text;267 Section *text;
268 268
269 name = (char *) symtab_section->link->data + sym->st_name;269 name = (char *) symtab_section->link->data + sym->st_name;
270 text = s1->sections[sym->st_shndx];270 text = S->sections[sym->st_shndx];
271 /* Modify reloc to target a thumb stub to switch to ARM */271 /* Modify reloc to target a thumb stub to switch to ARM */
272 snprintf(buf, sizeof(buf), "%s_from_thumb", name);272 snprintf(buf, sizeof(buf), "%s_from_thumb", name);
273 index = put_elf_sym(symtab_section,273 index = put_elf_sym(S, symtab_section,
274 text->data_offset + 1,274 text->data_offset + 1,
275 sym->st_size, sym->st_info, 0,275 sym->st_size, sym->st_info, 0,
276 sym->st_shndx, buf);276 sym->st_shndx, buf);
@@ -281,7 +281,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 4 unmodified lines
281 put_elf_reloc(symtab_section, text,281 put_elf_reloc(symtab_section, text,
282 text->data_offset + 4, R_ARM_JUMP24,282 text->data_offset + 4, R_ARM_JUMP24,
283 sym_index);283 sym_index);
284 p = section_ptr_add(text, 8);284 p = section_ptr_add(S, text, 8);
285 write32le(p, 0x4778); /* bx pc */285 write32le(p, 0x4778); /* bx pc */
286 write32le(p+2, 0x46c0); /* nop */286 write32le(p+2, 0x46c0); /* nop */
287 write32le(p+4, 0xeafffffe); /* b $sym */287 write32le(p+4, 0xeafffffe); /* b $sym */
@@ -301,7 +301,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 13 unmodified lines
301 - instruction must be a call (bl) or a jump to PLT */301 - instruction must be a call (bl) or a jump to PLT */
302 if (!to_thumb || x >= 0x1000000 || x < -0x1000000)302 if (!to_thumb || x >= 0x1000000 || x < -0x1000000)
303 if (to_thumb || (val & 2) || (!is_call && !to_plt))303 if (to_thumb || (val & 2) || (!is_call && !to_plt))
304 tcc_error("can't relocate value at %x,%d",addr, type);304 tcc_error(S, "can't relocate value at %x,%d",addr, type);
305 305
306 /* Compute and store final offset */306 /* Compute and store final offset */
307 s = (x >> 24) & 1;307 s = (x >> 24) & 1;
@@ -372,14 +372,14 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 64 unmodified lines
372 x = (x * 2) / 2;372 x = (x * 2) / 2;
373 x += val - addr;373 x += val - addr;
374 if((x^(x>>1))&0x40000000)374 if((x^(x>>1))&0x40000000)
375 tcc_error("can't relocate value at %x,%d",addr, type);375 tcc_error(S, "can't relocate value at %x,%d",addr, type);
376 (*(int *)ptr) |= x & 0x7fffffff;376 (*(int *)ptr) |= x & 0x7fffffff;
377 }377 }
378 return;378 return;
379 case R_ARM_ABS32:379 case R_ARM_ABS32:
380 case R_ARM_TARGET1:380 case R_ARM_TARGET1:
381 if (s1->output_type == TCC_OUTPUT_DLL) {381 if (S->output_type == TCC_OUTPUT_DLL) {
382 esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;382 esym_index = get_sym_attr(S, sym_index, 0)->dyn_index;
383 qrel->r_offset = rel->r_offset;383 qrel->r_offset = rel->r_offset;
384 if (esym_index) {384 if (esym_index) {
385 qrel->r_info = ELFW(R_INFO)(esym_index, R_ARM_ABS32);385 qrel->r_info = ELFW(R_INFO)(esym_index, R_ARM_ABS32);
@@ -396,19 +396,19 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 10 unmodified lines
396 *(int *)ptr += val - addr;396 *(int *)ptr += val - addr;
397 return;397 return;
398 case R_ARM_GOTPC:398 case R_ARM_GOTPC:
399 *(int *)ptr += s1->got->sh_addr - addr;399 *(int *)ptr += S->got->sh_addr - addr;
400 return;400 return;
401 case R_ARM_GOTOFF:401 case R_ARM_GOTOFF:
402 *(int *)ptr += val - s1->got->sh_addr;402 *(int *)ptr += val - S->got->sh_addr;
403 return;403 return;
404 case R_ARM_GOT32:404 case R_ARM_GOT32:
405 /* we load the got offset */405 /* we load the got offset */
406 *(int *)ptr += get_sym_attr(s1, sym_index, 0)->got_offset;406 *(int *)ptr += get_sym_attr(S, sym_index, 0)->got_offset;
407 return;407 return;
408 case R_ARM_GOT_PREL:408 case R_ARM_GOT_PREL:
409 /* we load the pc relative got offset */409 /* we load the pc relative got offset */
410 *(int *)ptr += s1->got->sh_addr +410 *(int *)ptr += S->got->sh_addr +
411 get_sym_attr(s1, sym_index, 0)->got_offset -411 get_sym_attr(S, sym_index, 0)->got_offset -
412 addr;412 addr;
413 return;413 return;
414 case R_ARM_COPY:414 case R_ARM_COPY:
@@ -428,7 +428,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 13 unmodified lines
428 return;428 return;
429 case R_ARM_RELATIVE:429 case R_ARM_RELATIVE:
430#ifdef TCC_TARGET_PE430#ifdef TCC_TARGET_PE
431 add32le(ptr, val - s1->pe_imagebase);431 add32le(ptr, val - S->pe_imagebase);
432#endif432#endif
433 /* do nothing */433 /* do nothing */
434 return;434 return;
arm64-asm.c+13−13
@@ -9,9 +9,9 @@ · 8 unmodified lines
9#define CONFIG_TCC_ASM9#define CONFIG_TCC_ASM
10#define NB_ASM_REGS 1610#define NB_ASM_REGS 16
11 11
12ST_FUNC void g(int c);12ST_FUNC void g(TCCState* S, int c);
13ST_FUNC void gen_le16(int c);13ST_FUNC void gen_le16(TCCState* S, int c);
14ST_FUNC void gen_le32(int c);14ST_FUNC void gen_le32(TCCState* S, int c);
15 15
16/*************************************************************/16/*************************************************************/
17#else17#else
@@ -25,7 +25,7 @@ static void asm_error(void) · 7 unmodified lines
25}25}
26 26
27/* XXX: make it faster ? */27/* XXX: make it faster ? */
28ST_FUNC void g(int c)28ST_FUNC void g(TCCState* S, int c)
29{29{
30 int ind1;30 int ind1;
31 if (nocode_wanted)31 if (nocode_wanted)
@@ -37,24 +37,24 @@ ST_FUNC void g(int c) · 5 unmodified lines
37 ind = ind1;37 ind = ind1;
38}38}
39 39
40ST_FUNC void gen_le16 (int i)40ST_FUNC void gen_le16 (TCCState* S, int i)
41{41{
42 g(i);42 g(S, i);
43 g(i>>8);43 g(S, i>>8);
44}44}
45 45
46ST_FUNC void gen_le32 (int i)46ST_FUNC void gen_le32 (TCCState* S, int i)
47{47{
48 gen_le16(i);48 gen_le16(S, i);
49 gen_le16(i>>16);49 gen_le16(S, i>>16);
50}50}
51 51
52ST_FUNC void gen_expr32(ExprValue *pe)52ST_FUNC void gen_expr32(TCCState* S, ExprValue *pe)
53{53{
54 gen_le32(pe->v);54 gen_le32(S, pe->v);
55}55}
56 56
57ST_FUNC void asm_opcode(TCCState *s1, int opcode)57ST_FUNC void asm_opcode(TCCState *S, int opcode)
58{58{
59 asm_error();59 asm_error();
60}60}
arm64-gen.c+641−647
@@ -90,15 +90,9 @@ ST_DATA const int reg_classes[NB_REGS] = { · 89 unmodified lines
90 RC_FLOAT | RC_F(7)90 RC_FLOAT | RC_F(7)
91};91};
92 92
93#if defined(CONFIG_TCC_BCHECK)
94static addr_t func_bound_offset;
95static unsigned long func_bound_ind;
96ST_DATA int func_bound_add_epilog;
97#endif
98
99#define IS_FREG(x) ((x) >= TREG_F(0))93#define IS_FREG(x) ((x) >= TREG_F(0))
100 94
101static uint32_t intr(int r)95static uint32_t intr(TCCState *S, int r)
102{96{
103 assert(TREG_R(0) <= r && r <= TREG_R30);97 assert(TREG_R(0) <= r && r <= TREG_R30);
104 return r < TREG_R30 ? r : 30;98 return r < TREG_R30 ? r : 30;
@@ -111,15 +105,15 @@ static uint32_t fltr(int r) · 6 unmodified lines
111}105}
112 106
113// Add an instruction to text section:107// Add an instruction to text section:
114ST_FUNC void o(unsigned int c)108ST_FUNC void o(TCCState *S, unsigned int c)
115{109{
116 int ind1 = ind + 4;110 int ind1 = S->tccgen_ind + 4;
117 if (nocode_wanted)111 if (S->tccgen_nocode_wanted)
118 return;112 return;
119 if (ind1 > cur_text_section->data_allocated)113 if (ind1 > cur_text_section->data_allocated)
120 section_realloc(cur_text_section, ind1);114 section_realloc(S, cur_text_section, ind1);
121 write32le(cur_text_section->data + ind, c);115 write32le(cur_text_section->data + S->tccgen_ind, c);
122 ind = ind1;116 S->tccgen_ind = ind1;
123}117}
124 118
125static int arm64_encode_bimm64(uint64_t x)119static int arm64_encode_bimm64(uint64_t x)
@@ -208,11 +202,11 @@ static uint32_t arm64_movi(int r, uint64_t x) · 82 unmodified lines
208 return 0;202 return 0;
209}203}
210 204
211static void arm64_movimm(int r, uint64_t x)205static void arm64_movimm(TCCState *S, int r, uint64_t x)
212{206{
213 uint32_t i;207 uint32_t i;
214 if ((i = arm64_movi(r, x)))208 if ((i = arm64_movi(r, x)))
215 o(i); // a single MOV209 o(S, i); // a single MOV
216 else {210 else {
217 // MOVZ/MOVN and 1-3 MOVKs211 // MOVZ/MOVN and 1-3 MOVKs
218 int z = 0, m = 0;212 int z = 0, m = 0;
@@ -228,19 +222,19 @@ static void arm64_movimm(int r, uint64_t x) · 9 unmodified lines
228 }222 }
229 for (i = 0; i < 64; i += 16)223 for (i = 0; i < 64; i += 16)
230 if (x1 >> i & 0xffff) {224 if (x1 >> i & 0xffff) {
231 o(mov1 | r | (x1 >> i & 0xffff) << 5 | i << 17);225 o(S, mov1 | r | (x1 >> i & 0xffff) << 5 | i << 17);
232 // movz/movn x(r),#(*),lsl #(i)226 // movz/movn x(r),#(*),lsl #(i)
233 break;227 break;
234 }228 }
235 for (i += 16; i < 64; i += 16)229 for (i += 16; i < 64; i += 16)
236 if (x1 >> i & 0xffff)230 if (x1 >> i & 0xffff)
237 o(0xf2800000 | r | (x >> i & 0xffff) << 5 | i << 17);231 o(S, 0xf2800000 | r | (x >> i & 0xffff) << 5 | i << 17);
238 // movk x(r),#(*),lsl #(i)232 // movk x(r),#(*),lsl #(i)
239 }233 }
240}234}
241 235
242// Patch all branches in list pointed to by t to branch to a:236// Patch all branches in list pointed to by t to branch to a:
243ST_FUNC void gsym_addr(int t_, int a_)237ST_FUNC void gsym_addr(TCCState *S, int t_, int a_)
244{238{
245 uint32_t t = t_;239 uint32_t t = t_;
246 uint32_t a = a_;240 uint32_t a = a_;
@@ -248,7 +242,7 @@ ST_FUNC void gsym_addr(int t_, int a_) · 1 unmodified line
248 unsigned char *ptr = cur_text_section->data + t;242 unsigned char *ptr = cur_text_section->data + t;
249 uint32_t next = read32le(ptr);243 uint32_t next = read32le(ptr);
250 if (a - t + 0x8000000 >= 0x10000000)244 if (a - t + 0x8000000 >= 0x10000000)
251 tcc_error("branch out of range");245 tcc_error(S, "branch out of range");
252 write32le(ptr, (a - t == 4 ? 0xd503201f : // nop246 write32le(ptr, (a - t == 4 ? 0xd503201f : // nop
253 0x14000000 | ((a - t) >> 2 & 0x3ffffff))); // b247 0x14000000 | ((a - t) >> 2 & 0x3ffffff))); // b
254 t = next;248 t = next;
@@ -278,17 +272,17 @@ static int arm64_type_size(int t) · 23 unmodified lines
278 return 0;272 return 0;
279}273}
280 274
281static void arm64_spoff(int reg, uint64_t off)275static void arm64_spoff(TCCState *S, int reg, uint64_t off)
282{276{
283 uint32_t sub = off >> 63;277 uint32_t sub = off >> 63;
284 if (sub)278 if (sub)
285 off = -off;279 off = -off;
286 if (off < 4096)280 if (off < 4096)
287 o(0x910003e0 | sub << 30 | reg | off << 10);281 o(S, 0x910003e0 | sub << 30 | reg | off << 10);
288 // (add|sub) x(reg),sp,#(off)282 // (add|sub) x(reg),sp,#(off)
289 else {283 else {
290 arm64_movimm(30, off); // use x30 for offset284 arm64_movimm(S, 30, off); // use x30 for offset
291 o(0x8b3e63e0 | sub << 30 | reg); // (add|sub) x(reg),sp,x30285 o(S, 0x8b3e63e0 | sub << 30 | reg); // (add|sub) x(reg),sp,x30
292 }286 }
293}287}
294 288
@@ -309,41 +303,41 @@ static uint64_t arm64_check_offset(int invert, int sz_, uint64_t off) · 14 unmodified lines
309 return invert ? 0ul : off;303 return invert ? 0ul : off;
310}304}
311 305
312static void arm64_ldrx(int sg, int sz_, int dst, int bas, uint64_t off)306static void arm64_ldrx(TCCState *S, int sg, int sz_, int dst, int bas, uint64_t off)
313{307{
314 uint32_t sz = sz_;308 uint32_t sz = sz_;
315 if (sz >= 2)309 if (sz >= 2)
316 sg = 0;310 sg = 0;
317 if (!(off & ~((uint32_t)0xfff << sz)))311 if (!(off & ~((uint32_t)0xfff << sz)))
318 o(0x39400000 | dst | bas << 5 | off << (10 - sz) |312 o(S, 0x39400000 | dst | bas << 5 | off << (10 - sz) |
319 (uint32_t)!!sg << 23 | sz << 30); // ldr(*) x(dst),[x(bas),#(off)]313 (uint32_t)!!sg << 23 | sz << 30); // ldr(*) x(dst),[x(bas),#(off)]
320 else if (off < 256 || -off <= 256)314 else if (off < 256 || -off <= 256)
321 o(0x38400000 | dst | bas << 5 | (off & 511) << 12 |315 o(S, 0x38400000 | dst | bas << 5 | (off & 511) << 12 |
322 (uint32_t)!!sg << 23 | sz << 30); // ldur(*) x(dst),[x(bas),#(off)]316 (uint32_t)!!sg << 23 | sz << 30); // ldur(*) x(dst),[x(bas),#(off)]
323 else {317 else {
324 arm64_movimm(30, off); // use x30 for offset318 arm64_movimm(S, 30, off); // use x30 for offset
325 o(0x38206800 | dst | bas << 5 | (uint32_t)30 << 16 |319 o(S, 0x38206800 | dst | bas << 5 | (uint32_t)30 << 16 |
326 (uint32_t)(!!sg + 1) << 22 | sz << 30); // ldr(*) x(dst),[x(bas),x30]320 (uint32_t)(!!sg + 1) << 22 | sz << 30); // ldr(*) x(dst),[x(bas),x30]
327 }321 }
328}322}
329 323
330static void arm64_ldrv(int sz_, int dst, int bas, uint64_t off)324static void arm64_ldrv(TCCState *S, int sz_, int dst, int bas, uint64_t off)
331{325{
332 uint32_t sz = sz_;326 uint32_t sz = sz_;
333 if (!(off & ~((uint32_t)0xfff << sz)))327 if (!(off & ~((uint32_t)0xfff << sz)))
334 o(0x3d400000 | dst | bas << 5 | off << (10 - sz) |328 o(S, 0x3d400000 | dst | bas << 5 | off << (10 - sz) |
335 (sz & 4) << 21 | (sz & 3) << 30); // ldr (s|d|q)(dst),[x(bas),#(off)]329 (sz & 4) << 21 | (sz & 3) << 30); // ldr (s|d|q)(dst),[x(bas),#(off)]
336 else if (off < 256 || -off <= 256)330 else if (off < 256 || -off <= 256)
337 o(0x3c400000 | dst | bas << 5 | (off & 511) << 12 |331 o(S, 0x3c400000 | dst | bas << 5 | (off & 511) << 12 |
338 (sz & 4) << 21 | (sz & 3) << 30); // ldur (s|d|q)(dst),[x(bas),#(off)]332 (sz & 4) << 21 | (sz & 3) << 30); // ldur (s|d|q)(dst),[x(bas),#(off)]
339 else {333 else {
340 arm64_movimm(30, off); // use x30 for offset334 arm64_movimm(S, 30, off); // use x30 for offset
341 o(0x3c606800 | dst | bas << 5 | (uint32_t)30 << 16 |335 o(S, 0x3c606800 | dst | bas << 5 | (uint32_t)30 << 16 |
342 sz << 30 | (sz & 4) << 21); // ldr (s|d|q)(dst),[x(bas),x30]336 sz << 30 | (sz & 4) << 21); // ldr (s|d|q)(dst),[x(bas),x30]
343 }337 }
344}338}
345 339
346static void arm64_ldrs(int reg_, int size)340static void arm64_ldrs(TCCState *S, int reg_, int size)
347{341{
348 uint32_t reg = reg_;342 uint32_t reg = reg_;
349 // Use x30 for intermediate value in some cases.343 // Use x30 for intermediate value in some cases.
@@ -353,138 +347,138 @@ static void arm64_ldrs(int reg_, int size) · 3 unmodified lines
353 /* Can happen with zero size structs */347 /* Can happen with zero size structs */
354 break;348 break;
355 case 1:349 case 1:
356 arm64_ldrx(0, 0, reg, reg, 0);350 arm64_ldrx(S, 0, 0, reg, reg, 0);
357 break;351 break;
358 case 2:352 case 2:
359 arm64_ldrx(0, 1, reg, reg, 0);353 arm64_ldrx(S, 0, 1, reg, reg, 0);
360 break;354 break;
361 case 3:355 case 3:
362 arm64_ldrx(0, 1, 30, reg, 0);356 arm64_ldrx(S, 0, 1, 30, reg, 0);
363 arm64_ldrx(0, 0, reg, reg, 2);357 arm64_ldrx(S, 0, 0, reg, reg, 2);
364 o(0x2a0043c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #16358 o(S, 0x2a0043c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #16
365 break;359 break;
366 case 4:360 case 4:
367 arm64_ldrx(0, 2, reg, reg, 0);361 arm64_ldrx(S, 0, 2, reg, reg, 0);
368 break;362 break;
369 case 5:363 case 5:
370 arm64_ldrx(0, 2, 30, reg, 0);364 arm64_ldrx(S, 0, 2, 30, reg, 0);
371 arm64_ldrx(0, 0, reg, reg, 4);365 arm64_ldrx(S, 0, 0, reg, reg, 4);
372 o(0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32366 o(S, 0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32
373 break;367 break;
374 case 6:368 case 6:
375 arm64_ldrx(0, 2, 30, reg, 0);369 arm64_ldrx(S, 0, 2, 30, reg, 0);
376 arm64_ldrx(0, 1, reg, reg, 4);370 arm64_ldrx(S, 0, 1, reg, reg, 4);
377 o(0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32371 o(S, 0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32
378 break;372 break;
379 case 7:373 case 7:
380 arm64_ldrx(0, 2, 30, reg, 0);374 arm64_ldrx(S, 0, 2, 30, reg, 0);
381 arm64_ldrx(0, 2, reg, reg, 3);375 arm64_ldrx(S, 0, 2, reg, reg, 3);
382 o(0x53087c00 | reg | reg << 5); // lsr w(reg), w(reg), #8376 o(S, 0x53087c00 | reg | reg << 5); // lsr w(reg), w(reg), #8
383 o(0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32377 o(S, 0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32
384 break;378 break;
385 case 8:379 case 8:
386 arm64_ldrx(0, 3, reg, reg, 0);380 arm64_ldrx(S, 0, 3, reg, reg, 0);
387 break;381 break;
388 case 9:382 case 9:
389 arm64_ldrx(0, 0, reg + 1, reg, 8);383 arm64_ldrx(S, 0, 0, reg + 1, reg, 8);
390 arm64_ldrx(0, 3, reg, reg, 0);384 arm64_ldrx(S, 0, 3, reg, reg, 0);
391 break;385 break;
392 case 10:386 case 10:
393 arm64_ldrx(0, 1, reg + 1, reg, 8);387 arm64_ldrx(S, 0, 1, reg + 1, reg, 8);
394 arm64_ldrx(0, 3, reg, reg, 0);388 arm64_ldrx(S, 0, 3, reg, reg, 0);
395 break;389 break;
396 case 11:390 case 11:
397 arm64_ldrx(0, 2, reg + 1, reg, 7);391 arm64_ldrx(S, 0, 2, reg + 1, reg, 7);
398 o(0x53087c00 | (reg+1) | (reg+1) << 5); // lsr w(reg+1), w(reg+1), #8392 o(S, 0x53087c00 | (reg+1) | (reg+1) << 5); // lsr w(reg+1), w(reg+1), #8
399 arm64_ldrx(0, 3, reg, reg, 0);393 arm64_ldrx(S, 0, 3, reg, reg, 0);
400 break;394 break;
401 case 12:395 case 12:
402 arm64_ldrx(0, 2, reg + 1, reg, 8);396 arm64_ldrx(S, 0, 2, reg + 1, reg, 8);
403 arm64_ldrx(0, 3, reg, reg, 0);397 arm64_ldrx(S, 0, 3, reg, reg, 0);
404 break;398 break;
405 case 13:399 case 13:
406 arm64_ldrx(0, 3, reg + 1, reg, 5);400 arm64_ldrx(S, 0, 3, reg + 1, reg, 5);
407 o(0xd358fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #24401 o(S, 0xd358fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #24
408 arm64_ldrx(0, 3, reg, reg, 0);402 arm64_ldrx(S, 0, 3, reg, reg, 0);
409 break;403 break;
410 case 14:404 case 14:
411 arm64_ldrx(0, 3, reg + 1, reg, 6);405 arm64_ldrx(S, 0, 3, reg + 1, reg, 6);
412 o(0xd350fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #16406 o(S, 0xd350fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #16
413 arm64_ldrx(0, 3, reg, reg, 0);407 arm64_ldrx(S, 0, 3, reg, reg, 0);
414 break;408 break;
415 case 15:409 case 15:
416 arm64_ldrx(0, 3, reg + 1, reg, 7);410 arm64_ldrx(S, 0, 3, reg + 1, reg, 7);
417 o(0xd348fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #8411 o(S, 0xd348fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #8
418 arm64_ldrx(0, 3, reg, reg, 0);412 arm64_ldrx(S, 0, 3, reg, reg, 0);
419 break;413 break;
420 case 16:414 case 16:
421 o(0xa9400000 | reg | (reg+1) << 10 | reg << 5);415 o(S, 0xa9400000 | reg | (reg+1) << 10 | reg << 5);
422 // ldp x(reg),x(reg+1),[x(reg)]416 // ldp x(reg),x(reg+1),[x(reg)]
423 break;417 break;
424 }418 }
425}419}
426 420
427static void arm64_strx(int sz_, int dst, int bas, uint64_t off)421static void arm64_strx(TCCState *S, int sz_, int dst, int bas, uint64_t off)
428{422{
429 uint32_t sz = sz_;423 uint32_t sz = sz_;
430 if (!(off & ~((uint32_t)0xfff << sz)))424 if (!(off & ~((uint32_t)0xfff << sz)))
431 o(0x39000000 | dst | bas << 5 | off << (10 - sz) | sz << 30);425 o(S, 0x39000000 | dst | bas << 5 | off << (10 - sz) | sz << 30);
432 // str(*) x(dst),[x(bas],#(off)]426 // str(*) x(dst),[x(bas],#(off)]
433 else if (off < 256 || -off <= 256)427 else if (off < 256 || -off <= 256)
434 o(0x38000000 | dst | bas << 5 | (off & 511) << 12 | sz << 30);428 o(S, 0x38000000 | dst | bas << 5 | (off & 511) << 12 | sz << 30);
435 // stur(*) x(dst),[x(bas],#(off)]429 // stur(*) x(dst),[x(bas],#(off)]
436 else {430 else {
437 arm64_movimm(30, off); // use x30 for offset431 arm64_movimm(S, 30, off); // use x30 for offset
438 o(0x38206800 | dst | bas << 5 | (uint32_t)30 << 16 | sz << 30);432 o(S, 0x38206800 | dst | bas << 5 | (uint32_t)30 << 16 | sz << 30);
439 // str(*) x(dst),[x(bas),x30]433 // str(*) x(dst),[x(bas),x30]
440 }434 }
441}435}
442 436
443static void arm64_strv(int sz_, int dst, int bas, uint64_t off)437static void arm64_strv(TCCState *S, int sz_, int dst, int bas, uint64_t off)
444{438{
445 uint32_t sz = sz_;439 uint32_t sz = sz_;
446 if (!(off & ~((uint32_t)0xfff << sz)))440 if (!(off & ~((uint32_t)0xfff << sz)))
447 o(0x3d000000 | dst | bas << 5 | off << (10 - sz) |441 o(S, 0x3d000000 | dst | bas << 5 | off << (10 - sz) |
448 (sz & 4) << 21 | (sz & 3) << 30); // str (s|d|q)(dst),[x(bas),#(off)]442 (sz & 4) << 21 | (sz & 3) << 30); // str (s|d|q)(dst),[x(bas),#(off)]
449 else if (off < 256 || -off <= 256)443 else if (off < 256 || -off <= 256)
450 o(0x3c000000 | dst | bas << 5 | (off & 511) << 12 |444 o(S, 0x3c000000 | dst | bas << 5 | (off & 511) << 12 |
451 (sz & 4) << 21 | (sz & 3) << 30); // stur (s|d|q)(dst),[x(bas),#(off)]445 (sz & 4) << 21 | (sz & 3) << 30); // stur (s|d|q)(dst),[x(bas),#(off)]
452 else {446 else {
453 arm64_movimm(30, off); // use x30 for offset447 arm64_movimm(S, 30, off); // use x30 for offset
454 o(0x3c206800 | dst | bas << 5 | (uint32_t)30 << 16 |448 o(S, 0x3c206800 | dst | bas << 5 | (uint32_t)30 << 16 |
455 sz << 30 | (sz & 4) << 21); // str (s|d|q)(dst),[x(bas),x30]449 sz << 30 | (sz & 4) << 21); // str (s|d|q)(dst),[x(bas),x30]
456 }450 }
457}451}
458 452
459static void arm64_sym(int r, Sym *sym, unsigned long addend)453static void arm64_sym(TCCState *S, int r, Sym *sym, unsigned long addend)
460{454{
461 greloca(cur_text_section, sym, ind, R_AARCH64_ADR_GOT_PAGE, 0);455 greloca(S, cur_text_section, sym, S->tccgen_ind, R_AARCH64_ADR_GOT_PAGE, 0);
462 o(0x90000000 | r); // adrp xr, #sym456 o(S, 0x90000000 | r); // adrp xr, #sym
463 greloca(cur_text_section, sym, ind, R_AARCH64_LD64_GOT_LO12_NC, 0);457 greloca(S, cur_text_section, sym, S->tccgen_ind, R_AARCH64_LD64_GOT_LO12_NC, 0);
464 o(0xf9400000 | r | (r << 5)); // ld xr,[xr, #sym]458 o(S, 0xf9400000 | r | (r << 5)); // ld xr,[xr, #sym]
465 if (addend) {459 if (addend) {
466 // add xr, xr, #addend460 // add xr, xr, #addend
467 if (addend & 0xffful)461 if (addend & 0xffful)
468 o(0x91000000 | r | r << 5 | (addend & 0xfff) << 10);462 o(S, 0x91000000 | r | r << 5 | (addend & 0xfff) << 10);
469 if (addend > 0xffful) {463 if (addend > 0xffful) {
470 // add xr, xr, #addend, lsl #12464 // add xr, xr, #addend, lsl #12
471 if (addend & 0xfff000ul)465 if (addend & 0xfff000ul)
472 o(0x91400000 | r | r << 5 | ((addend >> 12) & 0xfff) << 10);466 o(S, 0x91400000 | r | r << 5 | ((addend >> 12) & 0xfff) << 10);
473 if (addend > 0xfffffful) {467 if (addend > 0xfffffful) {
474 /* very unlikely */468 /* very unlikely */
475 int t = r ? 0 : 1;469 int t = r ? 0 : 1;
476 o(0xf81f0fe0 | t); /* str xt, [sp, #-16]! */470 o(S, 0xf81f0fe0 | t); /* str xt, [sp, #-16]! */
477 arm64_movimm(t, addend & ~0xfffffful); // use xt for addent471 arm64_movimm(S, t, addend & ~0xfffffful); // use xt for addent
478 o(0x91000000 | r | (t << 5)); /* add xr, xt, #0 */472 o(S, 0x91000000 | r | (t << 5)); /* add xr, xt, #0 */
479 o(0xf84107e0 | t); /* ldr xt, [sp], #16 */473 o(S, 0xf84107e0 | t); /* ldr xt, [sp], #16 */
480 }474 }
481 }475 }
482 }476 }
483}477}
484 478
485static void arm64_load_cmp(int r, SValue *sv);479static void arm64_load_cmp(TCCState *S, int r, SValue *sv);
486 480
487ST_FUNC void load(int r, SValue *sv)481ST_FUNC void load(TCCState *S, int r, SValue *sv)
488{482{
489 int svtt = sv->type.t;483 int svtt = sv->type.t;
490 int svr = sv->r & ~VT_BOUNDED;484 int svr = sv->r & ~VT_BOUNDED;
@@ -494,24 +488,24 @@ ST_FUNC void load(int r, SValue *sv) · 3 unmodified lines
494 488
495 if (svr == (VT_LOCAL | VT_LVAL)) {489 if (svr == (VT_LOCAL | VT_LVAL)) {
496 if (IS_FREG(r))490 if (IS_FREG(r))
497 arm64_ldrv(arm64_type_size(svtt), fltr(r), 29, svcul);491 arm64_ldrv(S, arm64_type_size(svtt), fltr(r), 29, svcul);
498 else492 else
499 arm64_ldrx(!(svtt & VT_UNSIGNED), arm64_type_size(svtt),493 arm64_ldrx(S, !(svtt & VT_UNSIGNED), arm64_type_size(svtt),
500 intr(r), 29, svcul);494 intr(S, r), 29, svcul);
501 return;495 return;
502 }496 }
503 497
504 if (svr == (VT_CONST | VT_LVAL)) {498 if (svr == (VT_CONST | VT_LVAL)) {
505 if (sv->sym)499 if (sv->sym)
506 arm64_sym(30, sv->sym, // use x30 for address500 arm64_sym(S, 30, sv->sym, // use x30 for address
507 arm64_check_offset(0, arm64_type_size(svtt), sv->c.i));501 arm64_check_offset(0, arm64_type_size(svtt), sv->c.i));
508 else502 else
509 arm64_movimm (30, sv->c.i);503 arm64_movimm (S, 30, sv->c.i);
510 if (IS_FREG(r))504 if (IS_FREG(r))
511 arm64_ldrv(arm64_type_size(svtt), fltr(r), 30,505 arm64_ldrv(S, arm64_type_size(svtt), fltr(r), 30,
512 arm64_check_offset(1, arm64_type_size(svtt), sv->c.i));506 arm64_check_offset(1, arm64_type_size(svtt), sv->c.i));
513 else507 else
514 arm64_ldrx(!(svtt&VT_UNSIGNED), arm64_type_size(svtt), intr(r), 30,508 arm64_ldrx(S, !(svtt&VT_UNSIGNED), arm64_type_size(svtt), intr(S, r), 30,
515 arm64_check_offset(1, arm64_type_size(svtt), sv->c.i));509 arm64_check_offset(1, arm64_type_size(svtt), sv->c.i));
516 return;510 return;
517 }511 }
@@ -519,34 +513,34 @@ ST_FUNC void load(int r, SValue *sv) · 1 unmodified line
519 if ((svr & ~VT_VALMASK) == VT_LVAL && svrv < VT_CONST) {513 if ((svr & ~VT_VALMASK) == VT_LVAL && svrv < VT_CONST) {
520 if ((svtt & VT_BTYPE) != VT_VOID) {514 if ((svtt & VT_BTYPE) != VT_VOID) {
521 if (IS_FREG(r))515 if (IS_FREG(r))
522 arm64_ldrv(arm64_type_size(svtt), fltr(r), intr(svrv), 0);516 arm64_ldrv(S, arm64_type_size(svtt), fltr(r), intr(S, svrv), 0);
523 else517 else
524 arm64_ldrx(!(svtt & VT_UNSIGNED), arm64_type_size(svtt),518 arm64_ldrx(S, !(svtt & VT_UNSIGNED), arm64_type_size(svtt),
525 intr(r), intr(svrv), 0);519 intr(S, r), intr(S, svrv), 0);
526 }520 }
527 return;521 return;
528 }522 }
529 523
530 if (svr == (VT_CONST | VT_LVAL | VT_SYM)) {524 if (svr == (VT_CONST | VT_LVAL | VT_SYM)) {
531 arm64_sym(30, sv->sym, // use x30 for address525 arm64_sym(S, 30, sv->sym, // use x30 for address
532 arm64_check_offset(0, arm64_type_size(svtt), svcul));526 arm64_check_offset(0, arm64_type_size(svtt), svcul));
533 if (IS_FREG(r))527 if (IS_FREG(r))
534 arm64_ldrv(arm64_type_size(svtt), fltr(r), 30,528 arm64_ldrv(S, arm64_type_size(svtt), fltr(r), 30,
535 arm64_check_offset(1, arm64_type_size(svtt), svcul));529 arm64_check_offset(1, arm64_type_size(svtt), svcul));
536 else530 else
537 arm64_ldrx(!(svtt&VT_UNSIGNED), arm64_type_size(svtt), intr(r), 30,531 arm64_ldrx(S, !(svtt&VT_UNSIGNED), arm64_type_size(svtt), intr(S, r), 30,
538 arm64_check_offset(1, arm64_type_size(svtt), svcul));532 arm64_check_offset(1, arm64_type_size(svtt), svcul));
539 return;533 return;
540 }534 }
541 535
542 if (svr == (VT_CONST | VT_SYM)) {536 if (svr == (VT_CONST | VT_SYM)) {
543 arm64_sym(intr(r), sv->sym, svcul);537 arm64_sym(S, intr(S, r), sv->sym, svcul);
544 return;538 return;
545 }539 }
546 540
547 if (svr == VT_CONST) {541 if (svr == VT_CONST) {
548 if ((svtt & VT_BTYPE) != VT_VOID)542 if ((svtt & VT_BTYPE) != VT_VOID)
549 arm64_movimm(intr(r), arm64_type_size(svtt) == 3 ?543 arm64_movimm(S, intr(S, r), arm64_type_size(svtt) == 3 ?
550 sv->c.i : (uint32_t)svcul);544 sv->c.i : (uint32_t)svcul);
551 return;545 return;
552 }546 }
@@ -554,12 +548,12 @@ ST_FUNC void load(int r, SValue *sv) · 1 unmodified line
554 if (svr < VT_CONST) {548 if (svr < VT_CONST) {
555 if (IS_FREG(r) && IS_FREG(svr))549 if (IS_FREG(r) && IS_FREG(svr))
556 if (svtt == VT_LDOUBLE)550 if (svtt == VT_LDOUBLE)
557 o(0x4ea01c00 | fltr(r) | fltr(svr) << 5);551 o(S, 0x4ea01c00 | fltr(r) | fltr(svr) << 5);
558 // mov v(r).16b,v(svr).16b552 // mov v(r).16b,v(svr).16b
559 else553 else
560 o(0x1e604000 | fltr(r) | fltr(svr) << 5); // fmov d(r),d(svr)554 o(S, 0x1e604000 | fltr(r) | fltr(svr) << 5); // fmov d(r),d(svr)
561 else if (!IS_FREG(r) && !IS_FREG(svr))555 else if (!IS_FREG(r) && !IS_FREG(svr))
562 o(0xaa0003e0 | intr(r) | intr(svr) << 16); // mov x(r),x(svr)556 o(S, 0xaa0003e0 | intr(S, r) | intr(S, svr) << 16); // mov x(r),x(svr)
563 else557 else
564 assert(0);558 assert(0);
565 return;559 return;
@@ -567,35 +561,35 @@ ST_FUNC void load(int r, SValue *sv) · 1 unmodified line
567 561
568 if (svr == VT_LOCAL) {562 if (svr == VT_LOCAL) {
569 if (-svcul < 0x1000)563 if (-svcul < 0x1000)
570 o(0xd10003a0 | intr(r) | -svcul << 10); // sub x(r),x29,#...564 o(S, 0xd10003a0 | intr(S, r) | -svcul << 10); // sub x(r),x29,#...
571 else {565 else {
572 arm64_movimm(30, -svcul); // use x30 for offset566 arm64_movimm(S, 30, -svcul); // use x30 for offset
573 o(0xcb0003a0 | intr(r) | (uint32_t)30 << 16); // sub x(r),x29,x30567 o(S, 0xcb0003a0 | intr(S, r) | (uint32_t)30 << 16); // sub x(r),x29,x30
574 }568 }
575 return;569 return;
576 }570 }
577 571
578 if (svr == VT_JMP || svr == VT_JMPI) {572 if (svr == VT_JMP || svr == VT_JMPI) {
579 int t = (svr == VT_JMPI);573 int t = (svr == VT_JMPI);
580 arm64_movimm(intr(r), t);574 arm64_movimm(S, intr(S, r), t);
581 o(0x14000002); // b .+8575 o(S, 0x14000002); // b .+8
582 gsym(svcul);576 gsym(S, svcul);
583 arm64_movimm(intr(r), t ^ 1);577 arm64_movimm(S, intr(S, r), t ^ 1);
584 return;578 return;
585 }579 }
586 580
587 if (svr == (VT_LLOCAL | VT_LVAL)) {581 if (svr == (VT_LLOCAL | VT_LVAL)) {
588 arm64_ldrx(0, 3, 30, 29, svcul); // use x30 for offset582 arm64_ldrx(S, 0, 3, 30, 29, svcul); // use x30 for offset
589 if (IS_FREG(r))583 if (IS_FREG(r))
590 arm64_ldrv(arm64_type_size(svtt), fltr(r), 30, 0);584 arm64_ldrv(S, arm64_type_size(svtt), fltr(r), 30, 0);
591 else585 else
592 arm64_ldrx(!(svtt & VT_UNSIGNED), arm64_type_size(svtt),586 arm64_ldrx(S, !(svtt & VT_UNSIGNED), arm64_type_size(svtt),
593 intr(r), 30, 0);587 intr(S, r), 30, 0);
594 return;588 return;
595 }589 }
596 590
597 if (svr == VT_CMP) {591 if (svr == VT_CMP) {
598 arm64_load_cmp(r, sv);592 arm64_load_cmp(S, r, sv);
599 return;593 return;
600 }594 }
601 595
@@ -603,7 +597,7 @@ ST_FUNC void load(int r, SValue *sv) · 1 unmodified line
603 assert(0);597 assert(0);
604}598}
605 599
606ST_FUNC void store(int r, SValue *sv)600ST_FUNC void store(TCCState *S, int r, SValue *sv)
607{601{
608 int svtt = sv->type.t;602 int svtt = sv->type.t;
609 int svr = sv->r & ~VT_BOUNDED;603 int svr = sv->r & ~VT_BOUNDED;
@@ -613,43 +607,43 @@ ST_FUNC void store(int r, SValue *sv) · 3 unmodified lines
613 607
614 if (svr == (VT_LOCAL | VT_LVAL)) {608 if (svr == (VT_LOCAL | VT_LVAL)) {
615 if (IS_FREG(r))609 if (IS_FREG(r))
616 arm64_strv(arm64_type_size(svtt), fltr(r), 29, svcul);610 arm64_strv(S, arm64_type_size(svtt), fltr(r), 29, svcul);
617 else611 else
618 arm64_strx(arm64_type_size(svtt), intr(r), 29, svcul);612 arm64_strx(S, arm64_type_size(svtt), intr(S, r), 29, svcul);
619 return;613 return;
620 }614 }
621 615
622 if (svr == (VT_CONST | VT_LVAL)) {616 if (svr == (VT_CONST | VT_LVAL)) {
623 if (sv->sym)617 if (sv->sym)
624 arm64_sym(30, sv->sym, // use x30 for address618 arm64_sym(S, 30, sv->sym, // use x30 for address
625 arm64_check_offset(0, arm64_type_size(svtt), sv->c.i));619 arm64_check_offset(0, arm64_type_size(svtt), sv->c.i));
626 else620 else
627 arm64_movimm (30, sv->c.i);621 arm64_movimm(S, 30, sv->c.i);
628 if (IS_FREG(r))622 if (IS_FREG(r))
629 arm64_strv(arm64_type_size(svtt), fltr(r), 30,623 arm64_strv(S, arm64_type_size(svtt), fltr(r), 30,
630 arm64_check_offset(1, arm64_type_size(svtt), sv->c.i));624 arm64_check_offset(1, arm64_type_size(svtt), sv->c.i));
631 else625 else
632 arm64_strx(arm64_type_size(svtt), intr(r), 30,626 arm64_strx(S, arm64_type_size(svtt), intr(S, r), 30,
633 arm64_check_offset(1, arm64_type_size(svtt), sv->c.i));627 arm64_check_offset(1, arm64_type_size(svtt), sv->c.i));
634 return;628 return;
635 }629 }
636 630
637 if ((svr & ~VT_VALMASK) == VT_LVAL && svrv < VT_CONST) {631 if ((svr & ~VT_VALMASK) == VT_LVAL && svrv < VT_CONST) {
638 if (IS_FREG(r))632 if (IS_FREG(r))
639 arm64_strv(arm64_type_size(svtt), fltr(r), intr(svrv), 0);633 arm64_strv(S, arm64_type_size(svtt), fltr(r), intr(S, svrv), 0);
640 else634 else
641 arm64_strx(arm64_type_size(svtt), intr(r), intr(svrv), 0);635 arm64_strx(S, arm64_type_size(svtt), intr(S, r), intr(S, svrv), 0);
642 return;636 return;
643 }637 }
644 638
645 if (svr == (VT_CONST | VT_LVAL | VT_SYM)) {639 if (svr == (VT_CONST | VT_LVAL | VT_SYM)) {
646 arm64_sym(30, sv->sym, // use x30 for address640 arm64_sym(S, 30, sv->sym, // use x30 for address
647 arm64_check_offset(0, arm64_type_size(svtt), svcul));641 arm64_check_offset(0, arm64_type_size(svtt), svcul));
648 if (IS_FREG(r))642 if (IS_FREG(r))
649 arm64_strv(arm64_type_size(svtt), fltr(r), 30,643 arm64_strv(S, arm64_type_size(svtt), fltr(r), 30,
650 arm64_check_offset(1, arm64_type_size(svtt), svcul));644 arm64_check_offset(1, arm64_type_size(svtt), svcul));
651 else645 else
652 arm64_strx(arm64_type_size(svtt), intr(r), 30,646 arm64_strx(S, arm64_type_size(svtt), intr(S, r), 30,
653 arm64_check_offset(1, arm64_type_size(svtt), svcul));647 arm64_check_offset(1, arm64_type_size(svtt), svcul));
654 return;648 return;
655 }649 }
@@ -658,82 +652,82 @@ ST_FUNC void store(int r, SValue *sv) · 2 unmodified lines
658 assert(0);652 assert(0);
659}653}
660 654
661static void arm64_gen_bl_or_b(int b)655static void arm64_gen_bl_or_b(TCCState *S, int b)
662{656{
663 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (vtop->r & VT_SYM)) {657 if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (S->tccgen_vtop->r & VT_SYM)) {
664 greloca(cur_text_section, vtop->sym, ind,658 greloca(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind,
665 b ? R_AARCH64_JUMP26 : R_AARCH64_CALL26, 0);659 b ? R_AARCH64_JUMP26 : R_AARCH64_CALL26, 0);
666 o(0x14000000 | (uint32_t)!b << 31); // b/bl .660 o(S, 0x14000000 | (uint32_t)!b << 31); // b/bl .
667 }661 }
668 else {662 else {
669#ifdef CONFIG_TCC_BCHECK663#ifdef CONFIG_TCC_BCHECK
670 vtop->r &= ~VT_MUSTBOUND;664 S->tccgen_vtop->r &= ~VT_MUSTBOUND;
671#endif665#endif
672 o(0xd61f0000 | (uint32_t)!b << 21 | intr(gv(RC_R30)) << 5); // br/blr666 o(S, 0xd61f0000 | (uint32_t)!b << 21 | intr(S, gv(S, RC_R30)) << 5); // br/blr
673 }667 }
674}668}
675 669
676#if defined(CONFIG_TCC_BCHECK)670#if defined(CONFIG_TCC_BCHECK)
677 671
678static void gen_bounds_call(int v)672static void gen_bounds_call(TCCState *S, int v)
679{673{
680 Sym *sym = external_helper_sym(v);674 Sym *sym = external_helper_sym(S, v);
681 675
682 greloca(cur_text_section, sym, ind, R_AARCH64_CALL26, 0);676 greloca(S, cur_text_section, sym, S->tccgen_ind, R_AARCH64_CALL26, 0);
683 o(0x94000000); // bl677 o(S, 0x94000000); // bl
684}678}
685 679
686static void gen_bounds_prolog(void)680static void gen_bounds_prolog(TCCState *S)
687{681{
688 /* leave some room for bound checking code */682 /* leave some room for bound checking code */
689 func_bound_offset = lbounds_section->data_offset;683 S->func_bound_offset = lbounds_section->data_offset;
690 func_bound_ind = ind;684 S->func_bound_ind = S->tccgen_ind;
691 func_bound_add_epilog = 0;685 S->func_bound_add_epilog = 0;
692 o(0xd503201f); /* nop -> mov x0, lbound section pointer */686 o(S, 0xd503201f); /* nop -> mov x0, lbound section pointer */
693 o(0xd503201f);687 o(S, 0xd503201f);
694 o(0xd503201f);688 o(S, 0xd503201f);
695 o(0xd503201f); /* nop -> call __bound_local_new */689 o(S, 0xd503201f); /* nop -> call __bound_local_new */
696}690}
697 691
698static void gen_bounds_epilog(void)692static void gen_bounds_epilog(TCCState *S)
699{693{
700 addr_t saved_ind;694 addr_t saved_ind;
701 addr_t *bounds_ptr;695 addr_t *bounds_ptr;
702 Sym *sym_data;696 Sym *sym_data;
703 int offset_modified = func_bound_offset != lbounds_section->data_offset;697 int offset_modified = S->func_bound_offset != lbounds_section->data_offset;
704 698
705 if (!offset_modified && !func_bound_add_epilog)699 if (!offset_modified && !S->func_bound_add_epilog)
706 return;700 return;
707 701
708 /* add end of table info */702 /* add end of table info */
709 bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));703 bounds_ptr = section_ptr_add(S, lbounds_section, sizeof(addr_t));
710 *bounds_ptr = 0;704 *bounds_ptr = 0;
711 705
712 sym_data = get_sym_ref(&char_pointer_type, lbounds_section,706 sym_data = get_sym_ref(S, &S->tccgen_char_pointer_type, lbounds_section,
713 func_bound_offset, lbounds_section->data_offset);707 S->func_bound_offset, lbounds_section->data_offset);
714 708
715 /* generate bound local allocation */709 /* generate bound local allocation */
716 if (offset_modified) {710 if (offset_modified) {
717 saved_ind = ind;711 saved_ind = S->tccgen_ind;
718 ind = func_bound_ind;712 S->tccgen_ind = S->func_bound_ind;
719 greloca(cur_text_section, sym_data, ind, R_AARCH64_ADR_GOT_PAGE, 0);713 greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_AARCH64_ADR_GOT_PAGE, 0);
720 o(0x90000000 | 0); // adrp x0, #sym_data714 o(S, 0x90000000 | 0); // adrp x0, #sym_data
721 greloca(cur_text_section, sym_data, ind, R_AARCH64_LD64_GOT_LO12_NC, 0);715 greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_AARCH64_LD64_GOT_LO12_NC, 0);
722 o(0xf9400000 | 0 | (0 << 5)); // ld x0,[x0, #sym_data]716 o(S, 0xf9400000 | 0 | (0 << 5)); // ld x0,[x0, #sym_data]
723 gen_bounds_call(TOK___bound_local_new);717 gen_bounds_call(S, TOK___bound_local_new);
724 ind = saved_ind;718 S->tccgen_ind = saved_ind;
725 }719 }
726 720
727 /* generate bound check local freeing */721 /* generate bound check local freeing */
728 o(0xf81f0fe0); /* str x0, [sp, #-16]! */722 o(S, 0xf81f0fe0); /* str x0, [sp, #-16]! */
729 o(0x3c9f0fe0); /* str q0, [sp, #-16]! */723 o(S, 0x3c9f0fe0); /* str q0, [sp, #-16]! */
730 greloca(cur_text_section, sym_data, ind, R_AARCH64_ADR_GOT_PAGE, 0);724 greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_AARCH64_ADR_GOT_PAGE, 0);
731 o(0x90000000 | 0); // adrp x0, #sym_data725 o(S, 0x90000000 | 0); // adrp x0, #sym_data
732 greloca(cur_text_section, sym_data, ind, R_AARCH64_LD64_GOT_LO12_NC, 0);726 greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_AARCH64_LD64_GOT_LO12_NC, 0);
733 o(0xf9400000 | 0 | (0 << 5)); // ld x0,[x0, #sym_data]727 o(S, 0xf9400000 | 0 | (0 << 5)); // ld x0,[x0, #sym_data]
734 gen_bounds_call(TOK___bound_local_delete);728 gen_bounds_call(S, TOK___bound_local_delete);
735 o(0x3cc107e0); /* ldr q0, [sp], #16 */729 o(S, 0x3cc107e0); /* ldr q0, [sp], #16 */
736 o(0xf84107e0); /* ldr x0, [sp], #16 */730 o(S, 0xf84107e0); /* ldr x0, [sp], #16 */
737}731}
738#endif732#endif
739 733
@@ -970,7 +964,7 @@ static unsigned long arm64_pcs(int n, CType **type, unsigned long *a) · 230 unmodified lines
970 return stack;964 return stack;
971}965}
972 966
973ST_FUNC void gfunc_call(int nb_args)967ST_FUNC void gfunc_call(TCCState *S, int nb_args)
974{968{
975 CType *return_type;969 CType *return_type;
976 CType **t;970 CType **t;
@@ -979,28 +973,28 @@ ST_FUNC void gfunc_call(int nb_args) · 2 unmodified lines
979 int i;973 int i;
980 974
981#ifdef CONFIG_TCC_BCHECK975#ifdef CONFIG_TCC_BCHECK
982 if (tcc_state->do_bounds_check)976 if (S->do_bounds_check)
983 gbound_args(nb_args);977 gbound_args(S, nb_args);
984#endif978#endif
985 979
986 return_type = &vtop[-nb_args].type.ref->type;980 return_type = &S->tccgen_vtop[-nb_args].type.ref->type;
987 if ((return_type->t & VT_BTYPE) == VT_STRUCT)981 if ((return_type->t & VT_BTYPE) == VT_STRUCT)
988 --nb_args;982 --nb_args;
989 983
990 t = tcc_malloc((nb_args + 1) * sizeof(*t));984 t = tcc_malloc(S, (nb_args + 1) * sizeof(*t));
991 a = tcc_malloc((nb_args + 1) * sizeof(*a));985 a = tcc_malloc(S, (nb_args + 1) * sizeof(*a));
992 a1 = tcc_malloc((nb_args + 1) * sizeof(*a1));986 a1 = tcc_malloc(S, (nb_args + 1) * sizeof(*a1));
993 987
994 t[0] = return_type;988 t[0] = return_type;
995 for (i = 0; i < nb_args; i++)989 for (i = 0; i < nb_args; i++)
996 t[nb_args - i] = &vtop[-i].type;990 t[nb_args - i] = &S->tccgen_vtop[-i].type;
997 991
998 stack = arm64_pcs(nb_args, t, a);992 stack = arm64_pcs(nb_args, t, a);
999 993
1000 // Allocate space for structs replaced by pointer:994 // Allocate space for structs replaced by pointer:
1001 for (i = nb_args; i; i--)995 for (i = nb_args; i; i--)
1002 if (a[i] & 1) {996 if (a[i] & 1) {
1003 SValue *arg = &vtop[i - nb_args];997 SValue *arg = &S->tccgen_vtop[i - nb_args];
1004 int align, size = type_size(&arg->type, &align);998 int align, size = type_size(&arg->type, &align);
1005 assert((arg->type.t & VT_BTYPE) == VT_STRUCT);999 assert((arg->type.t & VT_BTYPE) == VT_STRUCT);
1006 stack = (stack + align - 1) & -align;1000 stack = (stack + align - 1) & -align;
@@ -1011,134 +1005,134 @@ ST_FUNC void gfunc_call(int nb_args) · 4 unmodified lines
1011 stack = (stack + 15) >> 4 << 4;1005 stack = (stack + 15) >> 4 << 4;
1012 1006
1013 /* fetch cpu flag before generating any code */1007 /* fetch cpu flag before generating any code */
1014 if ((vtop->r & VT_VALMASK) == VT_CMP)1008 if ((S->tccgen_vtop->r & VT_VALMASK) == VT_CMP)
1015 gv(RC_INT);1009 gv(S, RC_INT);
1016 1010
1017 if (stack >= 0x1000000) // 16Mb1011 if (stack >= 0x1000000) // 16Mb
1018 tcc_error("stack size too big %lu", stack);1012 tcc_error(S, "stack size too big %lu", stack);
1019 if (stack & 0xfff)1013 if (stack & 0xfff)
1020 o(0xd10003ff | (stack & 0xfff) << 10); // sub sp,sp,#(n)1014 o(S, 0xd10003ff | (stack & 0xfff) << 10); // sub sp,sp,#(n)
1021 if (stack >> 12)1015 if (stack >> 12)
1022 o(0xd14003ff | (stack >> 12) << 10);1016 o(S, 0xd14003ff | (stack >> 12) << 10);
1023 1017
1024 // First pass: set all values on stack1018 // First pass: set all values on stack
1025 for (i = nb_args; i; i--) {1019 for (i = nb_args; i; i--) {
1026 vpushv(vtop - nb_args + i);1020 vpushv(S, S->tccgen_vtop - nb_args + i);
1027 1021
1028 if (a[i] & 1) {1022 if (a[i] & 1) {
1029 // struct replaced by pointer1023 // struct replaced by pointer
1030 int r = get_reg(RC_INT);1024 int r = get_reg(S, RC_INT);
1031 arm64_spoff(intr(r), a1[i]);1025 arm64_spoff(S, intr(S, r), a1[i]);
1032 vset(&vtop->type, r | VT_LVAL, 0);1026 vset(S, &S->tccgen_vtop->type, r | VT_LVAL, 0);
1033 vswap();1027 vswap(S);
1034 vstore();1028 vstore(S);
1035 if (a[i] >= 32) {1029 if (a[i] >= 32) {
1036 // pointer on stack1030 // pointer on stack
1037 r = get_reg(RC_INT);1031 r = get_reg(S, RC_INT);
1038 arm64_spoff(intr(r), a1[i]);1032 arm64_spoff(S, intr(S, r), a1[i]);
1039 arm64_strx(3, intr(r), 31, (a[i] - 32) >> 1 << 1);1033 arm64_strx(S, 3, intr(S, r), 31, (a[i] - 32) >> 1 << 1);
1040 }1034 }
1041 }1035 }
1042 else if (a[i] >= 32) {1036 else if (a[i] >= 32) {
1043 // value on stack1037 // value on stack
1044 if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {1038 if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_STRUCT) {
1045 int r = get_reg(RC_INT);1039 int r = get_reg(S, RC_INT);
1046 arm64_spoff(intr(r), a[i] - 32);1040 arm64_spoff(S, intr(S, r), a[i] - 32);
1047 vset(&vtop->type, r | VT_LVAL, 0);1041 vset(S, &S->tccgen_vtop->type, r | VT_LVAL, 0);
1048 vswap();1042 vswap(S);
1049 vstore();1043 vstore(S);
1050 }1044 }
1051 else if (is_float(vtop->type.t)) {1045 else if (is_float(S->tccgen_vtop->type.t)) {
1052 gv(RC_FLOAT);1046 gv(S, RC_FLOAT);
1053 arm64_strv(arm64_type_size(vtop[0].type.t),1047 arm64_strv(S, arm64_type_size(S->tccgen_vtop[0].type.t),
1054 fltr(vtop[0].r), 31, a[i] - 32);1048 fltr(S->tccgen_vtop[0].r), 31, a[i] - 32);
1055 }1049 }
1056 else {1050 else {
1057 gv(RC_INT);1051 gv(S, RC_INT);
1058 arm64_strx(arm64_type_size(vtop[0].type.t),1052 arm64_strx(S, arm64_type_size(S->tccgen_vtop[0].type.t),
1059 intr(vtop[0].r), 31, a[i] - 32);1053 intr(S, S->tccgen_vtop[0].r), 31, a[i] - 32);
1060 }1054 }
1061 }1055 }
1062 1056
1063 --vtop;1057 --S->tccgen_vtop;
1064 }1058 }
1065 1059
1066 // Second pass: assign values to registers1060 // Second pass: assign values to registers
1067 for (i = nb_args; i; i--, vtop--) {1061 for (i = nb_args; i; i--, S->tccgen_vtop--) {
1068 if (a[i] < 16 && !(a[i] & 1)) {1062 if (a[i] < 16 && !(a[i] & 1)) {
1069 // value in general-purpose registers1063 // value in general-purpose registers
1070 if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {1064 if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_STRUCT) {
1071 int align, size = type_size(&vtop->type, &align);1065 int align, size = type_size(&S->tccgen_vtop->type, &align);
1072 if (size) {1066 if (size) {
1073 vtop->type.t = VT_PTR;1067 S->tccgen_vtop->type.t = VT_PTR;
1074 gaddrof();1068 gaddrof(S);
1075 gv(RC_R(a[i] / 2));1069 gv(S, RC_R(a[i] / 2));
1076 arm64_ldrs(a[i] / 2, size);1070 arm64_ldrs(S, a[i] / 2, size);
1077 }1071 }
1078 }1072 }
1079 else1073 else
1080 gv(RC_R(a[i] / 2));1074 gv(S, RC_R(a[i] / 2));
1081 }1075 }
1082 else if (a[i] < 16)1076 else if (a[i] < 16)
1083 // struct replaced by pointer in register1077 // struct replaced by pointer in register
1084 arm64_spoff(a[i] / 2, a1[i]);1078 arm64_spoff(S, a[i] / 2, a1[i]);
1085 else if (a[i] < 32) {1079 else if (a[i] < 32) {
1086 // value in floating-point registers1080 // value in floating-point registers
1087 if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {1081 if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_STRUCT) {
1088 uint32_t j, sz, n = arm64_hfa(&vtop->type, &sz);1082 uint32_t j, sz, n = arm64_hfa(&S->tccgen_vtop->type, &sz);
1089 vtop->type.t = VT_PTR;1083 S->tccgen_vtop->type.t = VT_PTR;
1090 gaddrof();1084 gaddrof(S);
1091 gv(RC_R30);1085 gv(S, RC_R30);
1092 for (j = 0; j < n; j++)1086 for (j = 0; j < n; j++)
1093 o(0x3d4003c0 |1087 o(S, 0x3d4003c0 |
1094 (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |1088 (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |
1095 (a[i] / 2 - 8 + j) |1089 (a[i] / 2 - 8 + j) |
1096 j << 10); // ldr ([sdq])(*),[x30,#(j * sz)]1090 j << 10); // ldr ([sdq])(*),[x30,#(j * sz)]
1097 }1091 }
1098 else1092 else
1099 gv(RC_F(a[i] / 2 - 8));1093 gv(S, RC_F(a[i] / 2 - 8));
1100 }1094 }
1101 }1095 }
1102 1096
1103 if ((return_type->t & VT_BTYPE) == VT_STRUCT) {1097 if ((return_type->t & VT_BTYPE) == VT_STRUCT) {
1104 if (a[0] == 1) {1098 if (a[0] == 1) {
1105 // indirect return: set x8 and discard the stack value1099 // indirect return: set x8 and discard the stack value
1106 gv(RC_R(8));1100 gv(S, RC_R(8));
1107 --vtop;1101 --S->tccgen_vtop;
1108 }1102 }
1109 else1103 else
1110 // return in registers: keep the address for after the call1104 // return in registers: keep the address for after the call
1111 vswap();1105 vswap(S);
1112 }1106 }
1113 1107
1114 save_regs(0);1108 save_regs(S, 0);
1115 arm64_gen_bl_or_b(0);1109 arm64_gen_bl_or_b(S, 0);
1116 --vtop;1110 --S->tccgen_vtop;
1117 if (stack & 0xfff)1111 if (stack & 0xfff)
1118 o(0x910003ff | (stack & 0xfff) << 10); // add sp,sp,#(n)1112 o(S, 0x910003ff | (stack & 0xfff) << 10); // add sp,sp,#(n)
1119 if (stack >> 12)1113 if (stack >> 12)
1120 o(0x914003ff | (stack >> 12) << 10);1114 o(S, 0x914003ff | (stack >> 12) << 10);
1121 1115
1122 {1116 {
1123 int rt = return_type->t;1117 int rt = return_type->t;
1124 int bt = rt & VT_BTYPE;1118 int bt = rt & VT_BTYPE;
1125 if (bt == VT_STRUCT && !(a[0] & 1)) {1119 if (bt == VT_STRUCT && !(a[0] & 1)) {
1126 // A struct was returned in registers, so write it out:1120 // A struct was returned in registers, so write it out:
1127 gv(RC_R(8));1121 gv(S, RC_R(8));
1128 --vtop;1122 --S->tccgen_vtop;
1129 if (a[0] == 0) {1123 if (a[0] == 0) {
1130 int align, size = type_size(return_type, &align);1124 int align, size = type_size(return_type, &align);
1131 assert(size <= 16);1125 assert(size <= 16);
1132 if (size > 8)1126 if (size > 8)
1133 o(0xa9000500); // stp x0,x1,[x8]1127 o(S, 0xa9000500); // stp x0,x1,[x8]
1134 else if (size)1128 else if (size)
1135 arm64_strx(size > 4 ? 3 : size > 2 ? 2 : size > 1, 0, 8, 0);1129 arm64_strx(S, size > 4 ? 3 : size > 2 ? 2 : size > 1, 0, 8, 0);
1136 1130
1137 }1131 }
1138 else if (a[0] == 16) {1132 else if (a[0] == 16) {
1139 uint32_t j, sz, n = arm64_hfa(return_type, &sz);1133 uint32_t j, sz, n = arm64_hfa(return_type, &sz);
1140 for (j = 0; j < n; j++)1134 for (j = 0; j < n; j++)
1141 o(0x3d000100 |1135 o(S, 0x3d000100 |
1142 (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |1136 (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |
1143 (a[i] / 2 - 8 + j) |1137 (a[i] / 2 - 8 + j) |
1144 j << 10); // str ([sdq])(*),[x8,#(j * sz)]1138 j << 10); // str ([sdq])(*),[x8,#(j * sz)]
@@ -1146,9 +1140,9 @@ ST_FUNC void gfunc_call(int nb_args) · 1 unmodified line
1146 }1140 }
1147 }1141 }
1148 1142
1149 tcc_free(a1);1143 tcc_free(S, a1);
1150 tcc_free(a);1144 tcc_free(S, a);
1151 tcc_free(t);1145 tcc_free(S, t);
1152}1146}
1153 1147
1154static unsigned long arm64_func_va_list_stack;1148static unsigned long arm64_func_va_list_stack;
@@ -1156,7 +1150,7 @@ static int arm64_func_va_list_gr_offs; · 1 unmodified line
1156static int arm64_func_va_list_vr_offs;1150static int arm64_func_va_list_vr_offs;
1157static int arm64_func_sub_sp_offset;1151static int arm64_func_sub_sp_offset;
1158 1152
1159ST_FUNC void gfunc_prolog(Sym *func_sym)1153ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym)
1160{1154{
1161 CType *func_type = &func_sym->type;1155 CType *func_type = &func_sym->type;
1162 int n = 0;1156 int n = 0;
@@ -1165,28 +1159,28 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 2 unmodified lines
1165 CType **t;1159 CType **t;
1166 unsigned long *a;1160 unsigned long *a;
1167 1161
1168 func_vc = 144; // offset of where x8 is stored1162 S->tccgen_func_vc = 144; // offset of where x8 is stored
1169 1163
1170 for (sym = func_type->ref; sym; sym = sym->next)1164 for (sym = func_type->ref; sym; sym = sym->next)
1171 ++n;1165 ++n;
1172 t = n ? tcc_malloc(n * sizeof(*t)) : NULL;1166 t = n ? tcc_malloc(S, n * sizeof(*t)) : NULL;
1173 a = n ? tcc_malloc(n * sizeof(*a)) : NULL;1167 a = n ? tcc_malloc(S, n * sizeof(*a)) : NULL;
1174 1168
1175 for (sym = func_type->ref; sym; sym = sym->next)1169 for (sym = func_type->ref; sym; sym = sym->next)
1176 t[i++] = &sym->type;1170 t[i++] = &sym->type;
1177 1171
1178 arm64_func_va_list_stack = arm64_pcs(n - 1, t, a);1172 arm64_func_va_list_stack = arm64_pcs(n - 1, t, a);
1179 1173
1180 o(0xa9b27bfd); // stp x29,x30,[sp,#-224]!1174 o(S, 0xa9b27bfd); // stp x29,x30,[sp,#-224]!
1181 o(0xad0087e0); // stp q0,q1,[sp,#16]1175 o(S, 0xad0087e0); // stp q0,q1,[sp,#16]
1182 o(0xad018fe2); // stp q2,q3,[sp,#48]1176 o(S, 0xad018fe2); // stp q2,q3,[sp,#48]
1183 o(0xad0297e4); // stp q4,q5,[sp,#80]1177 o(S, 0xad0297e4); // stp q4,q5,[sp,#80]
1184 o(0xad039fe6); // stp q6,q7,[sp,#112]1178 o(S, 0xad039fe6); // stp q6,q7,[sp,#112]
1185 o(0xa90923e8); // stp x8,x8,[sp,#144]1179 o(S, 0xa90923e8); // stp x8,x8,[sp,#144]
1186 o(0xa90a07e0); // stp x0,x1,[sp,#160]1180 o(S, 0xa90a07e0); // stp x0,x1,[sp,#160]
1187 o(0xa90b0fe2); // stp x2,x3,[sp,#176]1181 o(S, 0xa90b0fe2); // stp x2,x3,[sp,#176]
1188 o(0xa90c17e4); // stp x4,x5,[sp,#192]1182 o(S, 0xa90c17e4); // stp x4,x5,[sp,#192]
1189 o(0xa90d1fe6); // stp x6,x7,[sp,#208]1183 o(S, 0xa90d1fe6); // stp x6,x7,[sp,#208]
1190 1184
1191 arm64_func_va_list_gr_offs = -64;1185 arm64_func_va_list_gr_offs = -64;
1192 arm64_func_va_list_vr_offs = -128;1186 arm64_func_va_list_vr_offs = -128;
@@ -1195,7 +1189,7 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 2 unmodified lines
1195 int off = (a[i] < 16 ? 160 + a[i] / 2 * 8 :1189 int off = (a[i] < 16 ? 160 + a[i] / 2 * 8 :
1196 a[i] < 32 ? 16 + (a[i] - 16) / 2 * 16 :1190 a[i] < 32 ? 16 + (a[i] - 16) / 2 * 16 :
1197 224 + ((a[i] - 32) >> 1 << 1));1191 224 + ((a[i] - 32) >> 1 << 1));
1198 sym_push(sym->v & ~SYM_FIELD, &sym->type,1192 sym_push(S, sym->v & ~SYM_FIELD, &sym->type,
1199 (a[i] & 1 ? VT_LLOCAL : VT_LOCAL) | VT_LVAL,1193 (a[i] & 1 ? VT_LLOCAL : VT_LOCAL) | VT_LVAL,
1200 off);1194 off);
1201 1195
@@ -1215,65 +1209,65 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 13 unmodified lines
1215 uint32_t j, sz, k = arm64_hfa(&sym->type, &sz);1209 uint32_t j, sz, k = arm64_hfa(&sym->type, &sz);
1216 if (sz < 16)1210 if (sz < 16)
1217 for (j = 0; j < k; j++) {1211 for (j = 0; j < k; j++) {
1218 o(0x3d0003e0 | -(sz & 8) << 27 | (sz & 4) << 29 |1212 o(S, 0x3d0003e0 | -(sz & 8) << 27 | (sz & 4) << 29 |
1219 ((a[i] - 16) / 2 + j) | (off / sz + j) << 10);1213 ((a[i] - 16) / 2 + j) | (off / sz + j) << 10);
1220 // str ([sdq])(*),[sp,#(j * sz)]1214 // str ([sdq])(*),[sp,#(j * sz)]
1221 }1215 }
1222 }1216 }
1223 }1217 }
1224 1218
1225 tcc_free(a);1219 tcc_free(S, a);
1226 tcc_free(t);1220 tcc_free(S, t);
1227 1221
1228 o(0x910003fd); // mov x29,sp1222 o(S, 0x910003fd); // mov x29,sp
1229 arm64_func_sub_sp_offset = ind;1223 arm64_func_sub_sp_offset = S->tccgen_ind;
1230 // In gfunc_epilog these will be replaced with code to decrement SP:1224 // In gfunc_epilog these will be replaced with code to decrement SP:
1231 o(0xd503201f); // nop1225 o(S, 0xd503201f); // nop
1232 o(0xd503201f); // nop1226 o(S, 0xd503201f); // nop
1233 loc = 0;1227 S->tccgen_loc = 0;
1234#ifdef CONFIG_TCC_BCHECK1228#ifdef CONFIG_TCC_BCHECK
1235 if (tcc_state->do_bounds_check)1229 if (S->do_bounds_check)
1236 gen_bounds_prolog();1230 gen_bounds_prolog(S);
1237#endif1231#endif
1238}1232}
1239 1233
1240ST_FUNC void gen_va_start(void)1234ST_FUNC void gen_va_start(TCCState *S)
1241{1235{
1242 int r;1236 int r;
1243 --vtop; // we don't need the "arg"1237 --S->tccgen_vtop; // we don't need the "arg"
1244 gaddrof();1238 gaddrof(S);
1245 r = intr(gv(RC_INT));1239 r = intr(S, gv(S, RC_INT));
1246 1240
1247 if (arm64_func_va_list_stack) {1241 if (arm64_func_va_list_stack) {
1248 //xx could use add (immediate) here1242 //xx could use add (immediate) here
1249 arm64_movimm(30, arm64_func_va_list_stack + 224);1243 arm64_movimm(S, 30, arm64_func_va_list_stack + 224);
1250 o(0x8b1e03be); // add x30,x29,x301244 o(S, 0x8b1e03be); // add x30,x29,x30
1251 }1245 }
1252 else1246 else
1253 o(0x910383be); // add x30,x29,#2241247 o(S, 0x910383be); // add x30,x29,#224
1254 o(0xf900001e | r << 5); // str x30,[x(r)]1248 o(S, 0xf900001e | r << 5); // str x30,[x(r)]
1255 1249
1256 if (arm64_func_va_list_gr_offs) {1250 if (arm64_func_va_list_gr_offs) {
1257 if (arm64_func_va_list_stack)1251 if (arm64_func_va_list_stack)
1258 o(0x910383be); // add x30,x29,#2241252 o(S, 0x910383be); // add x30,x29,#224
1259 o(0xf900041e | r << 5); // str x30,[x(r),#8]1253 o(S, 0xf900041e | r << 5); // str x30,[x(r),#8]
1260 }1254 }
1261 1255
1262 if (arm64_func_va_list_vr_offs) {1256 if (arm64_func_va_list_vr_offs) {
1263 o(0x910243be); // add x30,x29,#1441257 o(S, 0x910243be); // add x30,x29,#144
1264 o(0xf900081e | r << 5); // str x30,[x(r),#16]1258 o(S, 0xf900081e | r << 5); // str x30,[x(r),#16]
1265 }1259 }
1266 1260
1267 arm64_movimm(30, arm64_func_va_list_gr_offs);1261 arm64_movimm(S, 30, arm64_func_va_list_gr_offs);
1268 o(0xb900181e | r << 5); // str w30,[x(r),#24]1262 o(S, 0xb900181e | r << 5); // str w30,[x(r),#24]
1269 1263
1270 arm64_movimm(30, arm64_func_va_list_vr_offs);1264 arm64_movimm(S, 30, arm64_func_va_list_vr_offs);
1271 o(0xb9001c1e | r << 5); // str w30,[x(r),#28]1265 o(S, 0xb9001c1e | r << 5); // str w30,[x(r),#28]
1272 1266
1273 --vtop;1267 --S->tccgen_vtop;
1274}1268}
1275 1269
1276ST_FUNC void gen_va_arg(CType *t)1270ST_FUNC void gen_va_arg(TCCState *S, CType *t)
1277{1271{
1278 int align, size = type_size(t, &align);1272 int align, size = type_size(t, &align);
1279 unsigned fsize, hfa = arm64_hfa(t, &fsize);1273 unsigned fsize, hfa = arm64_hfa(t, &fsize);
@@ -1284,69 +1278,69 @@ ST_FUNC void gen_va_arg(CType *t) · 4 unmodified lines
1284 fsize = size;1278 fsize = size;
1285 }1279 }
1286 1280
1287 gaddrof();1281 gaddrof(S);
1288 r0 = intr(gv(RC_INT));1282 r0 = intr(S, gv(S, RC_INT));
1289 r1 = get_reg(RC_INT);1283 r1 = get_reg(S, RC_INT);
1290 vtop[0].r = r1 | VT_LVAL;1284 S->tccgen_vtop[0].r = r1 | VT_LVAL;
1291 r1 = intr(r1);1285 r1 = intr(S, r1);
1292 1286
1293 if (!hfa) {1287 if (!hfa) {
1294 uint32_t n = size > 16 ? 8 : (size + 7) & -8;1288 uint32_t n = size > 16 ? 8 : (size + 7) & -8;
1295 o(0xb940181e | r0 << 5); // ldr w30,[x(r0),#24] // __gr_offs1289 o(S, 0xb940181e | r0 << 5); // ldr w30,[x(r0),#24] // __gr_offs
1296 if (align == 16) {1290 if (align == 16) {
1297 assert(0); // this path untested but needed for __uint128_t1291 assert(0); // this path untested but needed for __uint128_t
1298 o(0x11003fde); // add w30,w30,#151292 o(S, 0x11003fde); // add w30,w30,#15
1299 o(0x121c6fde); // and w30,w30,#-161293 o(S, 0x121c6fde); // and w30,w30,#-16
1300 }1294 }
1301 o(0x310003c0 | r1 | n << 10); // adds w(r1),w30,#(n)1295 o(S, 0x310003c0 | r1 | n << 10); // adds w(r1),w30,#(n)
1302 o(0x540000ad); // b.le .+201296 o(S, 0x540000ad); // b.le .+20
1303 o(0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack1297 o(S, 0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack
1304 o(0x9100001e | r1 << 5 | n << 10); // add x30,x(r1),#(n)1298 o(S, 0x9100001e | r1 << 5 | n << 10); // add x30,x(r1),#(n)
1305 o(0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack1299 o(S, 0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack
1306 o(0x14000004); // b .+161300 o(S, 0x14000004); // b .+16
1307 o(0xb9001800 | r1 | r0 << 5); // str w(r1),[x(r0),#24] // __gr_offs1301 o(S, 0xb9001800 | r1 | r0 << 5); // str w(r1),[x(r0),#24] // __gr_offs
1308 o(0xf9400400 | r1 | r0 << 5); // ldr x(r1),[x(r0),#8] // __gr_top1302 o(S, 0xf9400400 | r1 | r0 << 5); // ldr x(r1),[x(r0),#8] // __gr_top
1309 o(0x8b3ec000 | r1 | r1 << 5); // add x(r1),x(r1),w30,sxtw1303 o(S, 0x8b3ec000 | r1 | r1 << 5); // add x(r1),x(r1),w30,sxtw
1310 if (size > 16)1304 if (size > 16)
1311 o(0xf9400000 | r1 | r1 << 5); // ldr x(r1),[x(r1)]1305 o(S, 0xf9400000 | r1 | r1 << 5); // ldr x(r1),[x(r1)]
1312 }1306 }
1313 else {1307 else {
1314 uint32_t rsz = hfa << 4;1308 uint32_t rsz = hfa << 4;
1315 uint32_t ssz = (size + 7) & -(uint32_t)8;1309 uint32_t ssz = (size + 7) & -(uint32_t)8;
1316 uint32_t b1, b2;1310 uint32_t b1, b2;
1317 o(0xb9401c1e | r0 << 5); // ldr w30,[x(r0),#28] // __vr_offs1311 o(S, 0xb9401c1e | r0 << 5); // ldr w30,[x(r0),#28] // __vr_offs
1318 o(0x310003c0 | r1 | rsz << 10); // adds w(r1),w30,#(rsz)1312 o(S, 0x310003c0 | r1 | rsz << 10); // adds w(r1),w30,#(rsz)
1319 b1 = ind; o(0x5400000d); // b.le lab11313 b1 = S->tccgen_ind; o(S, 0x5400000d); // b.le lab1
1320 o(0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack1314 o(S, 0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack
1321 if (fsize == 16) {1315 if (fsize == 16) {
1322 o(0x91003c00 | r1 | r1 << 5); // add x(r1),x(r1),#151316 o(S, 0x91003c00 | r1 | r1 << 5); // add x(r1),x(r1),#15
1323 o(0x927cec00 | r1 | r1 << 5); // and x(r1),x(r1),#-161317 o(S, 0x927cec00 | r1 | r1 << 5); // and x(r1),x(r1),#-16
1324 }1318 }
1325 o(0x9100001e | r1 << 5 | ssz << 10); // add x30,x(r1),#(ssz)1319 o(S, 0x9100001e | r1 << 5 | ssz << 10); // add x30,x(r1),#(ssz)
1326 o(0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack1320 o(S, 0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack
1327 b2 = ind; o(0x14000000); // b lab21321 b2 = S->tccgen_ind; o(S, 0x14000000); // b lab2
1328 // lab1:1322 // lab1:
1329 write32le(cur_text_section->data + b1, 0x5400000d | (ind - b1) << 3);1323 write32le(cur_text_section->data + b1, 0x5400000d | (S->tccgen_ind - b1) << 3);
1330 o(0xb9001c00 | r1 | r0 << 5); // str w(r1),[x(r0),#28] // __vr_offs1324 o(S, 0xb9001c00 | r1 | r0 << 5); // str w(r1),[x(r0),#28] // __vr_offs
1331 o(0xf9400800 | r1 | r0 << 5); // ldr x(r1),[x(r0),#16] // __vr_top1325 o(S, 0xf9400800 | r1 | r0 << 5); // ldr x(r1),[x(r0),#16] // __vr_top
1332 if (hfa == 1 || fsize == 16)1326 if (hfa == 1 || fsize == 16)
1333 o(0x8b3ec000 | r1 | r1 << 5); // add x(r1),x(r1),w30,sxtw1327 o(S, 0x8b3ec000 | r1 | r1 << 5); // add x(r1),x(r1),w30,sxtw
1334 else {1328 else {
1335 // We need to change the layout of this HFA.1329 // We need to change the layout of this HFA.
1336 // Get some space on the stack using global variable "loc":1330 // Get some space on the stack using global variable "loc":
1337 loc = (loc - size) & -(uint32_t)align;1331 S->tccgen_loc = (S->tccgen_loc - size) & -(uint32_t)align;
1338 o(0x8b3ec000 | 30 | r1 << 5); // add x30,x(r1),w30,sxtw1332 o(S, 0x8b3ec000 | 30 | r1 << 5); // add x30,x(r1),w30,sxtw
1339 arm64_movimm(r1, loc);1333 arm64_movimm(S, r1, S->tccgen_loc);
1340 o(0x8b0003a0 | r1 | r1 << 16); // add x(r1),x29,x(r1)1334 o(S, 0x8b0003a0 | r1 | r1 << 16); // add x(r1),x29,x(r1)
1341 o(0x4c402bdc | (uint32_t)fsize << 7 |1335 o(S, 0x4c402bdc | (uint32_t)fsize << 7 |
1342 (uint32_t)(hfa == 2) << 15 |1336 (uint32_t)(hfa == 2) << 15 |
1343 (uint32_t)(hfa == 3) << 14); // ld1 {v28.(4s|2d),...},[x30]1337 (uint32_t)(hfa == 3) << 14); // ld1 {v28.(4s|2d),...},[x30]
1344 o(0x0d00801c | r1 << 5 | (fsize == 8) << 10 |1338 o(S, 0x0d00801c | r1 << 5 | (fsize == 8) << 10 |
1345 (uint32_t)(hfa != 2) << 13 |1339 (uint32_t)(hfa != 2) << 13 |
1346 (uint32_t)(hfa != 3) << 21); // st(hfa) {v28.(s|d),...}[0],[x(r1)]1340 (uint32_t)(hfa != 3) << 21); // st(hfa) {v28.(s|d),...}[0],[x(r1)]
1347 }1341 }
1348 // lab2:1342 // lab2:
1349 write32le(cur_text_section->data + b2, 0x14000000 | (ind - b2) >> 2);1343 write32le(cur_text_section->data + b2, 0x14000000 | (S->tccgen_ind - b2) >> 2);
1350 }1344 }
1351}1345}
1352 1346
@@ -1356,7 +1350,7 @@ ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, · 3 unmodified lines
1356 return 0;1350 return 0;
1357}1351}
1358 1352
1359ST_FUNC void gfunc_return(CType *func_type)1353ST_FUNC void gfunc_return(TCCState *S, CType *func_type)
1360{1354{
1361 CType *t = func_type;1355 CType *t = func_type;
1362 unsigned long a;1356 unsigned long a;
@@ -1368,52 +1362,52 @@ ST_FUNC void gfunc_return(CType *func_type) · 5 unmodified lines
1368 case 0:1362 case 0:
1369 if ((func_type->t & VT_BTYPE) == VT_STRUCT) {1363 if ((func_type->t & VT_BTYPE) == VT_STRUCT) {
1370 int align, size = type_size(func_type, &align);1364 int align, size = type_size(func_type, &align);
1371 gaddrof();1365 gaddrof(S);
1372 gv(RC_R(0));1366 gv(S, RC_R(0));
1373 arm64_ldrs(0, size);1367 arm64_ldrs(S, 0, size);
1374 }1368 }
1375 else1369 else
1376 gv(RC_IRET);1370 gv(S, RC_IRET);
1377 break;1371 break;
1378 case 1: {1372 case 1: {
1379 CType type = *func_type;1373 CType type = *func_type;
1380 mk_pointer(&type);1374 mk_pointer(S, &type);
1381 vset(&type, VT_LOCAL | VT_LVAL, func_vc);1375 vset(S, &type, VT_LOCAL | VT_LVAL, S->tccgen_func_vc);
1382 indir();1376 indir(S);
1383 vswap();1377 vswap(S);
1384 vstore();1378 vstore(S);
1385 break;1379 break;
1386 }1380 }
1387 case 16:1381 case 16:
1388 if ((func_type->t & VT_BTYPE) == VT_STRUCT) {1382 if ((func_type->t & VT_BTYPE) == VT_STRUCT) {
1389 uint32_t j, sz, n = arm64_hfa(&vtop->type, &sz);1383 uint32_t j, sz, n = arm64_hfa(&S->tccgen_vtop->type, &sz);
1390 gaddrof();1384 gaddrof(S);
1391 gv(RC_R(0));1385 gv(S, RC_R(0));
1392 for (j = 0; j < n; j++)1386 for (j = 0; j < n; j++)
1393 o(0x3d400000 |1387 o(S, 0x3d400000 |
1394 (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |1388 (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |
1395 j | j << 10); // ldr ([sdq])(*),[x0,#(j * sz)]1389 j | j << 10); // ldr ([sdq])(*),[x0,#(j * sz)]
1396 }1390 }
1397 else1391 else
1398 gv(RC_FRET);1392 gv(S, RC_FRET);
1399 break;1393 break;
1400 default:1394 default:
1401 assert(0);1395 assert(0);
1402 }1396 }
1403 vtop--;1397 S->tccgen_vtop--;
1404}1398}
1405 1399
1406ST_FUNC void gfunc_epilog(void)1400ST_FUNC void gfunc_epilog(TCCState *S)
1407{1401{
1408#ifdef CONFIG_TCC_BCHECK1402#ifdef CONFIG_TCC_BCHECK
1409 if (tcc_state->do_bounds_check)1403 if (S->do_bounds_check)
1410 gen_bounds_epilog();1404 gen_bounds_epilog(S);
1411#endif1405#endif
1412 1406
1413 if (loc) {1407 if (S->tccgen_loc) {
1414 // Insert instructions to subtract size of stack frame from SP.1408 // Insert instructions to subtract size of stack frame from SP.
1415 unsigned char *ptr = cur_text_section->data + arm64_func_sub_sp_offset;1409 unsigned char *ptr = cur_text_section->data + arm64_func_sub_sp_offset;
1416 uint64_t diff = (-loc + 15) & ~15;1410 uint64_t diff = (-S->tccgen_loc + 15) & ~15;
1417 if (!(diff >> 24)) {1411 if (!(diff >> 24)) {
1418 if (diff & 0xfff) // sub sp,sp,#(diff & 0xfff)1412 if (diff & 0xfff) // sub sp,sp,#(diff & 0xfff)
1419 write32le(ptr, 0xd10003ff | (diff & 0xfff) << 10);1413 write32le(ptr, 0xd10003ff | (diff & 0xfff) << 10);
@@ -1439,40 +1433,40 @@ ST_FUNC void gfunc_epilog(void) · 19 unmodified lines
1439 // sub sp,sp,x16,lsl #(j)1433 // sub sp,sp,x16,lsl #(j)
1440 }1434 }
1441 }1435 }
1442 o(0x910003bf); // mov sp,x291436 o(S, 0x910003bf); // mov sp,x29
1443 o(0xa8ce7bfd); // ldp x29,x30,[sp],#2241437 o(S, 0xa8ce7bfd); // ldp x29,x30,[sp],#224
1444 1438
1445 o(0xd65f03c0); // ret1439 o(S, 0xd65f03c0); // ret
1446}1440}
1447 1441
1448ST_FUNC void gen_fill_nops(int bytes)1442ST_FUNC void gen_fill_nops(TCCState *S, int bytes)
1449{1443{
1450 if ((bytes & 3))1444 if ((bytes & 3))
1451 tcc_error("alignment of code section not multiple of 4");1445 tcc_error(S, "alignment of code section not multiple of 4");
1452 while (bytes > 0) {1446 while (bytes > 0) {
1453 o(0xd503201f); // nop1447 o(S, 0xd503201f); // nop
1454 bytes -= 4;1448 bytes -= 4;
1455 }1449 }
1456}1450}
1457 1451
1458// Generate forward branch to label:1452// Generate forward branch to label:
1459ST_FUNC int gjmp(int t)1453ST_FUNC int gjmp(TCCState *S, int t)
1460{1454{
1461 int r = ind;1455 int r = S->tccgen_ind;
1462 if (nocode_wanted)1456 if (S->tccgen_nocode_wanted)
1463 return t;1457 return t;
1464 o(t);1458 o(S, t);
1465 return r;1459 return r;
1466}1460}
1467 1461
1468// Generate branch to known address:1462// Generate branch to known address:
1469ST_FUNC void gjmp_addr(int a)1463ST_FUNC void gjmp_addr(TCCState *S, int a)
1470{1464{
1471 assert(a - ind + 0x8000000 < 0x10000000);1465 assert(a - S->tccgen_ind + 0x8000000 < 0x10000000);
1472 o(0x14000000 | ((a - ind) >> 2 & 0x3ffffff));1466 o(S, 0x14000000 | ((a - S->tccgen_ind) >> 2 & 0x3ffffff));
1473}1467}
1474 1468
1475ST_FUNC int gjmp_append(int n, int t)1469ST_FUNC int gjmp_append(TCCState *S, int n, int t)
1476{1470{
1477 void *p;1471 void *p;
1478 /* insert vtop->c jump list in t */1472 /* insert vtop->c jump list in t */
@@ -1486,61 +1480,61 @@ ST_FUNC int gjmp_append(int n, int t) · 7 unmodified lines
1486 return t;1480 return t;
1487}1481}
1488 1482
1489void arm64_vset_VT_CMP(int op)1483void arm64_vset_VT_CMP(TCCState *S, int op)
1490{1484{
1491 if (op >= TOK_ULT && op <= TOK_GT) {1485 if (op >= TOK_ULT && op <= TOK_GT) {
1492 vtop->cmp_r = vtop->r;1486 S->tccgen_vtop->cmp_r = S->tccgen_vtop->r;
1493 vset_VT_CMP(0x80);1487 vset_VT_CMP(S, 0x80);
1494 }1488 }
1495}1489}
1496 1490
1497static void arm64_gen_opil(int op, uint32_t l);1491static void arm64_gen_opil(TCCState *S, int op, uint32_t l);
1498 1492
1499static void arm64_load_cmp(int r, SValue *sv)1493static void arm64_load_cmp(TCCState *S, int r, SValue *sv)
1500{1494{
1501 sv->r = sv->cmp_r;1495 sv->r = sv->cmp_r;
1502 if (sv->c.i & 1) {1496 if (sv->c.i & 1) {
1503 vpushi(1);1497 vpushi(S, 1);
1504 arm64_gen_opil('^', 0);1498 arm64_gen_opil(S, '^', 0);
1505 }1499 }
1506 if (r != sv->r) {1500 if (r != sv->r) {
1507 load(r, sv);1501 load(S, r, sv);
1508 sv->r = r;1502 sv->r = r;
1509 }1503 }
1510}1504}
1511 1505
1512ST_FUNC int gjmp_cond(int op, int t)1506ST_FUNC int gjmp_cond(TCCState *S, int op, int t)
1513{1507{
1514 int bt = vtop->type.t & VT_BTYPE;1508 int bt = S->tccgen_vtop->type.t & VT_BTYPE;
1515 1509
1516 int inv = op & 1;1510 int inv = op & 1;
1517 vtop->r = vtop->cmp_r;1511 S->tccgen_vtop->r = S->tccgen_vtop->cmp_r;
1518 1512
1519 if (bt == VT_LDOUBLE) {1513 if (bt == VT_LDOUBLE) {
1520 uint32_t a, b, f = fltr(gv(RC_FLOAT));1514 uint32_t a, b, f = fltr(gv(S, RC_FLOAT));
1521 a = get_reg(RC_INT);1515 a = get_reg(S, RC_INT);
1522 vpushi(0);1516 vpushi(S, 0);
1523 vtop[0].r = a;1517 S->tccgen_vtop[0].r = a;
1524 b = get_reg(RC_INT);1518 b = get_reg(S, RC_INT);
1525 a = intr(a);1519 a = intr(S, a);
1526 b = intr(b);1520 b = intr(S, b);
1527 o(0x4e083c00 | a | f << 5); // mov x(a),v(f).d[0]1521 o(S, 0x4e083c00 | a | f << 5); // mov x(a),v(f).d[0]
1528 o(0x4e183c00 | b | f << 5); // mov x(b),v(f).d[1]1522 o(S, 0x4e183c00 | b | f << 5); // mov x(b),v(f).d[1]
1529 o(0xaa000400 | a | a << 5 | b << 16); // orr x(a),x(a),x(b),lsl #11523 o(S, 0xaa000400 | a | a << 5 | b << 16); // orr x(a),x(a),x(b),lsl #1
1530 o(0xb4000040 | a | !!inv << 24); // cbz/cbnz x(a),.+81524 o(S, 0xb4000040 | a | !!inv << 24); // cbz/cbnz x(a),.+8
1531 --vtop;1525 --S->tccgen_vtop;
1532 }1526 }
1533 else if (bt == VT_FLOAT || bt == VT_DOUBLE) {1527 else if (bt == VT_FLOAT || bt == VT_DOUBLE) {
1534 uint32_t a = fltr(gv(RC_FLOAT));1528 uint32_t a = fltr(gv(S, RC_FLOAT));
1535 o(0x1e202008 | a << 5 | (bt != VT_FLOAT) << 22); // fcmp1529 o(S, 0x1e202008 | a << 5 | (bt != VT_FLOAT) << 22); // fcmp
1536 o(0x54000040 | !!inv); // b.eq/b.ne .+81530 o(S, 0x54000040 | !!inv); // b.eq/b.ne .+8
1537 }1531 }
1538 else {1532 else {
1539 uint32_t ll = (bt == VT_PTR || bt == VT_LLONG);1533 uint32_t ll = (bt == VT_PTR || bt == VT_LLONG);
1540 uint32_t a = intr(gv(RC_INT));1534 uint32_t a = intr(S, gv(S, RC_INT));
1541 o(0x34000040 | a | !!inv << 24 | ll << 31); // cbz/cbnz wA,.+81535 o(S, 0x34000040 | a | !!inv << 24 | ll << 31); // cbz/cbnz wA,.+8
1542 }1536 }
1543 return gjmp(t);1537 return gjmp(S, t);
1544}1538}
1545 1539
1546static int arm64_iconst(uint64_t *val, SValue *sv)1540static int arm64_iconst(uint64_t *val, SValue *sv)
@@ -1557,7 +1551,7 @@ static int arm64_iconst(uint64_t *val, SValue *sv) · 10 unmodified lines
1557 return 1;1551 return 1;
1558}1552}
1559 1553
1560static int arm64_gen_opic(int op, uint32_t l, int rev, uint64_t val,1554static int arm64_gen_opic(TCCState *S, int op, uint32_t l, int rev, uint64_t val,
1561 uint32_t x, uint32_t a)1555 uint32_t x, uint32_t a)
1562{1556{
1563 if (op == '-' && !rev) {1557 if (op == '-' && !rev) {
@@ -1573,30 +1567,30 @@ static int arm64_gen_opic(int op, uint32_t l, int rev, uint64_t val, · 9 unmodified lines
1573 val = s ? -val : val;1567 val = s ? -val : val;
1574 val = l ? val : (uint32_t)val;1568 val = l ? val : (uint32_t)val;
1575 if (!(val & ~(uint64_t)0xfff))1569 if (!(val & ~(uint64_t)0xfff))
1576 o(0x11000000 | l << 31 | s << 30 | x | a << 5 | val << 10);1570 o(S, 0x11000000 | l << 31 | s << 30 | x | a << 5 | val << 10);
1577 else if (!(val & ~(uint64_t)0xfff000))1571 else if (!(val & ~(uint64_t)0xfff000))
1578 o(0x11400000 | l << 31 | s << 30 | x | a << 5 | val >> 12 << 10);1572 o(S, 0x11400000 | l << 31 | s << 30 | x | a << 5 | val >> 12 << 10);
1579 else {1573 else {
1580 arm64_movimm(30, val); // use x301574 arm64_movimm(S, 30, val); // use x30
1581 o(0x0b1e0000 | l << 31 | s << 30 | x | a << 5);1575 o(S, 0x0b1e0000 | l << 31 | s << 30 | x | a << 5);
1582 }1576 }
1583 return 1;1577 return 1;
1584 }1578 }
1585 1579
1586 case '-':1580 case '-':
1587 if (!val)1581 if (!val)
1588 o(0x4b0003e0 | l << 31 | x | a << 16); // neg1582 o(S, 0x4b0003e0 | l << 31 | x | a << 16); // neg
1589 else if (val == (l ? (uint64_t)-1 : (uint32_t)-1))1583 else if (val == (l ? (uint64_t)-1 : (uint32_t)-1))
1590 o(0x2a2003e0 | l << 31 | x | a << 16); // mvn1584 o(S, 0x2a2003e0 | l << 31 | x | a << 16); // mvn
1591 else {1585 else {
1592 arm64_movimm(30, val); // use x301586 arm64_movimm(S, 30, val); // use x30
1593 o(0x4b0003c0 | l << 31 | x | a << 16); // sub1587 o(S, 0x4b0003c0 | l << 31 | x | a << 16); // sub
1594 }1588 }
1595 return 1;1589 return 1;
1596 1590
1597 case '^':1591 case '^':
1598 if (val == -1 || (val == 0xffffffff && !l)) {1592 if (val == -1 || (val == 0xffffffff && !l)) {
1599 o(0x2a2003e0 | l << 31 | x | a << 16); // mvn1593 o(S, 0x2a2003e0 | l << 31 | x | a << 16); // mvn
1600 return 1;1594 return 1;
1601 }1595 }
1602 // fall through1596 // fall through
@@ -1605,7 +1599,7 @@ static int arm64_gen_opic(int op, uint32_t l, int rev, uint64_t val, · 2 unmodified lines
1605 int e = arm64_encode_bimm64(l ? val : val | val << 32);1599 int e = arm64_encode_bimm64(l ? val : val | val << 32);
1606 if (e < 0)1600 if (e < 0)
1607 return 0;1601 return 0;
1608 o((op == '&' ? 0x12000000 :1602 o(S, (op == '&' ? 0x12000000 :
1609 op == '|' ? 0x32000000 : 0x52000000) |1603 op == '|' ? 0x32000000 : 0x52000000) |
1610 l << 31 | x | a << 5 | (uint32_t)e << 10);1604 l << 31 | x | a << 5 | (uint32_t)e << 10);
1611 return 1;1605 return 1;
@@ -1620,14 +1614,14 @@ static int arm64_gen_opic(int op, uint32_t l, int rev, uint64_t val, · 8 unmodified lines
1620 return 0;1614 return 0;
1621 if (!val) {1615 if (!val) {
1622 // tcc_warning("shift count >= width of type");1616 // tcc_warning("shift count >= width of type");
1623 o(0x2a0003e0 | l << 31 | a << 16);1617 o(S, 0x2a0003e0 | l << 31 | a << 16);
1624 return 1;1618 return 1;
1625 }1619 }
1626 else if (op == TOK_SHL)1620 else if (op == TOK_SHL)
1627 o(0x53000000 | l << 31 | l << 22 | x | a << 5 |1621 o(S, 0x53000000 | l << 31 | l << 22 | x | a << 5 |
1628 (n - val) << 16 | (n - 1 - val) << 10); // lsl1622 (n - val) << 16 | (n - 1 - val) << 10); // lsl
1629 else1623 else
1630 o(0x13000000 | (op == TOK_SHR) << 30 | l << 31 | l << 22 |1624 o(S, 0x13000000 | (op == TOK_SHR) << 30 | l << 31 | l << 22 |
1631 x | a << 5 | val << 16 | (n - 1) << 10); // lsr/asr1625 x | a << 5 | val << 16 | (n - 1) << 10); // lsr/asr
1632 return 1;1626 return 1;
1633 }1627 }
@@ -1636,7 +1630,7 @@ static int arm64_gen_opic(int op, uint32_t l, int rev, uint64_t val, · 2 unmodified lines
1636 return 0;1630 return 0;
1637}1631}
1638 1632
1639static void arm64_gen_opil(int op, uint32_t l)1633static void arm64_gen_opil(TCCState *S, int op, uint32_t l)
1640{1634{
1641 uint32_t x, a, b;1635 uint32_t x, a, b;
1642 1636
@@ -1645,122 +1639,122 @@ static void arm64_gen_opil(int op, uint32_t l) · 2 unmodified lines
1645 uint64_t val;1639 uint64_t val;
1646 int rev = 1;1640 int rev = 1;
1647 1641
1648 if (arm64_iconst(0, &vtop[0])) {1642 if (arm64_iconst(0, &S->tccgen_vtop[0])) {
1649 vswap();1643 vswap(S);
1650 rev = 0;1644 rev = 0;
1651 }1645 }
1652 if (arm64_iconst(&val, &vtop[-1])) {1646 if (arm64_iconst(&val, &S->tccgen_vtop[-1])) {
1653 gv(RC_INT);1647 gv(S, RC_INT);
1654 a = intr(vtop[0].r);1648 a = intr(S, S->tccgen_vtop[0].r);
1655 --vtop;1649 --S->tccgen_vtop;
1656 x = get_reg(RC_INT);1650 x = get_reg(S, RC_INT);
1657 ++vtop;1651 ++S->tccgen_vtop;
1658 if (arm64_gen_opic(op, l, rev, val, intr(x), a)) {1652 if (arm64_gen_opic(S, op, l, rev, val, intr(S, x), a)) {
1659 vtop[0].r = x;1653 S->tccgen_vtop[0].r = x;
1660 vswap();1654 vswap(S);
1661 --vtop;1655 --S->tccgen_vtop;
1662 return;1656 return;
1663 }1657 }
1664 }1658 }
1665 if (!rev)1659 if (!rev)
1666 vswap();1660 vswap(S);
1667 }1661 }
1668 1662
1669 gv2(RC_INT, RC_INT);1663 gv2(S, RC_INT, RC_INT);
1670 assert(vtop[-1].r < VT_CONST && vtop[0].r < VT_CONST);1664 assert(S->tccgen_vtop[-1].r < VT_CONST && S->tccgen_vtop[0].r < VT_CONST);
1671 a = intr(vtop[-1].r);1665 a = intr(S, S->tccgen_vtop[-1].r);
1672 b = intr(vtop[0].r);1666 b = intr(S, S->tccgen_vtop[0].r);
1673 vtop -= 2;1667 S->tccgen_vtop -= 2;
1674 x = get_reg(RC_INT);1668 x = get_reg(S, RC_INT);
1675 ++vtop;1669 ++S->tccgen_vtop;
1676 vtop[0].r = x;1670 S->tccgen_vtop[0].r = x;
1677 x = intr(x);1671 x = intr(S, x);
1678 1672
1679 switch (op) {1673 switch (op) {
1680 case '%':1674 case '%':
1681 // Use x30 for quotient:1675 // Use x30 for quotient:
1682 o(0x1ac00c00 | l << 31 | 30 | a << 5 | b << 16); // sdiv1676 o(S, 0x1ac00c00 | l << 31 | 30 | a << 5 | b << 16); // sdiv
1683 o(0x1b008000 | l << 31 | x | (uint32_t)30 << 5 |1677 o(S, 0x1b008000 | l << 31 | x | (uint32_t)30 << 5 |
1684 b << 16 | a << 10); // msub1678 b << 16 | a << 10); // msub
1685 break;1679 break;
1686 case '&':1680 case '&':
1687 o(0x0a000000 | l << 31 | x | a << 5 | b << 16); // and1681 o(S, 0x0a000000 | l << 31 | x | a << 5 | b << 16); // and
1688 break;1682 break;
1689 case '*':1683 case '*':
1690 o(0x1b007c00 | l << 31 | x | a << 5 | b << 16); // mul1684 o(S, 0x1b007c00 | l << 31 | x | a << 5 | b << 16); // mul
1691 break;1685 break;
1692 case '+':1686 case '+':
1693 o(0x0b000000 | l << 31 | x | a << 5 | b << 16); // add1687 o(S, 0x0b000000 | l << 31 | x | a << 5 | b << 16); // add
1694 break;1688 break;
1695 case '-':1689 case '-':
1696 o(0x4b000000 | l << 31 | x | a << 5 | b << 16); // sub1690 o(S, 0x4b000000 | l << 31 | x | a << 5 | b << 16); // sub
1697 break;1691 break;
1698 case '/':1692 case '/':
1699 o(0x1ac00c00 | l << 31 | x | a << 5 | b << 16); // sdiv1693 o(S, 0x1ac00c00 | l << 31 | x | a << 5 | b << 16); // sdiv
1700 break;1694 break;
1701 case '^':1695 case '^':
1702 o(0x4a000000 | l << 31 | x | a << 5 | b << 16); // eor1696 o(S, 0x4a000000 | l << 31 | x | a << 5 | b << 16); // eor
1703 break;1697 break;
1704 case '|':1698 case '|':
1705 o(0x2a000000 | l << 31 | x | a << 5 | b << 16); // orr1699 o(S, 0x2a000000 | l << 31 | x | a << 5 | b << 16); // orr
1706 break;1700 break;
1707 case TOK_EQ:1701 case TOK_EQ:
1708 o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp1702 o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
1709 o(0x1a9f17e0 | x); // cset wA,eq1703 o(S, 0x1a9f17e0 | x); // cset wA,eq
1710 break;1704 break;
1711 case TOK_GE:1705 case TOK_GE:
1712 o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp1706 o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
1713 o(0x1a9fb7e0 | x); // cset wA,ge1707 o(S, 0x1a9fb7e0 | x); // cset wA,ge
1714 break;1708 break;
1715 case TOK_GT:1709 case TOK_GT:
1716 o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp1710 o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
1717 o(0x1a9fd7e0 | x); // cset wA,gt1711 o(S, 0x1a9fd7e0 | x); // cset wA,gt
1718 break;1712 break;
1719 case TOK_LE:1713 case TOK_LE:
1720 o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp1714 o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
1721 o(0x1a9fc7e0 | x); // cset wA,le1715 o(S, 0x1a9fc7e0 | x); // cset wA,le
1722 break;1716 break;
1723 case TOK_LT:1717 case TOK_LT:
1724 o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp1718 o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
1725 o(0x1a9fa7e0 | x); // cset wA,lt1719 o(S, 0x1a9fa7e0 | x); // cset wA,lt
1726 break;1720 break;
1727 case TOK_NE:1721 case TOK_NE:
1728 o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp1722 o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
1729 o(0x1a9f07e0 | x); // cset wA,ne1723 o(S, 0x1a9f07e0 | x); // cset wA,ne
1730 break;1724 break;
1731 case TOK_SAR:1725 case TOK_SAR:
1732 o(0x1ac02800 | l << 31 | x | a << 5 | b << 16); // asr1726 o(S, 0x1ac02800 | l << 31 | x | a << 5 | b << 16); // asr
1733 break;1727 break;
1734 case TOK_SHL:1728 case TOK_SHL:
1735 o(0x1ac02000 | l << 31 | x | a << 5 | b << 16); // lsl1729 o(S, 0x1ac02000 | l << 31 | x | a << 5 | b << 16); // lsl
1736 break;1730 break;
1737 case TOK_SHR:1731 case TOK_SHR:
1738 o(0x1ac02400 | l << 31 | x | a << 5 | b << 16); // lsr1732 o(S, 0x1ac02400 | l << 31 | x | a << 5 | b << 16); // lsr
1739 break;1733 break;
1740 case TOK_UDIV:1734 case TOK_UDIV:
1741 case TOK_PDIV:1735 case TOK_PDIV:
1742 o(0x1ac00800 | l << 31 | x | a << 5 | b << 16); // udiv1736 o(S, 0x1ac00800 | l << 31 | x | a << 5 | b << 16); // udiv
1743 break;1737 break;
1744 case TOK_UGE:1738 case TOK_UGE:
1745 o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp1739 o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
1746 o(0x1a9f37e0 | x); // cset wA,cs1740 o(S, 0x1a9f37e0 | x); // cset wA,cs
1747 break;1741 break;
1748 case TOK_UGT:1742 case TOK_UGT:
1749 o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp1743 o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
1750 o(0x1a9f97e0 | x); // cset wA,hi1744 o(S, 0x1a9f97e0 | x); // cset wA,hi
1751 break;1745 break;
1752 case TOK_ULT:1746 case TOK_ULT:
1753 o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp1747 o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
1754 o(0x1a9f27e0 | x); // cset wA,cc1748 o(S, 0x1a9f27e0 | x); // cset wA,cc
1755 break;1749 break;
1756 case TOK_ULE:1750 case TOK_ULE:
1757 o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp1751 o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
1758 o(0x1a9f87e0 | x); // cset wA,ls1752 o(S, 0x1a9f87e0 | x); // cset wA,ls
1759 break;1753 break;
1760 case TOK_UMOD:1754 case TOK_UMOD:
1761 // Use x30 for quotient:1755 // Use x30 for quotient:
1762 o(0x1ac00800 | l << 31 | 30 | a << 5 | b << 16); // udiv1756 o(S, 0x1ac00800 | l << 31 | 30 | a << 5 | b << 16); // udiv
1763 o(0x1b008000 | l << 31 | x | (uint32_t)30 << 5 |1757 o(S, 0x1b008000 | l << 31 | x | (uint32_t)30 << 5 |
1764 b << 16 | a << 10); // msub1758 b << 16 | a << 10); // msub
1765 break;1759 break;
1766 default:1760 default:
@@ -1768,24 +1762,24 @@ static void arm64_gen_opil(int op, uint32_t l) · 1 unmodified line
1768 }1762 }
1769}1763}
1770 1764
1771ST_FUNC void gen_opi(int op)1765ST_FUNC void gen_opi(TCCState *S, int op)
1772{1766{
1773 arm64_gen_opil(op, 0);1767 arm64_gen_opil(S, op, 0);
1774 arm64_vset_VT_CMP(op);1768 arm64_vset_VT_CMP(S, op);
1775}1769}
1776 1770
1777ST_FUNC void gen_opl(int op)1771ST_FUNC void gen_opl(TCCState* S, int op)
1778{1772{
1779 arm64_gen_opil(op, 1);1773 arm64_gen_opil(S, op, 1);
1780 arm64_vset_VT_CMP(op);1774 arm64_vset_VT_CMP(S, op);
1781}1775}
1782 1776
1783ST_FUNC void gen_opf(int op)1777ST_FUNC void gen_opf(TCCState *S, int op)
1784{1778{
1785 uint32_t x, a, b, dbl;1779 uint32_t x, a, b, dbl;
1786 1780
1787 if (vtop[0].type.t == VT_LDOUBLE) {1781 if (S->tccgen_vtop[0].type.t == VT_LDOUBLE) {
1788 CType type = vtop[0].type;1782 CType type = S->tccgen_vtop[0].type;
1789 int func = 0;1783 int func = 0;
1790 int cond = -1;1784 int cond = -1;
1791 switch (op) {1785 switch (op) {
@@ -1801,162 +1795,162 @@ ST_FUNC void gen_opf(int op) · 9 unmodified lines
1801 case TOK_GT: func = TOK___gttf2; cond = 13; break;1795 case TOK_GT: func = TOK___gttf2; cond = 13; break;
1802 default: assert(0); break;1796 default: assert(0); break;
1803 }1797 }
1804 vpush_helper_func(func);1798 vpush_helper_func(S, func);
1805 vrott(3);1799 vrott(S, 3);
1806 gfunc_call(2);1800 gfunc_call(S, 2);
1807 vpushi(0);1801 vpushi(S, 0);
1808 vtop->r = cond < 0 ? REG_FRET : REG_IRET;1802 S->tccgen_vtop->r = cond < 0 ? REG_FRET : REG_IRET;
1809 if (cond < 0)1803 if (cond < 0)
1810 vtop->type = type;1804 S->tccgen_vtop->type = type;
1811 else {1805 else {
1812 o(0x7100001f); // cmp w0,#01806 o(S, 0x7100001f); // cmp w0,#0
1813 o(0x1a9f07e0 | (uint32_t)cond << 12); // cset w0,(cond)1807 o(S, 0x1a9f07e0 | (uint32_t)cond << 12); // cset w0,(cond)
1814 }1808 }
1815 return;1809 return;
1816 }1810 }
1817 1811
1818 dbl = vtop[0].type.t != VT_FLOAT;1812 dbl = S->tccgen_vtop[0].type.t != VT_FLOAT;
1819 gv2(RC_FLOAT, RC_FLOAT);1813 gv2(S, RC_FLOAT, RC_FLOAT);
1820 assert(vtop[-1].r < VT_CONST && vtop[0].r < VT_CONST);1814 assert(S->tccgen_vtop[-1].r < VT_CONST && S->tccgen_vtop[0].r < VT_CONST);
1821 a = fltr(vtop[-1].r);1815 a = fltr(S->tccgen_vtop[-1].r);
1822 b = fltr(vtop[0].r);1816 b = fltr(S->tccgen_vtop[0].r);
1823 vtop -= 2;1817 S->tccgen_vtop -= 2;
1824 switch (op) {1818 switch (op) {
1825 case TOK_EQ: case TOK_NE:1819 case TOK_EQ: case TOK_NE:
1826 case TOK_LT: case TOK_GE: case TOK_LE: case TOK_GT:1820 case TOK_LT: case TOK_GE: case TOK_LE: case TOK_GT:
1827 x = get_reg(RC_INT);1821 x = get_reg(S, RC_INT);
1828 ++vtop;1822 ++S->tccgen_vtop;
1829 vtop[0].r = x;1823 S->tccgen_vtop[0].r = x;
1830 x = intr(x);1824 x = intr(S, x);
1831 break;1825 break;
1832 default:1826 default:
1833 x = get_reg(RC_FLOAT);1827 x = get_reg(S, RC_FLOAT);
1834 ++vtop;1828 ++S->tccgen_vtop;
1835 vtop[0].r = x;1829 S->tccgen_vtop[0].r = x;
1836 x = fltr(x);1830 x = fltr(x);
1837 break;1831 break;
1838 }1832 }
1839 1833
1840 switch (op) {1834 switch (op) {
1841 case '*':1835 case '*':
1842 o(0x1e200800 | dbl << 22 | x | a << 5 | b << 16); // fmul1836 o(S, 0x1e200800 | dbl << 22 | x | a << 5 | b << 16); // fmul
1843 break;1837 break;
1844 case '+':1838 case '+':
1845 o(0x1e202800 | dbl << 22 | x | a << 5 | b << 16); // fadd1839 o(S, 0x1e202800 | dbl << 22 | x | a << 5 | b << 16); // fadd
1846 break;1840 break;
1847 case '-':1841 case '-':
1848 o(0x1e203800 | dbl << 22 | x | a << 5 | b << 16); // fsub1842 o(S, 0x1e203800 | dbl << 22 | x | a << 5 | b << 16); // fsub
1849 break;1843 break;
1850 case '/':1844 case '/':
1851 o(0x1e201800 | dbl << 22 | x | a << 5 | b << 16); // fdiv1845 o(S, 0x1e201800 | dbl << 22 | x | a << 5 | b << 16); // fdiv
1852 break;1846 break;
1853 case TOK_EQ:1847 case TOK_EQ:
1854 o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp1848 o(S, 0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
1855 o(0x1a9f17e0 | x); // cset w(x),eq1849 o(S, 0x1a9f17e0 | x); // cset w(x),eq
1856 break;1850 break;
1857 case TOK_GE:1851 case TOK_GE:
1858 o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp1852 o(S, 0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
1859 o(0x1a9fb7e0 | x); // cset w(x),ge1853 o(S, 0x1a9fb7e0 | x); // cset w(x),ge
1860 break;1854 break;
1861 case TOK_GT:1855 case TOK_GT:
1862 o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp1856 o(S, 0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
1863 o(0x1a9fd7e0 | x); // cset w(x),gt1857 o(S, 0x1a9fd7e0 | x); // cset w(x),gt
1864 break;1858 break;
1865 case TOK_LE:1859 case TOK_LE:
1866 o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp1860 o(S, 0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
1867 o(0x1a9f87e0 | x); // cset w(x),ls1861 o(S, 0x1a9f87e0 | x); // cset w(x),ls
1868 break;1862 break;
1869 case TOK_LT:1863 case TOK_LT:
1870 o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp1864 o(S, 0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
1871 o(0x1a9f57e0 | x); // cset w(x),mi1865 o(S, 0x1a9f57e0 | x); // cset w(x),mi
1872 break;1866 break;
1873 case TOK_NE:1867 case TOK_NE:
1874 o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp1868 o(S, 0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
1875 o(0x1a9f07e0 | x); // cset w(x),ne1869 o(S, 0x1a9f07e0 | x); // cset w(x),ne
1876 break;1870 break;
1877 default:1871 default:
1878 assert(0);1872 assert(0);
1879 }1873 }
1880 arm64_vset_VT_CMP(op);1874 arm64_vset_VT_CMP(S, op);
1881}1875}
1882 1876
1883// Generate sign extension from 32 to 64 bits:1877// Generate sign extension from 32 to 64 bits:
1884ST_FUNC void gen_cvt_sxtw(void)1878ST_FUNC void gen_cvt_sxtw(TCCState *S)
1885{1879{
1886 uint32_t r = intr(gv(RC_INT));1880 uint32_t r = intr(S, gv(S, RC_INT));
1887 o(0x93407c00 | r | r << 5); // sxtw x(r),w(r)1881 o(S, 0x93407c00 | r | r << 5); // sxtw x(r),w(r)
1888}1882}
1889 1883
1890/* char/short to int conversion */1884/* char/short to int conversion */
1891ST_FUNC void gen_cvt_csti(int t)1885ST_FUNC void gen_cvt_csti(TCCState *S, int t)
1892{1886{
1893 int r = intr(gv(RC_INT));1887 int r = intr(S, gv(S, RC_INT));
1894 o(0x13001c001888 o(S, 0x13001c00
1895 | ((t & VT_BTYPE) == VT_SHORT) << 131889 | ((t & VT_BTYPE) == VT_SHORT) << 13
1896 | (uint32_t)!!(t & VT_UNSIGNED) << 301890 | (uint32_t)!!(t & VT_UNSIGNED) << 30
1897 | r | r << 5); // [su]xt[bh] w(r),w(r)1891 | r | r << 5); // [su]xt[bh] w(r),w(r)
1898}1892}
1899 1893
1900ST_FUNC void gen_cvt_itof(int t)1894ST_FUNC void gen_cvt_itof(TCCState *S, int t)
1901{1895{
1902 if (t == VT_LDOUBLE) {1896 if (t == VT_LDOUBLE) {
1903 int f = vtop->type.t;1897 int f = S->tccgen_vtop->type.t;
1904 int func = (f & VT_BTYPE) == VT_LLONG ?1898 int func = (f & VT_BTYPE) == VT_LLONG ?
1905 (f & VT_UNSIGNED ? TOK___floatunditf : TOK___floatditf) :1899 (f & VT_UNSIGNED ? TOK___floatunditf : TOK___floatditf) :
1906 (f & VT_UNSIGNED ? TOK___floatunsitf : TOK___floatsitf);1900 (f & VT_UNSIGNED ? TOK___floatunsitf : TOK___floatsitf);
1907 vpush_helper_func(func);1901 vpush_helper_func(S, func);
1908 vrott(2);1902 vrott(S, 2);
1909 gfunc_call(1);1903 gfunc_call(S, 1);
1910 vpushi(0);1904 vpushi(S, 0);
1911 vtop->type.t = t;1905 S->tccgen_vtop->type.t = t;
1912 vtop->r = REG_FRET;1906 S->tccgen_vtop->r = REG_FRET;
1913 return;1907 return;
1914 }1908 }
1915 else {1909 else {
1916 int d, n = intr(gv(RC_INT));1910 int d, n = intr(S, gv(S, RC_INT));
1917 int s = !(vtop->type.t & VT_UNSIGNED);1911 int s = !(S->tccgen_vtop->type.t & VT_UNSIGNED);
1918 uint32_t l = ((vtop->type.t & VT_BTYPE) == VT_LLONG);1912 uint32_t l = ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG);
1919 --vtop;1913 --S->tccgen_vtop;
1920 d = get_reg(RC_FLOAT);1914 d = get_reg(S, RC_FLOAT);
1921 ++vtop;1915 ++S->tccgen_vtop;
1922 vtop[0].r = d;1916 S->tccgen_vtop[0].r = d;
1923 o(0x1e220000 | (uint32_t)!s << 16 |1917 o(S, 0x1e220000 | (uint32_t)!s << 16 |
1924 (uint32_t)(t != VT_FLOAT) << 22 | fltr(d) |1918 (uint32_t)(t != VT_FLOAT) << 22 | fltr(d) |
1925 l << 31 | n << 5); // [us]cvtf [sd](d),[wx](n)1919 l << 31 | n << 5); // [us]cvtf [sd](d),[wx](n)
1926 }1920 }
1927}1921}
1928 1922
1929ST_FUNC void gen_cvt_ftoi(int t)1923ST_FUNC void gen_cvt_ftoi(TCCState *S, int t)
1930{1924{
1931 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {1925 if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
1932 int func = (t & VT_BTYPE) == VT_LLONG ?1926 int func = (t & VT_BTYPE) == VT_LLONG ?
1933 (t & VT_UNSIGNED ? TOK___fixunstfdi : TOK___fixtfdi) :1927 (t & VT_UNSIGNED ? TOK___fixunstfdi : TOK___fixtfdi) :
1934 (t & VT_UNSIGNED ? TOK___fixunstfsi : TOK___fixtfsi);1928 (t & VT_UNSIGNED ? TOK___fixunstfsi : TOK___fixtfsi);
1935 vpush_helper_func(func);1929 vpush_helper_func(S, func);
1936 vrott(2);1930 vrott(S, 2);
1937 gfunc_call(1);1931 gfunc_call(S, 1);
1938 vpushi(0);1932 vpushi(S, 0);
1939 vtop->type.t = t;1933 S->tccgen_vtop->type.t = t;
1940 vtop->r = REG_IRET;1934 S->tccgen_vtop->r = REG_IRET;
1941 return;1935 return;
1942 }1936 }
1943 else {1937 else {
1944 int d, n = fltr(gv(RC_FLOAT));1938 int d, n = fltr(gv(S, RC_FLOAT));
1945 uint32_t l = ((vtop->type.t & VT_BTYPE) != VT_FLOAT);1939 uint32_t l = ((S->tccgen_vtop->type.t & VT_BTYPE) != VT_FLOAT);
1946 --vtop;1940 --S->tccgen_vtop;
1947 d = get_reg(RC_INT);1941 d = get_reg(S, RC_INT);
1948 ++vtop;1942 ++S->tccgen_vtop;
1949 vtop[0].r = d;1943 S->tccgen_vtop[0].r = d;
1950 o(0x1e380000 |1944 o(S, 0x1e380000 |
1951 (uint32_t)!!(t & VT_UNSIGNED) << 16 |1945 (uint32_t)!!(t & VT_UNSIGNED) << 16 |
1952 (uint32_t)((t & VT_BTYPE) == VT_LLONG) << 31 | intr(d) |1946 (uint32_t)((t & VT_BTYPE) == VT_LLONG) << 31 | intr(S, d) |
1953 l << 22 | n << 5); // fcvtz[su] [wx](d),[sd](n)1947 l << 22 | n << 5); // fcvtz[su] [wx](d),[sd](n)
1954 }1948 }
1955}1949}
1956 1950
1957ST_FUNC void gen_cvt_ftof(int t)1951ST_FUNC void gen_cvt_ftof(TCCState *S, int t)
1958{1952{
1959 int f = vtop[0].type.t & VT_BTYPE;1953 int f = S->tccgen_vtop[0].type.t & VT_BTYPE;
1960 assert(t == VT_FLOAT || t == VT_DOUBLE || t == VT_LDOUBLE);1954 assert(t == VT_FLOAT || t == VT_DOUBLE || t == VT_LDOUBLE);
1961 assert(f == VT_FLOAT || f == VT_DOUBLE || f == VT_LDOUBLE);1955 assert(f == VT_FLOAT || f == VT_DOUBLE || f == VT_LDOUBLE);
1962 if (t == f)1956 if (t == f)
@@ -1966,142 +1960,142 @@ ST_FUNC void gen_cvt_ftof(int t) · 3 unmodified lines
1966 int func = (t == VT_LDOUBLE) ?1960 int func = (t == VT_LDOUBLE) ?
1967 (f == VT_FLOAT ? TOK___extendsftf2 : TOK___extenddftf2) :1961 (f == VT_FLOAT ? TOK___extendsftf2 : TOK___extenddftf2) :
1968 (t == VT_FLOAT ? TOK___trunctfsf2 : TOK___trunctfdf2);1962 (t == VT_FLOAT ? TOK___trunctfsf2 : TOK___trunctfdf2);
1969 vpush_helper_func(func);1963 vpush_helper_func(S, func);
1970 vrott(2);1964 vrott(S, 2);
1971 gfunc_call(1);1965 gfunc_call(S, 1);
1972 vpushi(0);1966 vpushi(S, 0);
1973 vtop->type.t = t;1967 S->tccgen_vtop->type.t = t;
1974 vtop->r = REG_FRET;1968 S->tccgen_vtop->r = REG_FRET;
1975 }1969 }
1976 else {1970 else {
1977 int x, a;1971 int x, a;
1978 gv(RC_FLOAT);1972 gv(S, RC_FLOAT);
1979 assert(vtop[0].r < VT_CONST);1973 assert(S->tccgen_vtop[0].r < VT_CONST);
1980 a = fltr(vtop[0].r);1974 a = fltr(S->tccgen_vtop[0].r);
1981 --vtop;1975 --S->tccgen_vtop;
1982 x = get_reg(RC_FLOAT);1976 x = get_reg(S, RC_FLOAT);
1983 ++vtop;1977 ++S->tccgen_vtop;
1984 vtop[0].r = x;1978 S->tccgen_vtop[0].r = x;
1985 x = fltr(x);1979 x = fltr(x);
1986 1980
1987 if (f == VT_FLOAT)1981 if (f == VT_FLOAT)
1988 o(0x1e22c000 | x | a << 5); // fcvt d(x),s(a)1982 o(S, 0x1e22c000 | x | a << 5); // fcvt d(x),s(a)
1989 else1983 else
1990 o(0x1e624000 | x | a << 5); // fcvt s(x),d(a)1984 o(S, 0x1e624000 | x | a << 5); // fcvt s(x),d(a)
1991 }1985 }
1992}1986}
1993 1987
1994/* increment tcov counter */1988/* increment tcov counter */
1995ST_FUNC void gen_increment_tcov (SValue *sv)1989ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv)
1996{1990{
1997 int r1, r2;1991 int r1, r2;
1998 1992
1999 vpushv(sv);1993 vpushv(S, sv);
2000 vtop->r = r1 = get_reg(RC_INT);1994 S->tccgen_vtop->r = r1 = get_reg(S, RC_INT);
2001 r2 = get_reg(RC_INT);1995 r2 = get_reg(S, RC_INT);
2002 greloca(cur_text_section, sv->sym, ind, R_AARCH64_ADR_GOT_PAGE, 0);1996 greloca(S, cur_text_section, sv->sym, S->tccgen_ind, R_AARCH64_ADR_GOT_PAGE, 0);
2003 o(0x90000000 | r1); // adrp r1, #sym1997 o(S, 0x90000000 | r1); // adrp r1, #sym
2004 greloca(cur_text_section, sv->sym, ind, R_AARCH64_LD64_GOT_LO12_NC, 0);1998 greloca(S, cur_text_section, sv->sym, S->tccgen_ind, R_AARCH64_LD64_GOT_LO12_NC, 0);
2005 o(0xf9400000 | r1 | (r1 << 5)); // ld xr,[xr, #sym]1999 o(S, 0xf9400000 | r1 | (r1 << 5)); // ld xr,[xr, #sym]
2006 o(0xf9400000 | (intr(r1)<<5) | intr(r2)); // ldr r2, [r1]2000 o(S, 0xf9400000 | (intr(S, r1)<<5) | intr(S, r2)); // ldr r2, [r1]
2007 o(0x91000400 | (intr(r2)<<5) | intr(r2)); // add r2, r2, #12001 o(S, 0x91000400 | (intr(S, r2)<<5) | intr(S, r2)); // add r2, r2, #1
2008 o(0xf9000000 | (intr(r1)<<5) | intr(r2)); // str r2, [r1]2002 o(S, 0xf9000000 | (intr(S, r1)<<5) | intr(S, r2)); // str r2, [r1]
2009 vpop();2003 vpop(S);
2010}2004}
2011 2005
2012ST_FUNC void ggoto(void)2006ST_FUNC void ggoto(TCCState *S)
2013{2007{
2014 arm64_gen_bl_or_b(1);2008 arm64_gen_bl_or_b(S, 1);
2015 --vtop;2009 --S->tccgen_vtop;
2016}2010}
2017 2011
2018ST_FUNC void gen_clear_cache(void)2012ST_FUNC void gen_clear_cache(TCCState *S)
2019{2013{
2020 uint32_t beg, end, dsz, isz, p, lab1, b1;2014 uint32_t beg, end, dsz, isz, p, lab1, b1;
2021 gv2(RC_INT, RC_INT);2015 gv2(S, RC_INT, RC_INT);
2022 vpushi(0);2016 vpushi(S, 0);
2023 vtop->r = get_reg(RC_INT);2017 S->tccgen_vtop->r = get_reg(S, RC_INT);
2024 vpushi(0);2018 vpushi(S, 0);
2025 vtop->r = get_reg(RC_INT);2019 S->tccgen_vtop->r = get_reg(S, RC_INT);
2026 vpushi(0);2020 vpushi(S, 0);
2027 vtop->r = get_reg(RC_INT);2021 S->tccgen_vtop->r = get_reg(S, RC_INT);
2028 beg = intr(vtop[-4].r); // x02022 beg = intr(S, S->tccgen_vtop[-4].r); // x0
2029 end = intr(vtop[-3].r); // x12023 end = intr(S, S->tccgen_vtop[-3].r); // x1
2030 dsz = intr(vtop[-2].r); // x22024 dsz = intr(S, S->tccgen_vtop[-2].r); // x2
2031 isz = intr(vtop[-1].r); // x32025 isz = intr(S, S->tccgen_vtop[-1].r); // x3
2032 p = intr(vtop[0].r); // x42026 p = intr(S, S->tccgen_vtop[0].r); // x4
2033 vtop -= 5;2027 S->tccgen_vtop -= 5;
2034 2028
2035 o(0xd53b0020 | isz); // mrs x(isz),ctr_el02029 o(S, 0xd53b0020 | isz); // mrs x(isz),ctr_el0
2036 o(0x52800080 | p); // mov w(p),#42030 o(S, 0x52800080 | p); // mov w(p),#4
2037 o(0x53104c00 | dsz | isz << 5); // ubfx w(dsz),w(isz),#16,#42031 o(S, 0x53104c00 | dsz | isz << 5); // ubfx w(dsz),w(isz),#16,#4
2038 o(0x1ac02000 | dsz | p << 5 | dsz << 16); // lsl w(dsz),w(p),w(dsz)2032 o(S, 0x1ac02000 | dsz | p << 5 | dsz << 16); // lsl w(dsz),w(p),w(dsz)
2039 o(0x12000c00 | isz | isz << 5); // and w(isz),w(isz),#152033 o(S, 0x12000c00 | isz | isz << 5); // and w(isz),w(isz),#15
2040 o(0x1ac02000 | isz | p << 5 | isz << 16); // lsl w(isz),w(p),w(isz)2034 o(S, 0x1ac02000 | isz | p << 5 | isz << 16); // lsl w(isz),w(p),w(isz)
2041 o(0x51000400 | p | dsz << 5); // sub w(p),w(dsz),#12035 o(S, 0x51000400 | p | dsz << 5); // sub w(p),w(dsz),#1
2042 o(0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p)2036 o(S, 0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p)
2043 b1 = ind; o(0x14000000); // b2037 b1 = S->tccgen_ind; o(S, 0x14000000); // b
2044 lab1 = ind;2038 lab1 = S->tccgen_ind;
2045 o(0xd50b7b20 | p); // dc cvau,x(p)2039 o(S, 0xd50b7b20 | p); // dc cvau,x(p)
2046 o(0x8b000000 | p | p << 5 | dsz << 16); // add x(p),x(p),x(dsz)2040 o(S, 0x8b000000 | p | p << 5 | dsz << 16); // add x(p),x(p),x(dsz)
2047 write32le(cur_text_section->data + b1, 0x14000000 | (ind - b1) >> 2);2041 write32le(cur_text_section->data + b1, 0x14000000 | (S->tccgen_ind - b1) >> 2);
2048 o(0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end)2042 o(S, 0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end)
2049 o(0x54ffffa3 | ((lab1 - ind) << 3 & 0xffffe0)); // b.cc lab12043 o(S, 0x54ffffa3 | ((lab1 - S->tccgen_ind) << 3 & 0xffffe0)); // b.cc lab1
2050 o(0xd5033b9f); // dsb ish2044 o(S, 0xd5033b9f); // dsb ish
2051 o(0x51000400 | p | isz << 5); // sub w(p),w(isz),#12045 o(S, 0x51000400 | p | isz << 5); // sub w(p),w(isz),#1
2052 o(0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p)2046 o(S, 0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p)
2053 b1 = ind; o(0x14000000); // b2047 b1 = S->tccgen_ind; o(S, 0x14000000); // b
2054 lab1 = ind;2048 lab1 = S->tccgen_ind;
2055 o(0xd50b7520 | p); // ic ivau,x(p)2049 o(S, 0xd50b7520 | p); // ic ivau,x(p)
2056 o(0x8b000000 | p | p << 5 | isz << 16); // add x(p),x(p),x(isz)2050 o(S, 0x8b000000 | p | p << 5 | isz << 16); // add x(p),x(p),x(isz)
2057 write32le(cur_text_section->data + b1, 0x14000000 | (ind - b1) >> 2);2051 write32le(cur_text_section->data + b1, 0x14000000 | (S->tccgen_ind - b1) >> 2);
2058 o(0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end)2052 o(S, 0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end)
2059 o(0x54ffffa3 | ((lab1 - ind) << 3 & 0xffffe0)); // b.cc lab12053 o(S, 0x54ffffa3 | ((lab1 - S->tccgen_ind) << 3 & 0xffffe0)); // b.cc lab1
2060 o(0xd5033b9f); // dsb ish2054 o(S, 0xd5033b9f); // dsb ish
2061 o(0xd5033fdf); // isb2055 o(S, 0xd5033fdf); // isb
2062}2056}
2063 2057
2064ST_FUNC void gen_vla_sp_save(int addr) {2058ST_FUNC void gen_vla_sp_save(TCCState *S, int addr) {
2065 uint32_t r = intr(get_reg(RC_INT));2059 uint32_t r = intr(S, get_reg(S, RC_INT));
2066 o(0x910003e0 | r); // mov x(r),sp2060 o(S, 0x910003e0 | r); // mov x(r),sp
2067 arm64_strx(3, r, 29, addr);2061 arm64_strx(S, 3, r, 29, addr);
2068}2062}
2069 2063
2070ST_FUNC void gen_vla_sp_restore(int addr) {2064ST_FUNC void gen_vla_sp_restore(TCCState *S, int addr) {
2071 // Use x30 because this function can be called when there2065 // Use x30 because this function can be called when there
2072 // is a live return value in x0 but there is nothing on2066 // is a live return value in x0 but there is nothing on
2073 // the value stack to prevent get_reg from returning x0.2067 // the value stack to prevent get_reg from returning x0.
2074 uint32_t r = 30;2068 uint32_t r = 30;
2075 arm64_ldrx(0, 3, r, 29, addr);2069 arm64_ldrx(S, 0, 3, r, 29, addr);
2076 o(0x9100001f | r << 5); // mov sp,x(r)2070 o(S, 0x9100001f | r << 5); // mov sp,x(r)
2077}2071}
2078 2072
2079ST_FUNC void gen_vla_alloc(CType *type, int align) {2073ST_FUNC void gen_vla_alloc(TCCState *S, CType *type, int align) {
2080 uint32_t r;2074 uint32_t r;
2081#if defined(CONFIG_TCC_BCHECK)2075#if defined(CONFIG_TCC_BCHECK)
2082 if (tcc_state->do_bounds_check)2076 if (S->do_bounds_check)
2083 vpushv(vtop);2077 vpushv(S, S->tccgen_vtop);
2084#endif2078#endif
2085 r = intr(gv(RC_INT));2079 r = intr(S, gv(S, RC_INT));
2086#if defined(CONFIG_TCC_BCHECK)2080#if defined(CONFIG_TCC_BCHECK)
2087 if (tcc_state->do_bounds_check)2081 if (S->do_bounds_check)
2088 o(0x91004000 | r | r << 5); // add x(r),x(r),#15+12082 o(S, 0x91004000 | r | r << 5); // add x(r),x(r),#15+1
2089 else2083 else
2090#endif2084#endif
2091 o(0x91003c00 | r | r << 5); // add x(r),x(r),#152085 o(S, 0x91003c00 | r | r << 5); // add x(r),x(r),#15
2092 o(0x927cec00 | r | r << 5); // bic x(r),x(r),#152086 o(S, 0x927cec00 | r | r << 5); // bic x(r),x(r),#15
2093 o(0xcb2063ff | r << 16); // sub sp,sp,x(r)2087 o(S, 0xcb2063ff | r << 16); // sub sp,sp,x(r)
2094 vpop();2088 vpop(S);
2095#if defined(CONFIG_TCC_BCHECK)2089#if defined(CONFIG_TCC_BCHECK)
2096 if (tcc_state->do_bounds_check) {2090 if (S->do_bounds_check) {
2097 vpushi(0);2091 vpushi(S, 0);
2098 vtop->r = TREG_R(0);2092 S->tccgen_vtop->r = TREG_R(0);
2099 o(0x910003e0 | vtop->r); // mov r0,sp2093 o(S, 0x910003e0 | S->tccgen_vtop->r); // mov r0,sp
2100 vswap();2094 vswap(S);
2101 vpush_helper_func(TOK___bound_new_region);2095 vpush_helper_func(S, TOK___bound_new_region);
2102 vrott(3);2096 vrott(S, 3);
2103 gfunc_call(2);2097 gfunc_call(S, 2);
2104 func_bound_add_epilog = 1;2098 S->func_bound_add_epilog = 1;
2105 }2099 }
2106#endif2100#endif
2107}2101}
arm64-link.c+32−32
@@ -90,18 +90,18 @@ int gotplt_entry_type (int reloc_type) · 89 unmodified lines
90 return -1;90 return -1;
91}91}
92 92
93ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)93ST_FUNC unsigned create_plt_entry(TCCState *S, unsigned got_offset, struct sym_attr *attr)
94{94{
95 Section *plt = s1->plt;95 Section *plt = S->plt;
96 uint8_t *p;96 uint8_t *p;
97 unsigned plt_offset;97 unsigned plt_offset;
98 98
99 if (plt->data_offset == 0) {99 if (plt->data_offset == 0) {
100 section_ptr_add(plt, 32);100 section_ptr_add(S, plt, 32);
101 }101 }
102 plt_offset = plt->data_offset;102 plt_offset = plt->data_offset;
103 103
104 p = section_ptr_add(plt, 16);104 p = section_ptr_add(S, plt, 16);
105 write32le(p, got_offset);105 write32le(p, got_offset);
106 write32le(p + 4, (uint64_t) got_offset >> 32);106 write32le(p + 4, (uint64_t) got_offset >> 32);
107 return plt_offset;107 return plt_offset;
@@ -109,22 +109,22 @@ ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_ · 1 unmodified line
109 109
110/* relocate the PLT: compute addresses and offsets in the PLT now that final110/* relocate the PLT: compute addresses and offsets in the PLT now that final
111 address for PLT and GOT are known (see fill_program_header) */111 address for PLT and GOT are known (see fill_program_header) */
112ST_FUNC void relocate_plt(TCCState *s1)112ST_FUNC void relocate_plt(TCCState *S)
113{113{
114 uint8_t *p, *p_end;114 uint8_t *p, *p_end;
115 115
116 if (!s1->plt)116 if (!S->plt)
117 return;117 return;
118 118
119 p = s1->plt->data;119 p = S->plt->data;
120 p_end = p + s1->plt->data_offset;120 p_end = p + S->plt->data_offset;
121 121
122 if (p < p_end) {122 if (p < p_end) {
123 uint64_t plt = s1->plt->sh_addr;123 uint64_t plt = S->plt->sh_addr;
124 uint64_t got = s1->got->sh_addr + 16;124 uint64_t got = S->got->sh_addr + 16;
125 uint64_t off = (got >> 12) - (plt >> 12);125 uint64_t off = (got >> 12) - (plt >> 12);
126 if ((off + ((uint32_t)1 << 20)) >> 21)126 if ((off + ((uint32_t)1 << 20)) >> 21)
127 tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt);127 tcc_error(S, "Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt);
128 write32le(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]!128 write32le(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]!
129 write32le(p + 4, (0x90000010 | // adrp x16,...129 write32le(p + 4, (0x90000010 | // adrp x16,...
130 (off & 0x1ffffc) << 3 | (off & 3) << 29));130 (off & 0x1ffffc) << 3 | (off & 3) << 29));
@@ -137,13 +137,13 @@ ST_FUNC void relocate_plt(TCCState *s1) · 6 unmodified lines
137 write32le(p + 24, 0xd503201f); // nop137 write32le(p + 24, 0xd503201f); // nop
138 write32le(p + 28, 0xd503201f); // nop138 write32le(p + 28, 0xd503201f); // nop
139 p += 32;139 p += 32;
140 got = s1->got->sh_addr;140 got = S->got->sh_addr;
141 while (p < p_end) {141 while (p < p_end) {
142 uint64_t pc = plt + (p - s1->plt->data);142 uint64_t pc = plt + (p - S->plt->data);
143 uint64_t addr = got + read64le(p);143 uint64_t addr = got + read64le(p);
144 uint64_t off = (addr >> 12) - (pc >> 12);144 uint64_t off = (addr >> 12) - (pc >> 12);
145 if ((off + ((uint32_t)1 << 20)) >> 21)145 if ((off + ((uint32_t)1 << 20)) >> 21)
146 tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc);146 tcc_error(S, "Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc);
147 write32le(p, (0x90000010 | // adrp x16,...147 write32le(p, (0x90000010 | // adrp x16,...
148 (off & 0x1ffffc) << 3 | (off & 3) << 29));148 (off & 0x1ffffc) << 3 | (off & 3) << 29));
149 write32le(p + 4, (0xf9400211 | // ldr x17,[x16,#...]149 write32le(p + 4, (0xf9400211 | // ldr x17,[x16,#...]
@@ -155,16 +155,16 @@ ST_FUNC void relocate_plt(TCCState *s1) · 5 unmodified lines
155 }155 }
156 }156 }
157 157
158 if (s1->plt->reloc) {158 if (S->plt->reloc) {
159 ElfW_Rel *rel;159 ElfW_Rel *rel;
160 p = s1->got->data;160 p = S->got->data;
161 for_each_elem(s1->plt->reloc, 0, rel, ElfW_Rel) {161 for_each_elem(S->plt->reloc, 0, rel, ElfW_Rel) {
162 write64le(p + rel->r_offset, s1->plt->sh_addr);162 write64le(p + rel->r_offset, S->plt->sh_addr);
163 }163 }
164 }164 }
165}165}
166 166
167void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)167void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
168{168{
169 int sym_index = ELFW(R_SYM)(rel->r_info), esym_index;169 int sym_index = ELFW(R_SYM)(rel->r_info), esym_index;
170#ifdef DEBUG_RELOC170#ifdef DEBUG_RELOC
@@ -173,8 +173,8 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 2 unmodified lines
173 173
174 switch(type) {174 switch(type) {
175 case R_AARCH64_ABS64:175 case R_AARCH64_ABS64:
176 if (s1->output_type == TCC_OUTPUT_DLL) {176 if (S->output_type == TCC_OUTPUT_DLL) {
177 esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;177 esym_index = get_sym_attr(S, sym_index, 0)->dyn_index;
178 qrel->r_offset = rel->r_offset;178 qrel->r_offset = rel->r_offset;
179 if (esym_index) {179 if (esym_index) {
180 qrel->r_info = ELFW(R_INFO)(esym_index, R_AARCH64_ABS64);180 qrel->r_info = ELFW(R_INFO)(esym_index, R_AARCH64_ABS64);
@@ -190,7 +190,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 9 unmodified lines
190 add64le(ptr, val);190 add64le(ptr, val);
191 return;191 return;
192 case R_AARCH64_ABS32:192 case R_AARCH64_ABS32:
193 if (s1->output_type == TCC_OUTPUT_DLL) {193 if (S->output_type == TCC_OUTPUT_DLL) {
194 /* XXX: this logic may depend on TCC's codegen194 /* XXX: this logic may depend on TCC's codegen
195 now TCC uses R_AARCH64_RELATIVE even for a 64bit pointer */195 now TCC uses R_AARCH64_RELATIVE even for a 64bit pointer */
196 qrel->r_offset = rel->r_offset;196 qrel->r_offset = rel->r_offset;
@@ -202,9 +202,9 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 5 unmodified lines
202 add32le(ptr, val);202 add32le(ptr, val);
203 return;203 return;
204 case R_AARCH64_PREL32:204 case R_AARCH64_PREL32:
205 if (s1->output_type == TCC_OUTPUT_DLL) {205 if (S->output_type == TCC_OUTPUT_DLL) {
206 /* DLL relocation */206 /* DLL relocation */
207 esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;207 esym_index = get_sym_attr(S, sym_index, 0)->dyn_index;
208 if (esym_index) {208 if (esym_index) {
209 qrel->r_offset = rel->r_offset;209 qrel->r_offset = rel->r_offset;
210 qrel->r_info = ELFW(R_INFO)(esym_index, R_AARCH64_PREL32);210 qrel->r_info = ELFW(R_INFO)(esym_index, R_AARCH64_PREL32);
@@ -235,7 +235,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 24 unmodified lines
235 case R_AARCH64_ADR_PREL_PG_HI21: {235 case R_AARCH64_ADR_PREL_PG_HI21: {
236 uint64_t off = (val >> 12) - (addr >> 12);236 uint64_t off = (val >> 12) - (addr >> 12);
237 if ((off + ((uint64_t)1 << 20)) >> 21)237 if ((off + ((uint64_t)1 << 20)) >> 21)
238 tcc_error("R_AARCH64_ADR_PREL_PG_HI21 relocation failed");238 tcc_error(S, "R_AARCH64_ADR_PREL_PG_HI21 relocation failed");
239 write32le(ptr, ((read32le(ptr) & 0x9f00001f) |239 write32le(ptr, ((read32le(ptr) & 0x9f00001f) |
240 (off & 0x1ffffc) << 3 | (off & 3) << 29));240 (off & 0x1ffffc) << 3 | (off & 3) << 29));
241 return;241 return;
@@ -268,7 +268,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 26 unmodified lines
268 (char *) symtab_section->link->data + sym->st_name);268 (char *) symtab_section->link->data + sym->st_name);
269#endif269#endif
270 if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc)270 if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc)
271 tcc_error("R_AARCH64_(JUMP|CALL)26 relocation failed"271 tcc_error(S, "R_AARCH64_(JUMP|CALL)26 relocation failed"
272 " (val=%lx, addr=%lx)", (long)val, (long)addr);272 " (val=%lx, addr=%lx)", (long)val, (long)addr);
273 write32le(ptr, (0x14000000 |273 write32le(ptr, (0x14000000 |
274 (uint32_t)(type == R_AARCH64_CALL26) << 31 |274 (uint32_t)(type == R_AARCH64_CALL26) << 31 |
@@ -276,10 +276,10 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 1 unmodified line
276 return;276 return;
277 case R_AARCH64_ADR_GOT_PAGE: {277 case R_AARCH64_ADR_GOT_PAGE: {
278 uint64_t off =278 uint64_t off =
279 (((s1->got->sh_addr +279 (((S->got->sh_addr +
280 get_sym_attr(s1, sym_index, 0)->got_offset) >> 12) - (addr >> 12));280 get_sym_attr(S, sym_index, 0)->got_offset) >> 12) - (addr >> 12));
281 if ((off + ((uint64_t)1 << 20)) >> 21)281 if ((off + ((uint64_t)1 << 20)) >> 21)
282 tcc_error("R_AARCH64_ADR_GOT_PAGE relocation failed");282 tcc_error(S, "R_AARCH64_ADR_GOT_PAGE relocation failed");
283 write32le(ptr, ((read32le(ptr) & 0x9f00001f) |283 write32le(ptr, ((read32le(ptr) & 0x9f00001f) |
284 (off & 0x1ffffc) << 3 | (off & 3) << 29));284 (off & 0x1ffffc) << 3 | (off & 3) << 29));
285 return;285 return;
@@ -287,8 +287,8 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 1 unmodified line
287 case R_AARCH64_LD64_GOT_LO12_NC:287 case R_AARCH64_LD64_GOT_LO12_NC:
288 write32le(ptr,288 write32le(ptr,
289 ((read32le(ptr) & 0xfff803ff) |289 ((read32le(ptr) & 0xfff803ff) |
290 ((s1->got->sh_addr +290 ((S->got->sh_addr +
291 get_sym_attr(s1, sym_index, 0)->got_offset) & 0xff8) << 7));291 get_sym_attr(S, sym_index, 0)->got_offset) & 0xff8) << 7));
292 return;292 return;
293 case R_AARCH64_COPY:293 case R_AARCH64_COPY:
294 return;294 return;
@@ -304,7 +304,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 9 unmodified lines
304 return;304 return;
305 case R_AARCH64_RELATIVE:305 case R_AARCH64_RELATIVE:
306#ifdef TCC_TARGET_PE306#ifdef TCC_TARGET_PE
307 add32le(ptr, val - s1->pe_imagebase);307 add32le(ptr, val - S->pe_imagebase);
308#endif308#endif
309 /* do nothing */309 /* do nothing */
310 return;310 return;
c67-gen.c+758−758
@@ -172,7 +172,7 @@ int TotalBytesPushedOnStack; · 171 unmodified lines
172#define ALWAYS_ASSERT(x) \172#define ALWAYS_ASSERT(x) \
173do {\173do {\
174 if (!(x))\174 if (!(x))\
175 tcc_error("internal compiler error file at %s:%d", __FILE__, __LINE__);\175 tcc_error(S, "internal compiler error file at %s:%d", __FILE__, __LINE__);\
176} while (0)176} while (0)
177 177
178/******************************************************/178/******************************************************/
@@ -186,27 +186,27 @@ static int C67_compare_reg; · 7 unmodified lines
186FILE *f = NULL;186FILE *f = NULL;
187#endif187#endif
188 188
189void C67_g(int c)189void C67_g(TCCState* S, int c)
190{190{
191 int ind1;191 int ind1;
192 if (nocode_wanted)192 if (S->tccgen_nocode_wanted)
193 return;193 return;
194#ifdef ASSEMBLY_LISTING_C67194#ifdef ASSEMBLY_LISTING_C67
195 fprintf(f, " %08X", c);195 fprintf(f, " %08X", c);
196#endif196#endif
197 ind1 = ind + 4;197 ind1 = S->tccgen_ind + 4;
198 if (ind1 > (int) cur_text_section->data_allocated)198 if (ind1 > (int) cur_text_section->data_allocated)
199 section_realloc(cur_text_section, ind1);199 section_realloc(S, cur_text_section, ind1);
200 cur_text_section->data[ind] = c & 0xff;200 cur_text_section->data[S->tccgen_ind] = c & 0xff;
201 cur_text_section->data[ind + 1] = (c >> 8) & 0xff;201 cur_text_section->data[S->tccgen_ind + 1] = (c >> 8) & 0xff;
202 cur_text_section->data[ind + 2] = (c >> 16) & 0xff;202 cur_text_section->data[S->tccgen_ind + 2] = (c >> 16) & 0xff;
203 cur_text_section->data[ind + 3] = (c >> 24) & 0xff;203 cur_text_section->data[S->tccgen_ind + 3] = (c >> 24) & 0xff;
204 ind = ind1;204 S->tccgen_ind = ind1;
205}205}
206 206
207 207
208/* output a symbol and patch all calls to it */208/* output a symbol and patch all calls to it */
209void gsym_addr(int t, int a)209void gsym_addr(TCCState* S, int t, int a)
210{210{
211 int n, *ptr;211 int n, *ptr;
212 while (t) {212 while (t) {
@@ -220,9 +220,9 @@ void gsym_addr(int t, int a) · 7 unmodified lines
220 220
221 // define a label that will be relocated221 // define a label that will be relocated
222 222
223 sym = get_sym_ref(&char_pointer_type, cur_text_section, a, 0);223 sym = get_sym_ref(S, &S->tccgen_char_pointer_type, cur_text_section, a, 0);
224 greloc(cur_text_section, sym, t, R_C60LO16);224 greloc(S, cur_text_section, sym, t, R_C60LO16);
225 greloc(cur_text_section, sym, t + 4, R_C60HI16);225 greloc(S, cur_text_section, sym, t + 4, R_C60HI16);
226 226
227 // clear out where the pointer was227 // clear out where the pointer was
228 228
@@ -255,7 +255,7 @@ int ConvertRegToRegClass(int r) · 26 unmodified lines
255 255
256// map TCC reg to C67 reg number256// map TCC reg to C67 reg number
257 257
258int C67_map_regn(int r)258int C67_map_regn(TCCState* S, int r)
259{259{
260 if (r == 0) // normal tcc regs260 if (r == 0) // normal tcc regs
261 return 0x2; // A2261 return 0x2; // A2
@@ -296,7 +296,7 @@ int C67_map_regn(int r) · 34 unmodified lines
296// tcc reg 1 -> A3 -> X296// tcc reg 1 -> A3 -> X
297// tcc reg B2 -> 3297// tcc reg B2 -> 3
298 298
299int C67_map_regc(int r)299int C67_map_regc(TCCState* S, int r)
300{300{
301 if (r == 0) // normal tcc regs301 if (r == 0) // normal tcc regs
302 return 0x5;302 return 0x5;
@@ -317,7 +317,7 @@ int C67_map_regc(int r) · 14 unmodified lines
317 317
318// map TCC reg to C67 reg side A or B318// map TCC reg to C67 reg side A or B
319 319
320int C67_map_regs(int r)320int C67_map_regs(TCCState* S, int r)
321{321{
322 if (r == 0) // normal tcc regs322 if (r == 0) // normal tcc regs
323 return 0x0;323 return 0x0;
@@ -345,7 +345,7 @@ int C67_map_regs(int r) · 21 unmodified lines
345 return 0;345 return 0;
346}346}
347 347
348int C67_map_S12(char *s)348int C67_map_S12(TCCState* S, char *s)
349{349{
350 if (strstr(s, ".S1") != NULL)350 if (strstr(s, ".S1") != NULL)
351 return 0;351 return 0;
@@ -357,7 +357,7 @@ int C67_map_S12(char *s) · 5 unmodified lines
357 return 0;357 return 0;
358}358}
359 359
360int C67_map_D12(char *s)360int C67_map_D12(TCCState* S, char *s)
361{361{
362 if (strstr(s, ".D1") != NULL)362 if (strstr(s, ".D1") != NULL)
363 return 0;363 return 0;
@@ -371,7 +371,7 @@ int C67_map_D12(char *s) · 7 unmodified lines
371 371
372 372
373 373
374void C67_asm(const char *s, int a, int b, int c)374void C67_asm(TCCState* S, const char *s, int a, int b, int c)
375{375{
376 BOOL xpath;376 BOOL xpath;
377 377
@@ -383,14 +383,14 @@ void C67_asm(const char *s, int a, int b, int c) · 5 unmodified lines
383#endif383#endif
384 384
385 if (strstr(s, "MVKL") == s) {385 if (strstr(s, "MVKL") == s) {
386 C67_g((C67_map_regn(b) << 23) |386 C67_g(S, (C67_map_regn(S, b) << 23) |
387 ((a & 0xffff) << 7) | (0x0a << 2) | (C67_map_regs(b) << 1));387 ((a & 0xffff) << 7) | (0x0a << 2) | (C67_map_regs(S, b) << 1));
388 } else if (strstr(s, "MVKH") == s) {388 } else if (strstr(s, "MVKH") == s) {
389 C67_g((C67_map_regn(b) << 23) |389 C67_g(S, (C67_map_regn(S, b) << 23) |
390 (((a >> 16) & 0xffff) << 7) |390 (((a >> 16) & 0xffff) << 7) |
391 (0x1a << 2) | (C67_map_regs(b) << 1));391 (0x1a << 2) | (C67_map_regs(S, b) << 1));
392 } else if (strstr(s, "STW.D SP POST DEC") == s) {392 } else if (strstr(s, "STW.D SP POST DEC") == s) {
393 C67_g((C67_map_regn(a) << 23) | //src393 C67_g(S, (C67_map_regn(S, a) << 23) | //src
394 (15 << 18) | //SP B15394 (15 << 18) | //SP B15
395 (2 << 13) | //ucst5 (must keep 8 byte boundary !!)395 (2 << 13) | //ucst5 (must keep 8 byte boundary !!)
396 (0xa << 9) | //mode a = post dec ucst396 (0xa << 9) | //mode a = post dec ucst
@@ -398,10 +398,10 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line
398 (1 << 7) | //y D1/D2 use B side398 (1 << 7) | //y D1/D2 use B side
399 (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU399 (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
400 (1 << 2) | //opcode400 (1 << 2) | //opcode
401 (C67_map_regs(a) << 1) | //side of src401 (C67_map_regs(S, a) << 1) | //side of src
402 (0 << 0)); //parallel402 (0 << 0)); //parallel
403 } else if (strstr(s, "STB.D *+SP[A0]") == s) {403 } else if (strstr(s, "STB.D *+SP[A0]") == s) {
404 C67_g((C67_map_regn(a) << 23) | //src404 C67_g(S, (C67_map_regn(S, a) << 23) | //src
405 (15 << 18) | //base reg A15405 (15 << 18) | //base reg A15
406 (0 << 13) | //offset reg A0406 (0 << 13) | //offset reg A0
407 (5 << 9) | //mode 5 = pos offset, base reg + off reg407 (5 << 9) | //mode 5 = pos offset, base reg + off reg
@@ -409,10 +409,10 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line
409 (0 << 7) | //y D1/D2 A side409 (0 << 7) | //y D1/D2 A side
410 (3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 410 (3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
411 (1 << 2) | //opcode411 (1 << 2) | //opcode
412 (C67_map_regs(a) << 1) | //side of src412 (C67_map_regs(S, a) << 1) | //side of src
413 (0 << 0)); //parallel413 (0 << 0)); //parallel
414 } else if (strstr(s, "STH.D *+SP[A0]") == s) {414 } else if (strstr(s, "STH.D *+SP[A0]") == s) {
415 C67_g((C67_map_regn(a) << 23) | //src415 C67_g(S, (C67_map_regn(S, a) << 23) | //src
416 (15 << 18) | //base reg A15416 (15 << 18) | //base reg A15
417 (0 << 13) | //offset reg A0417 (0 << 13) | //offset reg A0
418 (5 << 9) | //mode 5 = pos offset, base reg + off reg418 (5 << 9) | //mode 5 = pos offset, base reg + off reg
@@ -420,10 +420,10 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line
420 (0 << 7) | //y D1/D2 A side420 (0 << 7) | //y D1/D2 A side
421 (5 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU421 (5 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
422 (1 << 2) | //opcode422 (1 << 2) | //opcode
423 (C67_map_regs(a) << 1) | //side of src423 (C67_map_regs(S, a) << 1) | //side of src
424 (0 << 0)); //parallel424 (0 << 0)); //parallel
425 } else if (strstr(s, "STB.D *+SP[A0]") == s) {425 } else if (strstr(s, "STB.D *+SP[A0]") == s) {
426 C67_g((C67_map_regn(a) << 23) | //src426 C67_g(S, (C67_map_regn(S, a) << 23) | //src
427 (15 << 18) | //base reg A15427 (15 << 18) | //base reg A15
428 (0 << 13) | //offset reg A0428 (0 << 13) | //offset reg A0
429 (5 << 9) | //mode 5 = pos offset, base reg + off reg429 (5 << 9) | //mode 5 = pos offset, base reg + off reg
@@ -431,10 +431,10 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line
431 (0 << 7) | //y D1/D2 A side431 (0 << 7) | //y D1/D2 A side
432 (3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 432 (3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
433 (1 << 2) | //opcode433 (1 << 2) | //opcode
434 (C67_map_regs(a) << 1) | //side of src434 (C67_map_regs(S, a) << 1) | //side of src
435 (0 << 0)); //parallel435 (0 << 0)); //parallel
436 } else if (strstr(s, "STH.D *+SP[A0]") == s) {436 } else if (strstr(s, "STH.D *+SP[A0]") == s) {
437 C67_g((C67_map_regn(a) << 23) | //src437 C67_g(S, (C67_map_regn(S, a) << 23) | //src
438 (15 << 18) | //base reg A15438 (15 << 18) | //base reg A15
439 (0 << 13) | //offset reg A0439 (0 << 13) | //offset reg A0
440 (5 << 9) | //mode 5 = pos offset, base reg + off reg440 (5 << 9) | //mode 5 = pos offset, base reg + off reg
@@ -442,10 +442,10 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line
442 (0 << 7) | //y D1/D2 A side442 (0 << 7) | //y D1/D2 A side
443 (5 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU443 (5 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
444 (1 << 2) | //opcode444 (1 << 2) | //opcode
445 (C67_map_regs(a) << 1) | //side of src445 (C67_map_regs(S, a) << 1) | //side of src
446 (0 << 0)); //parallel446 (0 << 0)); //parallel
447 } else if (strstr(s, "STW.D *+SP[A0]") == s) {447 } else if (strstr(s, "STW.D *+SP[A0]") == s) {
448 C67_g((C67_map_regn(a) << 23) | //src448 C67_g(S, (C67_map_regn(S, a) << 23) | //src
449 (15 << 18) | //base reg A15449 (15 << 18) | //base reg A15
450 (0 << 13) | //offset reg A0450 (0 << 13) | //offset reg A0
451 (5 << 9) | //mode 5 = pos offset, base reg + off reg451 (5 << 9) | //mode 5 = pos offset, base reg + off reg
@@ -453,55 +453,55 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line
453 (0 << 7) | //y D1/D2 A side453 (0 << 7) | //y D1/D2 A side
454 (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 454 (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
455 (1 << 2) | //opcode455 (1 << 2) | //opcode
456 (C67_map_regs(a) << 1) | //side of src456 (C67_map_regs(S, a) << 1) | //side of src
457 (0 << 0)); //parallel457 (0 << 0)); //parallel
458 } else if (strstr(s, "STW.D *") == s) {458 } else if (strstr(s, "STW.D *") == s) {
459 C67_g((C67_map_regn(a) << 23) | //src459 C67_g(S, (C67_map_regn(S, a) << 23) | //src
460 (C67_map_regn(b) << 18) | //base reg A0460 (C67_map_regn(S, b) << 18) | //base reg A0
461 (0 << 13) | //cst5461 (0 << 13) | //cst5
462 (1 << 9) | //mode 1 = pos cst offset462 (1 << 9) | //mode 1 = pos cst offset
463 (0 << 8) | //r (LDDW bit 0)463 (0 << 8) | //r (LDDW bit 0)
464 (C67_map_regs(b) << 7) | //y D1/D2 base reg side464 (C67_map_regs(S, b) << 7) | //y D1/D2 base reg side
465 (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 465 (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
466 (1 << 2) | //opcode466 (1 << 2) | //opcode
467 (C67_map_regs(a) << 1) | //side of src467 (C67_map_regs(S, a) << 1) | //side of src
468 (0 << 0)); //parallel468 (0 << 0)); //parallel
469 } else if (strstr(s, "STH.D *") == s) {469 } else if (strstr(s, "STH.D *") == s) {
470 C67_g((C67_map_regn(a) << 23) | //src470 C67_g(S, (C67_map_regn(S, a) << 23) | //src
471 (C67_map_regn(b) << 18) | //base reg A0471 (C67_map_regn(S, b) << 18) | //base reg A0
472 (0 << 13) | //cst5472 (0 << 13) | //cst5
473 (1 << 9) | //mode 1 = pos cst offset473 (1 << 9) | //mode 1 = pos cst offset
474 (0 << 8) | //r (LDDW bit 0)474 (0 << 8) | //r (LDDW bit 0)
475 (C67_map_regs(b) << 7) | //y D1/D2 base reg side475 (C67_map_regs(S, b) << 7) | //y D1/D2 base reg side
476 (5 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 476 (5 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
477 (1 << 2) | //opcode477 (1 << 2) | //opcode
478 (C67_map_regs(a) << 1) | //side of src478 (C67_map_regs(S, a) << 1) | //side of src
479 (0 << 0)); //parallel479 (0 << 0)); //parallel
480 } else if (strstr(s, "STB.D *") == s) {480 } else if (strstr(s, "STB.D *") == s) {
481 C67_g((C67_map_regn(a) << 23) | //src481 C67_g(S, (C67_map_regn(S, a) << 23) | //src
482 (C67_map_regn(b) << 18) | //base reg A0482 (C67_map_regn(S, b) << 18) | //base reg A0
483 (0 << 13) | //cst5483 (0 << 13) | //cst5
484 (1 << 9) | //mode 1 = pos cst offset484 (1 << 9) | //mode 1 = pos cst offset
485 (0 << 8) | //r (LDDW bit 0)485 (0 << 8) | //r (LDDW bit 0)
486 (C67_map_regs(b) << 7) | //y D1/D2 base reg side486 (C67_map_regs(S, b) << 7) | //y D1/D2 base reg side
487 (3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 487 (3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
488 (1 << 2) | //opcode488 (1 << 2) | //opcode
489 (C67_map_regs(a) << 1) | //side of src489 (C67_map_regs(S, a) << 1) | //side of src
490 (0 << 0)); //parallel490 (0 << 0)); //parallel
491 } else if (strstr(s, "STW.D +*") == s) {491 } else if (strstr(s, "STW.D +*") == s) {
492 ALWAYS_ASSERT(c < 32);492 ALWAYS_ASSERT(c < 32);
493 C67_g((C67_map_regn(a) << 23) | //src493 C67_g(S, (C67_map_regn(S, a) << 23) | //src
494 (C67_map_regn(b) << 18) | //base reg A0494 (C67_map_regn(S, b) << 18) | //base reg A0
495 (c << 13) | //cst5495 (c << 13) | //cst5
496 (1 << 9) | //mode 1 = pos cst offset496 (1 << 9) | //mode 1 = pos cst offset
497 (0 << 8) | //r (LDDW bit 0)497 (0 << 8) | //r (LDDW bit 0)
498 (C67_map_regs(b) << 7) | //y D1/D2 base reg side498 (C67_map_regs(S, b) << 7) | //y D1/D2 base reg side
499 (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 499 (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
500 (1 << 2) | //opcode500 (1 << 2) | //opcode
501 (C67_map_regs(a) << 1) | //side of src501 (C67_map_regs(S, a) << 1) | //side of src
502 (0 << 0)); //parallel502 (0 << 0)); //parallel
503 } else if (strstr(s, "LDW.D SP PRE INC") == s) {503 } else if (strstr(s, "LDW.D SP PRE INC") == s) {
504 C67_g((C67_map_regn(a) << 23) | //dst504 C67_g(S, (C67_map_regn(S, a) << 23) | //dst
505 (15 << 18) | //base reg B15505 (15 << 18) | //base reg B15
506 (2 << 13) | //ucst5 (must keep 8 byte boundary)506 (2 << 13) | //ucst5 (must keep 8 byte boundary)
507 (9 << 9) | //mode 9 = pre inc ucst5507 (9 << 9) | //mode 9 = pre inc ucst5
@@ -509,10 +509,10 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line
509 (1 << 7) | //y D1/D2 B side509 (1 << 7) | //y D1/D2 B side
510 (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU510 (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
511 (1 << 2) | //opcode511 (1 << 2) | //opcode
512 (C67_map_regs(a) << 1) | //side of dst512 (C67_map_regs(S, a) << 1) | //side of dst
513 (0 << 0)); //parallel513 (0 << 0)); //parallel
514 } else if (strstr(s, "LDDW.D SP PRE INC") == s) {514 } else if (strstr(s, "LDDW.D SP PRE INC") == s) {
515 C67_g((C67_map_regn(a) << 23) | //dst515 C67_g(S, (C67_map_regn(S, a) << 23) | //dst
516 (15 << 18) | //base reg B15516 (15 << 18) | //base reg B15
517 (1 << 13) | //ucst5 (must keep 8 byte boundary)517 (1 << 13) | //ucst5 (must keep 8 byte boundary)
518 (9 << 9) | //mode 9 = pre inc ucst5518 (9 << 9) | //mode 9 = pre inc ucst5
@@ -520,10 +520,10 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line
520 (1 << 7) | //y D1/D2 B side520 (1 << 7) | //y D1/D2 B side
521 (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU521 (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
522 (1 << 2) | //opcode522 (1 << 2) | //opcode
523 (C67_map_regs(a) << 1) | //side of dst523 (C67_map_regs(S, a) << 1) | //side of dst
524 (0 << 0)); //parallel524 (0 << 0)); //parallel
525 } else if (strstr(s, "LDW.D *+SP[A0]") == s) {525 } else if (strstr(s, "LDW.D *+SP[A0]") == s) {
526 C67_g((C67_map_regn(a) << 23) | //dst526 C67_g(S, (C67_map_regn(S, a) << 23) | //dst
527 (15 << 18) | //base reg A15527 (15 << 18) | //base reg A15
528 (0 << 13) | //offset reg A0528 (0 << 13) | //offset reg A0
529 (5 << 9) | //mode 5 = pos offset, base reg + off reg529 (5 << 9) | //mode 5 = pos offset, base reg + off reg
@@ -531,10 +531,10 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line
531 (0 << 7) | //y D1/D2 A side531 (0 << 7) | //y D1/D2 A side
532 (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU532 (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
533 (1 << 2) | //opcode533 (1 << 2) | //opcode
534 (C67_map_regs(a) << 1) | //side of dst534 (C67_map_regs(S, a) << 1) | //side of dst
535 (0 << 0)); //parallel535 (0 << 0)); //parallel
536 } else if (strstr(s, "LDDW.D *+SP[A0]") == s) {536 } else if (strstr(s, "LDDW.D *+SP[A0]") == s) {
537 C67_g((C67_map_regn(a) << 23) | //dst537 C67_g(S, (C67_map_regn(S, a) << 23) | //dst
538 (15 << 18) | //base reg A15538 (15 << 18) | //base reg A15
539 (0 << 13) | //offset reg A0539 (0 << 13) | //offset reg A0
540 (5 << 9) | //mode 5 = pos offset, base reg + off reg540 (5 << 9) | //mode 5 = pos offset, base reg + off reg
@@ -542,10 +542,10 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line
542 (0 << 7) | //y D1/D2 A side542 (0 << 7) | //y D1/D2 A side
543 (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU543 (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
544 (1 << 2) | //opcode544 (1 << 2) | //opcode
545 (C67_map_regs(a) << 1) | //side of dst545 (C67_map_regs(S, a) << 1) | //side of dst
546 (0 << 0)); //parallel546 (0 << 0)); //parallel
547 } else if (strstr(s, "LDH.D *+SP[A0]") == s) {547 } else if (strstr(s, "LDH.D *+SP[A0]") == s) {
548 C67_g((C67_map_regn(a) << 23) | //dst548 C67_g(S, (C67_map_regn(S, a) << 23) | //dst
549 (15 << 18) | //base reg A15549 (15 << 18) | //base reg A15
550 (0 << 13) | //offset reg A0550 (0 << 13) | //offset reg A0
551 (5 << 9) | //mode 5 = pos offset, base reg + off reg551 (5 << 9) | //mode 5 = pos offset, base reg + off reg
@@ -553,10 +553,10 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line
553 (0 << 7) | //y D1/D2 A side553 (0 << 7) | //y D1/D2 A side
554 (4 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU554 (4 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
555 (1 << 2) | //opcode555 (1 << 2) | //opcode
556 (C67_map_regs(a) << 1) | //side of dst556 (C67_map_regs(S, a) << 1) | //side of dst
557 (0 << 0)); //parallel557 (0 << 0)); //parallel
558 } else if (strstr(s, "LDB.D *+SP[A0]") == s) {558 } else if (strstr(s, "LDB.D *+SP[A0]") == s) {
559 C67_g((C67_map_regn(a) << 23) | //dst559 C67_g(S, (C67_map_regn(S, a) << 23) | //dst
560 (15 << 18) | //base reg A15560 (15 << 18) | //base reg A15
561 (0 << 13) | //offset reg A0561 (0 << 13) | //offset reg A0
562 (5 << 9) | //mode 5 = pos offset, base reg + off reg562 (5 << 9) | //mode 5 = pos offset, base reg + off reg
@@ -564,10 +564,10 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line
564 (0 << 7) | //y D1/D2 A side564 (0 << 7) | //y D1/D2 A side
565 (2 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU565 (2 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
566 (1 << 2) | //opcode566 (1 << 2) | //opcode
567 (C67_map_regs(a) << 1) | //side of dst567 (C67_map_regs(S, a) << 1) | //side of dst
568 (0 << 0)); //parallel568 (0 << 0)); //parallel
569 } else if (strstr(s, "LDHU.D *+SP[A0]") == s) {569 } else if (strstr(s, "LDHU.D *+SP[A0]") == s) {
570 C67_g((C67_map_regn(a) << 23) | //dst570 C67_g(S, (C67_map_regn(S, a) << 23) | //dst
571 (15 << 18) | //base reg A15571 (15 << 18) | //base reg A15
572 (0 << 13) | //offset reg A0572 (0 << 13) | //offset reg A0
573 (5 << 9) | //mode 5 = pos offset, base reg + off reg573 (5 << 9) | //mode 5 = pos offset, base reg + off reg
@@ -575,10 +575,10 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line
575 (0 << 7) | //y D1/D2 A side575 (0 << 7) | //y D1/D2 A side
576 (0 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU576 (0 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
577 (1 << 2) | //opcode577 (1 << 2) | //opcode
578 (C67_map_regs(a) << 1) | //side of dst578 (C67_map_regs(S, a) << 1) | //side of dst
579 (0 << 0)); //parallel579 (0 << 0)); //parallel
580 } else if (strstr(s, "LDBU.D *+SP[A0]") == s) {580 } else if (strstr(s, "LDBU.D *+SP[A0]") == s) {
581 C67_g((C67_map_regn(a) << 23) | //dst581 C67_g(S, (C67_map_regn(S, a) << 23) | //dst
582 (15 << 18) | //base reg A15582 (15 << 18) | //base reg A15
583 (0 << 13) | //offset reg A0583 (0 << 13) | //offset reg A0
584 (5 << 9) | //mode 5 = pos offset, base reg + off reg584 (5 << 9) | //mode 5 = pos offset, base reg + off reg
@@ -586,233 +586,233 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line
586 (0 << 7) | //y D1/D2 A side586 (0 << 7) | //y D1/D2 A side
587 (1 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU587 (1 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
588 (1 << 2) | //opcode588 (1 << 2) | //opcode
589 (C67_map_regs(a) << 1) | //side of dst589 (C67_map_regs(S, a) << 1) | //side of dst
590 (0 << 0)); //parallel590 (0 << 0)); //parallel
591 } else if (strstr(s, "LDW.D *") == s) {591 } else if (strstr(s, "LDW.D *") == s) {
592 C67_g((C67_map_regn(b) << 23) | //dst592 C67_g(S, (C67_map_regn(S, b) << 23) | //dst
593 (C67_map_regn(a) << 18) | //base reg A15593 (C67_map_regn(S, a) << 18) | //base reg A15
594 (0 << 13) | //cst5594 (0 << 13) | //cst5
595 (1 << 9) | //mode 1 = pos cst offset595 (1 << 9) | //mode 1 = pos cst offset
596 (0 << 8) | //r (LDDW bit 0)596 (0 << 8) | //r (LDDW bit 0)
597 (C67_map_regs(a) << 7) | //y D1/D2 src side597 (C67_map_regs(S, a) << 7) | //y D1/D2 src side
598 (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU598 (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
599 (1 << 2) | //opcode599 (1 << 2) | //opcode
600 (C67_map_regs(b) << 1) | //side of dst600 (C67_map_regs(S, b) << 1) | //side of dst
601 (0 << 0)); //parallel601 (0 << 0)); //parallel
602 } else if (strstr(s, "LDDW.D *") == s) {602 } else if (strstr(s, "LDDW.D *") == s) {
603 C67_g((C67_map_regn(b) << 23) | //dst603 C67_g(S, (C67_map_regn(S, b) << 23) | //dst
604 (C67_map_regn(a) << 18) | //base reg A15604 (C67_map_regn(S, a) << 18) | //base reg A15
605 (0 << 13) | //cst5605 (0 << 13) | //cst5
606 (1 << 9) | //mode 1 = pos cst offset606 (1 << 9) | //mode 1 = pos cst offset
607 (1 << 8) | //r (LDDW bit 1)607 (1 << 8) | //r (LDDW bit 1)
608 (C67_map_regs(a) << 7) | //y D1/D2 src side608 (C67_map_regs(S, a) << 7) | //y D1/D2 src side
609 (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU609 (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
610 (1 << 2) | //opcode610 (1 << 2) | //opcode
611 (C67_map_regs(b) << 1) | //side of dst611 (C67_map_regs(S, b) << 1) | //side of dst
612 (0 << 0)); //parallel612 (0 << 0)); //parallel
613 } else if (strstr(s, "LDH.D *") == s) {613 } else if (strstr(s, "LDH.D *") == s) {
614 C67_g((C67_map_regn(b) << 23) | //dst614 C67_g(S, (C67_map_regn(S, b) << 23) | //dst
615 (C67_map_regn(a) << 18) | //base reg A15615 (C67_map_regn(S, a) << 18) | //base reg A15
616 (0 << 13) | //cst5616 (0 << 13) | //cst5
617 (1 << 9) | //mode 1 = pos cst offset617 (1 << 9) | //mode 1 = pos cst offset
618 (0 << 8) | //r (LDDW bit 0)618 (0 << 8) | //r (LDDW bit 0)
619 (C67_map_regs(a) << 7) | //y D1/D2 src side619 (C67_map_regs(S, a) << 7) | //y D1/D2 src side
620 (4 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU620 (4 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
621 (1 << 2) | //opcode621 (1 << 2) | //opcode
622 (C67_map_regs(b) << 1) | //side of dst622 (C67_map_regs(S, b) << 1) | //side of dst
623 (0 << 0)); //parallel623 (0 << 0)); //parallel
624 } else if (strstr(s, "LDB.D *") == s) {624 } else if (strstr(s, "LDB.D *") == s) {
625 C67_g((C67_map_regn(b) << 23) | //dst625 C67_g(S, (C67_map_regn(S, b) << 23) | //dst
626 (C67_map_regn(a) << 18) | //base reg A15626 (C67_map_regn(S, a) << 18) | //base reg A15
627 (0 << 13) | //cst5627 (0 << 13) | //cst5
628 (1 << 9) | //mode 1 = pos cst offset628 (1 << 9) | //mode 1 = pos cst offset
629 (0 << 8) | //r (LDDW bit 0)629 (0 << 8) | //r (LDDW bit 0)
630 (C67_map_regs(a) << 7) | //y D1/D2 src side630 (C67_map_regs(S, a) << 7) | //y D1/D2 src side
631 (2 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 631 (2 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
632 (1 << 2) | //opcode632 (1 << 2) | //opcode
633 (C67_map_regs(b) << 1) | //side of dst633 (C67_map_regs(S, b) << 1) | //side of dst
634 (0 << 0)); //parallel634 (0 << 0)); //parallel
635 } else if (strstr(s, "LDHU.D *") == s) {635 } else if (strstr(s, "LDHU.D *") == s) {
636 C67_g((C67_map_regn(b) << 23) | //dst636 C67_g(S, (C67_map_regn(S, b) << 23) | //dst
637 (C67_map_regn(a) << 18) | //base reg A15637 (C67_map_regn(S, a) << 18) | //base reg A15
638 (0 << 13) | //cst5638 (0 << 13) | //cst5
639 (1 << 9) | //mode 1 = pos cst offset639 (1 << 9) | //mode 1 = pos cst offset
640 (0 << 8) | //r (LDDW bit 0)640 (0 << 8) | //r (LDDW bit 0)
641 (C67_map_regs(a) << 7) | //y D1/D2 src side641 (C67_map_regs(S, a) << 7) | //y D1/D2 src side
642 (0 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 642 (0 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
643 (1 << 2) | //opcode643 (1 << 2) | //opcode
644 (C67_map_regs(b) << 1) | //side of dst644 (C67_map_regs(S, b) << 1) | //side of dst
645 (0 << 0)); //parallel645 (0 << 0)); //parallel
646 } else if (strstr(s, "LDBU.D *") == s) {646 } else if (strstr(s, "LDBU.D *") == s) {
647 C67_g((C67_map_regn(b) << 23) | //dst647 C67_g(S, (C67_map_regn(S, b) << 23) | //dst
648 (C67_map_regn(a) << 18) | //base reg A15648 (C67_map_regn(S, a) << 18) | //base reg A15
649 (0 << 13) | //cst5649 (0 << 13) | //cst5
650 (1 << 9) | //mode 1 = pos cst offset650 (1 << 9) | //mode 1 = pos cst offset
651 (0 << 8) | //r (LDDW bit 0)651 (0 << 8) | //r (LDDW bit 0)
652 (C67_map_regs(a) << 7) | //y D1/D2 src side652 (C67_map_regs(S, a) << 7) | //y D1/D2 src side
653 (1 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU653 (1 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
654 (1 << 2) | //opcode654 (1 << 2) | //opcode
655 (C67_map_regs(b) << 1) | //side of dst655 (C67_map_regs(S, b) << 1) | //side of dst
656 (0 << 0)); //parallel656 (0 << 0)); //parallel
657 } else if (strstr(s, "LDW.D +*") == s) {657 } else if (strstr(s, "LDW.D +*") == s) {
658 C67_g((C67_map_regn(b) << 23) | //dst658 C67_g(S, (C67_map_regn(S, b) << 23) | //dst
659 (C67_map_regn(a) << 18) | //base reg A15659 (C67_map_regn(S, a) << 18) | //base reg A15
660 (1 << 13) | //cst5660 (1 << 13) | //cst5
661 (1 << 9) | //mode 1 = pos cst offset661 (1 << 9) | //mode 1 = pos cst offset
662 (0 << 8) | //r (LDDW bit 0)662 (0 << 8) | //r (LDDW bit 0)
663 (C67_map_regs(a) << 7) | //y D1/D2 src side663 (C67_map_regs(S, a) << 7) | //y D1/D2 src side
664 (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 664 (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
665 (1 << 2) | //opcode665 (1 << 2) | //opcode
666 (C67_map_regs(b) << 1) | //side of dst666 (C67_map_regs(S, b) << 1) | //side of dst
667 (0 << 0)); //parallel667 (0 << 0)); //parallel
668 } else if (strstr(s, "CMPLTSP") == s) {668 } else if (strstr(s, "CMPLTSP") == s) {
669 xpath = C67_map_regs(a) ^ C67_map_regs(b);669 xpath = C67_map_regs(S, a) ^ C67_map_regs(S, b);
670 ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));670 ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a));
671 671
672 C67_g((C67_map_regn(c) << 23) | //dst672 C67_g(S, (C67_map_regn(S, c) << 23) | //dst
673 (C67_map_regn(b) << 18) | //src2673 (C67_map_regn(S, b) << 18) | //src2
674 (C67_map_regn(a) << 13) | //src1674 (C67_map_regn(S, a) << 13) | //src1
675 (xpath << 12) | //x use cross path for src2675 (xpath << 12) | //x use cross path for src2
676 (0x3a << 6) | //opcode676 (0x3a << 6) | //opcode
677 (0x8 << 2) | //opcode fixed677 (0x8 << 2) | //opcode fixed
678 (C67_map_regs(c) << 1) | //side for reg c678 (C67_map_regs(S, c) << 1) | //side for reg c
679 (0 << 0)); //parallel679 (0 << 0)); //parallel
680 } else if (strstr(s, "CMPGTSP") == s) {680 } else if (strstr(s, "CMPGTSP") == s) {
681 xpath = C67_map_regs(a) ^ C67_map_regs(b);681 xpath = C67_map_regs(S, a) ^ C67_map_regs(S, b);
682 ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));682 ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a));
683 683
684 C67_g((C67_map_regn(c) << 23) | //dst684 C67_g(S, (C67_map_regn(S, c) << 23) | //dst
685 (C67_map_regn(b) << 18) | //src2685 (C67_map_regn(S, b) << 18) | //src2
686 (C67_map_regn(a) << 13) | //src1686 (C67_map_regn(S, a) << 13) | //src1
687 (xpath << 12) | //x use cross path for src2687 (xpath << 12) | //x use cross path for src2
688 (0x39 << 6) | //opcode688 (0x39 << 6) | //opcode
689 (0x8 << 2) | //opcode fixed689 (0x8 << 2) | //opcode fixed
690 (C67_map_regs(c) << 1) | //side for reg c690 (C67_map_regs(S, c) << 1) | //side for reg c
691 (0 << 0)); //parallel691 (0 << 0)); //parallel
692 } else if (strstr(s, "CMPEQSP") == s) {692 } else if (strstr(s, "CMPEQSP") == s) {
693 xpath = C67_map_regs(a) ^ C67_map_regs(b);693 xpath = C67_map_regs(S, a) ^ C67_map_regs(S, b);
694 ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));694 ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a));
695 695
696 C67_g((C67_map_regn(c) << 23) | //dst696 C67_g(S, (C67_map_regn(S, c) << 23) | //dst
697 (C67_map_regn(b) << 18) | //src2697 (C67_map_regn(S, b) << 18) | //src2
698 (C67_map_regn(a) << 13) | //src1698 (C67_map_regn(S, a) << 13) | //src1
699 (xpath << 12) | //x use cross path for src2699 (xpath << 12) | //x use cross path for src2
700 (0x38 << 6) | //opcode700 (0x38 << 6) | //opcode
701 (0x8 << 2) | //opcode fixed701 (0x8 << 2) | //opcode fixed
702 (C67_map_regs(c) << 1) | //side for reg c702 (C67_map_regs(S, c) << 1) | //side for reg c
703 (0 << 0)); //parallel703 (0 << 0)); //parallel
704 }704 }
705 705
706 else if (strstr(s, "CMPLTDP") == s) {706 else if (strstr(s, "CMPLTDP") == s) {
707 xpath = C67_map_regs(a) ^ C67_map_regs(b);707 xpath = C67_map_regs(S, a) ^ C67_map_regs(S, b);
708 ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));708 ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a));
709 709
710 C67_g((C67_map_regn(c) << 23) | //dst710 C67_g(S, (C67_map_regn(S, c) << 23) | //dst
711 (C67_map_regn(b) << 18) | //src2711 (C67_map_regn(S, b) << 18) | //src2
712 (C67_map_regn(a) << 13) | //src1712 (C67_map_regn(S, a) << 13) | //src1
713 (xpath << 12) | //x use cross path for src2713 (xpath << 12) | //x use cross path for src2
714 (0x2a << 6) | //opcode714 (0x2a << 6) | //opcode
715 (0x8 << 2) | //opcode fixed715 (0x8 << 2) | //opcode fixed
716 (C67_map_regs(c) << 1) | //side for reg c716 (C67_map_regs(S, c) << 1) | //side for reg c
717 (0 << 0)); //parallel717 (0 << 0)); //parallel
718 } else if (strstr(s, "CMPGTDP") == s) {718 } else if (strstr(s, "CMPGTDP") == s) {
719 xpath = C67_map_regs(a) ^ C67_map_regs(b);719 xpath = C67_map_regs(S, a) ^ C67_map_regs(S, b);
720 ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));720 ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a));
721 721
722 C67_g((C67_map_regn(c) << 23) | //dst722 C67_g(S, (C67_map_regn(S, c) << 23) | //dst
723 (C67_map_regn(b) << 18) | //src2723 (C67_map_regn(S, b) << 18) | //src2
724 (C67_map_regn(a) << 13) | //src1724 (C67_map_regn(S, a) << 13) | //src1
725 (xpath << 12) | //x use cross path for src2725 (xpath << 12) | //x use cross path for src2
726 (0x29 << 6) | //opcode726 (0x29 << 6) | //opcode
727 (0x8 << 2) | //opcode fixed727 (0x8 << 2) | //opcode fixed
728 (C67_map_regs(c) << 1) | //side for reg c728 (C67_map_regs(S, c) << 1) | //side for reg c
729 (0 << 0)); //parallel729 (0 << 0)); //parallel
730 } else if (strstr(s, "CMPEQDP") == s) {730 } else if (strstr(s, "CMPEQDP") == s) {
731 xpath = C67_map_regs(a) ^ C67_map_regs(b);731 xpath = C67_map_regs(S, a) ^ C67_map_regs(S, b);
732 ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));732 ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a));
733 733
734 C67_g((C67_map_regn(c) << 23) | //dst734 C67_g(S, (C67_map_regn(S, c) << 23) | //dst
735 (C67_map_regn(b) << 18) | //src2735 (C67_map_regn(S, b) << 18) | //src2
736 (C67_map_regn(a) << 13) | //src1736 (C67_map_regn(S, a) << 13) | //src1
737 (xpath << 12) | //x use cross path for src2737 (xpath << 12) | //x use cross path for src2
738 (0x28 << 6) | //opcode738 (0x28 << 6) | //opcode
739 (0x8 << 2) | //opcode fixed739 (0x8 << 2) | //opcode fixed
740 (C67_map_regs(c) << 1) | //side for reg c740 (C67_map_regs(S, c) << 1) | //side for reg c
741 (0 << 0)); //parallel741 (0 << 0)); //parallel
742 } else if (strstr(s, "CMPLT") == s) {742 } else if (strstr(s, "CMPLT") == s) {
743 xpath = C67_map_regs(a) ^ C67_map_regs(b);743 xpath = C67_map_regs(S, a) ^ C67_map_regs(S, b);
744 ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));744 ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a));
745 745
746 C67_g((C67_map_regn(c) << 23) | //dst746 C67_g(S, (C67_map_regn(S, c) << 23) | //dst
747 (C67_map_regn(b) << 18) | //src2747 (C67_map_regn(S, b) << 18) | //src2
748 (C67_map_regn(a) << 13) | //src1748 (C67_map_regn(S, a) << 13) | //src1
749 (xpath << 12) | //x use cross path for src2749 (xpath << 12) | //x use cross path for src2
750 (0x57 << 5) | //opcode750 (0x57 << 5) | //opcode
751 (0x6 << 2) | //opcode fixed751 (0x6 << 2) | //opcode fixed
752 (C67_map_regs(c) << 1) | //side for reg c752 (C67_map_regs(S, c) << 1) | //side for reg c
753 (0 << 0)); //parallel753 (0 << 0)); //parallel
754 } else if (strstr(s, "CMPGT") == s) {754 } else if (strstr(s, "CMPGT") == s) {
755 xpath = C67_map_regs(a) ^ C67_map_regs(b);755 xpath = C67_map_regs(S, a) ^ C67_map_regs(S, b);
756 ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));756 ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a));
757 757
758 C67_g((C67_map_regn(c) << 23) | //dst758 C67_g(S, (C67_map_regn(S, c) << 23) | //dst
759 (C67_map_regn(b) << 18) | //src2759 (C67_map_regn(S, b) << 18) | //src2
760 (C67_map_regn(a) << 13) | //src1760 (C67_map_regn(S, a) << 13) | //src1
761 (xpath << 12) | //x use cross path for src2761 (xpath << 12) | //x use cross path for src2
762 (0x47 << 5) | //opcode762 (0x47 << 5) | //opcode
763 (0x6 << 2) | //opcode fixed763 (0x6 << 2) | //opcode fixed
764 (C67_map_regs(c) << 1) | //side for reg c764 (C67_map_regs(S, c) << 1) | //side for reg c
765 (0 << 0)); //parallel765 (0 << 0)); //parallel
766 } else if (strstr(s, "CMPEQ") == s) {766 } else if (strstr(s, "CMPEQ") == s) {
767 xpath = C67_map_regs(a) ^ C67_map_regs(b);767 xpath = C67_map_regs(S, a) ^ C67_map_regs(S, b);
768 ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));768 ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a));
769 769
770 C67_g((C67_map_regn(c) << 23) | //dst770 C67_g(S, (C67_map_regn(S, c) << 23) | //dst
771 (C67_map_regn(b) << 18) | //src2771 (C67_map_regn(S, b) << 18) | //src2
772 (C67_map_regn(a) << 13) | //src1772 (C67_map_regn(S, a) << 13) | //src1
773 (xpath << 12) | //x use cross path for src2773 (xpath << 12) | //x use cross path for src2
774 (0x53 << 5) | //opcode774 (0x53 << 5) | //opcode
775 (0x6 << 2) | //opcode fixed775 (0x6 << 2) | //opcode fixed
776 (C67_map_regs(c) << 1) | //side for reg c776 (C67_map_regs(S, c) << 1) | //side for reg c
777 (0 << 0)); //parallel777 (0 << 0)); //parallel
778 } else if (strstr(s, "CMPLTU") == s) {778 } else if (strstr(s, "CMPLTU") == s) {
779 xpath = C67_map_regs(a) ^ C67_map_regs(b);779 xpath = C67_map_regs(S, a) ^ C67_map_regs(S, b);
780 ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));780 ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a));
781 781
782 C67_g((C67_map_regn(c) << 23) | //dst782 C67_g(S, (C67_map_regn(S, c) << 23) | //dst
783 (C67_map_regn(b) << 18) | //src2783 (C67_map_regn(S, b) << 18) | //src2
784 (C67_map_regn(a) << 13) | //src1784 (C67_map_regn(S, a) << 13) | //src1
785 (xpath << 12) | //x use cross path for src2785 (xpath << 12) | //x use cross path for src2
786 (0x5f << 5) | //opcode786 (0x5f << 5) | //opcode
787 (0x6 << 2) | //opcode fixed787 (0x6 << 2) | //opcode fixed
788 (C67_map_regs(c) << 1) | //side for reg c788 (C67_map_regs(S, c) << 1) | //side for reg c
789 (0 << 0)); //parallel789 (0 << 0)); //parallel
790 } else if (strstr(s, "CMPGTU") == s) {790 } else if (strstr(s, "CMPGTU") == s) {
791 xpath = C67_map_regs(a) ^ C67_map_regs(b);791 xpath = C67_map_regs(S, a) ^ C67_map_regs(S, b);
792 ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));792 ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a));
793 793
794 C67_g((C67_map_regn(c) << 23) | //dst794 C67_g(S, (C67_map_regn(S, c) << 23) | //dst
795 (C67_map_regn(b) << 18) | //src2795 (C67_map_regn(S, b) << 18) | //src2
796 (C67_map_regn(a) << 13) | //src1796 (C67_map_regn(S, a) << 13) | //src1
797 (xpath << 12) | //x use cross path for src2797 (xpath << 12) | //x use cross path for src2
798 (0x4f << 5) | //opcode798 (0x4f << 5) | //opcode
799 (0x6 << 2) | //opcode fixed799 (0x6 << 2) | //opcode fixed
800 (C67_map_regs(c) << 1) | //side for reg c800 (C67_map_regs(S, c) << 1) | //side for reg c
801 (0 << 0)); //parallel801 (0 << 0)); //parallel
802 } else if (strstr(s, "B DISP") == s) {802 } else if (strstr(s, "B DISP") == s) {
803 C67_g((0 << 29) | //creg803 C67_g(S, (0 << 29) | //creg
804 (0 << 28) | //z804 (0 << 28) | //z
805 (a << 7) | //cnst805 (a << 7) | //cnst
806 (0x4 << 2) | //opcode fixed806 (0x4 << 2) | //opcode fixed
807 (0 << 1) | //S0/S1807 (0 << 1) | //S0/S1
808 (0 << 0)); //parallel808 (0 << 0)); //parallel
809 } else if (strstr(s, "B.") == s) {809 } else if (strstr(s, "B.") == s) {
810 xpath = C67_map_regs(c) ^ 1;810 xpath = C67_map_regs(S, c) ^ 1;
811 811
812 C67_g((C67_map_regc(b) << 29) | //creg812 C67_g(S, (C67_map_regc(S, b) << 29) | //creg
813 (a << 28) | //inv813 (a << 28) | //inv
814 (0 << 23) | //dst814 (0 << 23) | //dst
815 (C67_map_regn(c) << 18) | //src2815 (C67_map_regn(S, c) << 18) | //src2
816 (0 << 13) | //816 (0 << 13) | //
817 (xpath << 12) | //x cross path if !B side817 (xpath << 12) | //x cross path if !B side
818 (0xd << 6) | //opcode818 (0xd << 6) | //opcode
@@ -820,369 +820,369 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line
820 (1 << 1) | //must be S2820 (1 << 1) | //must be S2
821 (0 << 0)); //parallel821 (0 << 0)); //parallel
822 } else if (strstr(s, "MV.L") == s) {822 } else if (strstr(s, "MV.L") == s) {
823 xpath = C67_map_regs(b) ^ C67_map_regs(c);823 xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c);
824 824
825 C67_g((0 << 29) | //creg825 C67_g(S, (0 << 29) | //creg
826 (0 << 28) | //inv826 (0 << 28) | //inv
827 (C67_map_regn(c) << 23) | //dst827 (C67_map_regn(S, c) << 23) | //dst
828 (C67_map_regn(b) << 18) | //src2828 (C67_map_regn(S, b) << 18) | //src2
829 (0 << 13) | //src1 (cst5)829 (0 << 13) | //src1 (cst5)
830 (xpath << 12) | //x cross path if opposite sides830 (xpath << 12) | //x cross path if opposite sides
831 (0x2 << 5) | //opcode831 (0x2 << 5) | //opcode
832 (0x6 << 2) | //opcode fixed832 (0x6 << 2) | //opcode fixed
833 (C67_map_regs(c) << 1) | //side of dest833 (C67_map_regs(S, c) << 1) | //side of dest
834 (0 << 0)); //parallel834 (0 << 0)); //parallel
835 } else if (strstr(s, "SPTRUNC.L") == s) {835 } else if (strstr(s, "SPTRUNC.L") == s) {
836 xpath = C67_map_regs(b) ^ C67_map_regs(c);836 xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c);
837 837
838 C67_g((0 << 29) | //creg838 C67_g(S, (0 << 29) | //creg
839 (0 << 28) | //inv839 (0 << 28) | //inv
840 (C67_map_regn(c) << 23) | //dst840 (C67_map_regn(S, c) << 23) | //dst
841 (C67_map_regn(b) << 18) | //src2841 (C67_map_regn(S, b) << 18) | //src2
842 (0 << 13) | //src1 NA842 (0 << 13) | //src1 NA
843 (xpath << 12) | //x cross path if opposite sides843 (xpath << 12) | //x cross path if opposite sides
844 (0xb << 5) | //opcode844 (0xb << 5) | //opcode
845 (0x6 << 2) | //opcode fixed845 (0x6 << 2) | //opcode fixed
846 (C67_map_regs(c) << 1) | //side of dest846 (C67_map_regs(S, c) << 1) | //side of dest
847 (0 << 0)); //parallel847 (0 << 0)); //parallel
848 } else if (strstr(s, "DPTRUNC.L") == s) {848 } else if (strstr(s, "DPTRUNC.L") == s) {
849 xpath = C67_map_regs(b) ^ C67_map_regs(c);849 xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c);
850 850
851 C67_g((0 << 29) | //creg851 C67_g(S, (0 << 29) | //creg
852 (0 << 28) | //inv852 (0 << 28) | //inv
853 (C67_map_regn(c) << 23) | //dst853 (C67_map_regn(S, c) << 23) | //dst
854 ((C67_map_regn(b) + 1) << 18) | //src2 WEIRD CPU must specify odd reg for some reason854 ((C67_map_regn(S, b) + 1) << 18) | //src2 WEIRD CPU must specify odd reg for some reason
855 (0 << 13) | //src1 NA855 (0 << 13) | //src1 NA
856 (xpath << 12) | //x cross path if opposite sides856 (xpath << 12) | //x cross path if opposite sides
857 (0x1 << 5) | //opcode857 (0x1 << 5) | //opcode
858 (0x6 << 2) | //opcode fixed858 (0x6 << 2) | //opcode fixed
859 (C67_map_regs(c) << 1) | //side of dest859 (C67_map_regs(S, c) << 1) | //side of dest
860 (0 << 0)); //parallel860 (0 << 0)); //parallel
861 } else if (strstr(s, "INTSP.L") == s) {861 } else if (strstr(s, "INTSP.L") == s) {
862 xpath = C67_map_regs(b) ^ C67_map_regs(c);862 xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c);
863 863
864 C67_g((0 << 29) | //creg864 C67_g(S, (0 << 29) | //creg
865 (0 << 28) | //inv865 (0 << 28) | //inv
866 (C67_map_regn(c) << 23) | //dst866 (C67_map_regn(S, c) << 23) | //dst
867 (C67_map_regn(b) << 18) | //src2 867 (C67_map_regn(S, b) << 18) | //src2
868 (0 << 13) | //src1 NA868 (0 << 13) | //src1 NA
869 (xpath << 12) | //x cross path if opposite sides869 (xpath << 12) | //x cross path if opposite sides
870 (0x4a << 5) | //opcode870 (0x4a << 5) | //opcode
871 (0x6 << 2) | //opcode fixed871 (0x6 << 2) | //opcode fixed
872 (C67_map_regs(c) << 1) | //side of dest872 (C67_map_regs(S, c) << 1) | //side of dest
873 (0 << 0)); //parallel873 (0 << 0)); //parallel
874 } else if (strstr(s, "INTSPU.L") == s) {874 } else if (strstr(s, "INTSPU.L") == s) {
875 xpath = C67_map_regs(b) ^ C67_map_regs(c);875 xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c);
876 876
877 C67_g((0 << 29) | //creg877 C67_g(S, (0 << 29) | //creg
878 (0 << 28) | //inv878 (0 << 28) | //inv
879 (C67_map_regn(c) << 23) | //dst879 (C67_map_regn(S, c) << 23) | //dst
880 (C67_map_regn(b) << 18) | //src2 880 (C67_map_regn(S, b) << 18) | //src2
881 (0 << 13) | //src1 NA881 (0 << 13) | //src1 NA
882 (xpath << 12) | //x cross path if opposite sides882 (xpath << 12) | //x cross path if opposite sides
883 (0x49 << 5) | //opcode883 (0x49 << 5) | //opcode
884 (0x6 << 2) | //opcode fixed884 (0x6 << 2) | //opcode fixed
885 (C67_map_regs(c) << 1) | //side of dest885 (C67_map_regs(S, c) << 1) | //side of dest
886 (0 << 0)); //parallel886 (0 << 0)); //parallel
887 } else if (strstr(s, "INTDP.L") == s) {887 } else if (strstr(s, "INTDP.L") == s) {
888 xpath = C67_map_regs(b) ^ C67_map_regs(c);888 xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c);
889 889
890 C67_g((0 << 29) | //creg890 C67_g(S, (0 << 29) | //creg
891 (0 << 28) | //inv891 (0 << 28) | //inv
892 (C67_map_regn(c) << 23) | //dst892 (C67_map_regn(S, c) << 23) | //dst
893 (C67_map_regn(b) << 18) | //src2 893 (C67_map_regn(S, b) << 18) | //src2
894 (0 << 13) | //src1 NA894 (0 << 13) | //src1 NA
895 (xpath << 12) | //x cross path if opposite sides895 (xpath << 12) | //x cross path if opposite sides
896 (0x39 << 5) | //opcode896 (0x39 << 5) | //opcode
897 (0x6 << 2) | //opcode fixed897 (0x6 << 2) | //opcode fixed
898 (C67_map_regs(c) << 1) | //side of dest898 (C67_map_regs(S, c) << 1) | //side of dest
899 (0 << 0)); //parallel899 (0 << 0)); //parallel
900 } else if (strstr(s, "INTDPU.L") == s) {900 } else if (strstr(s, "INTDPU.L") == s) {
901 xpath = C67_map_regs(b) ^ C67_map_regs(c);901 xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c);
902 902
903 C67_g((0 << 29) | //creg903 C67_g(S, (0 << 29) | //creg
904 (0 << 28) | //inv904 (0 << 28) | //inv
905 (C67_map_regn(c) << 23) | //dst905 (C67_map_regn(S, c) << 23) | //dst
906 ((C67_map_regn(b) + 1) << 18) | //src2 WEIRD CPU must specify odd reg for some reason906 ((C67_map_regn(S, b) + 1) << 18) | //src2 WEIRD CPU must specify odd reg for some reason
907 (0 << 13) | //src1 NA907 (0 << 13) | //src1 NA
908 (xpath << 12) | //x cross path if opposite sides908 (xpath << 12) | //x cross path if opposite sides
909 (0x3b << 5) | //opcode909 (0x3b << 5) | //opcode
910 (0x6 << 2) | //opcode fixed910 (0x6 << 2) | //opcode fixed
911 (C67_map_regs(c) << 1) | //side of dest911 (C67_map_regs(S, c) << 1) | //side of dest
912 (0 << 0)); //parallel912 (0 << 0)); //parallel
913 } else if (strstr(s, "SPDP.L") == s) {913 } else if (strstr(s, "SPDP.L") == s) {
914 xpath = C67_map_regs(b) ^ C67_map_regs(c);914 xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c);
915 915
916 C67_g((0 << 29) | //creg916 C67_g(S, (0 << 29) | //creg
917 (0 << 28) | //inv917 (0 << 28) | //inv
918 (C67_map_regn(c) << 23) | //dst918 (C67_map_regn(S, c) << 23) | //dst
919 (C67_map_regn(b) << 18) | //src2919 (C67_map_regn(S, b) << 18) | //src2
920 (0 << 13) | //src1 NA920 (0 << 13) | //src1 NA
921 (xpath << 12) | //x cross path if opposite sides921 (xpath << 12) | //x cross path if opposite sides
922 (0x2 << 6) | //opcode922 (0x2 << 6) | //opcode
923 (0x8 << 2) | //opcode fixed923 (0x8 << 2) | //opcode fixed
924 (C67_map_regs(c) << 1) | //side of dest924 (C67_map_regs(S, c) << 1) | //side of dest
925 (0 << 0)); //parallel925 (0 << 0)); //parallel
926 } else if (strstr(s, "DPSP.L") == s) {926 } else if (strstr(s, "DPSP.L") == s) {
927 ALWAYS_ASSERT(C67_map_regs(b) == C67_map_regs(c));927 ALWAYS_ASSERT(C67_map_regs(S, b) == C67_map_regs(S, c));
928 928
929 C67_g((0 << 29) | //creg929 C67_g(S, (0 << 29) | //creg
930 (0 << 28) | //inv930 (0 << 28) | //inv
931 (C67_map_regn(c) << 23) | //dst931 (C67_map_regn(S, c) << 23) | //dst
932 ((C67_map_regn(b) + 1) << 18) | //src2 WEIRD CPU must specify odd reg for some reason932 ((C67_map_regn(S, b) + 1) << 18) | //src2 WEIRD CPU must specify odd reg for some reason
933 (0 << 13) | //src1 NA933 (0 << 13) | //src1 NA
934 (0 << 12) | //x cross path if opposite sides934 (0 << 12) | //x cross path if opposite sides
935 (0x9 << 5) | //opcode935 (0x9 << 5) | //opcode
936 (0x6 << 2) | //opcode fixed936 (0x6 << 2) | //opcode fixed
937 (C67_map_regs(c) << 1) | //side of dest937 (C67_map_regs(S, c) << 1) | //side of dest
938 (0 << 0)); //parallel938 (0 << 0)); //parallel
939 } else if (strstr(s, "ADD.L") == s) {939 } else if (strstr(s, "ADD.L") == s) {
940 xpath = C67_map_regs(b) ^ C67_map_regs(c);940 xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c);
941 941
942 ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));942 ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c));
943 943
944 C67_g((0 << 29) | //creg944 C67_g(S, (0 << 29) | //creg
945 (0 << 28) | //inv945 (0 << 28) | //inv
946 (C67_map_regn(c) << 23) | //dst946 (C67_map_regn(S, c) << 23) | //dst
947 (C67_map_regn(b) << 18) | //src2 (possible x path)947 (C67_map_regn(S, b) << 18) | //src2 (possible x path)
948 (C67_map_regn(a) << 13) | //src1 948 (C67_map_regn(S, a) << 13) | //src1
949 (xpath << 12) | //x cross path if opposite sides949 (xpath << 12) | //x cross path if opposite sides
950 (0x3 << 5) | //opcode950 (0x3 << 5) | //opcode
951 (0x6 << 2) | //opcode fixed951 (0x6 << 2) | //opcode fixed
952 (C67_map_regs(c) << 1) | //side of dest952 (C67_map_regs(S, c) << 1) | //side of dest
953 (0 << 0)); //parallel953 (0 << 0)); //parallel
954 } else if (strstr(s, "SUB.L") == s) {954 } else if (strstr(s, "SUB.L") == s) {
955 xpath = C67_map_regs(b) ^ C67_map_regs(c);955 xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c);
956 956
957 ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));957 ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c));
958 958
959 C67_g((0 << 29) | //creg959 C67_g(S, (0 << 29) | //creg
960 (0 << 28) | //inv960 (0 << 28) | //inv
961 (C67_map_regn(c) << 23) | //dst961 (C67_map_regn(S, c) << 23) | //dst
962 (C67_map_regn(b) << 18) | //src2 (possible x path)962 (C67_map_regn(S, b) << 18) | //src2 (possible x path)
963 (C67_map_regn(a) << 13) | //src1 963 (C67_map_regn(S, a) << 13) | //src1
964 (xpath << 12) | //x cross path if opposite sides964 (xpath << 12) | //x cross path if opposite sides
965 (0x7 << 5) | //opcode965 (0x7 << 5) | //opcode
966 (0x6 << 2) | //opcode fixed966 (0x6 << 2) | //opcode fixed
967 (C67_map_regs(c) << 1) | //side of dest967 (C67_map_regs(S, c) << 1) | //side of dest
968 (0 << 0)); //parallel968 (0 << 0)); //parallel
969 } else if (strstr(s, "OR.L") == s) {969 } else if (strstr(s, "OR.L") == s) {
970 xpath = C67_map_regs(b) ^ C67_map_regs(c);970 xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c);
971 971
972 ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));972 ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c));
973 973
974 C67_g((0 << 29) | //creg974 C67_g(S, (0 << 29) | //creg
975 (0 << 28) | //inv975 (0 << 28) | //inv
976 (C67_map_regn(c) << 23) | //dst976 (C67_map_regn(S, c) << 23) | //dst
977 (C67_map_regn(b) << 18) | //src2 (possible x path)977 (C67_map_regn(S, b) << 18) | //src2 (possible x path)
978 (C67_map_regn(a) << 13) | //src1 978 (C67_map_regn(S, a) << 13) | //src1
979 (xpath << 12) | //x cross path if opposite sides979 (xpath << 12) | //x cross path if opposite sides
980 (0x7f << 5) | //opcode980 (0x7f << 5) | //opcode
981 (0x6 << 2) | //opcode fixed981 (0x6 << 2) | //opcode fixed
982 (C67_map_regs(c) << 1) | //side of dest982 (C67_map_regs(S, c) << 1) | //side of dest
983 (0 << 0)); //parallel983 (0 << 0)); //parallel
984 } else if (strstr(s, "AND.L") == s) {984 } else if (strstr(s, "AND.L") == s) {
985 xpath = C67_map_regs(b) ^ C67_map_regs(c);985 xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c);
986 986
987 ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));987 ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c));
988 988
989 C67_g((0 << 29) | //creg989 C67_g(S, (0 << 29) | //creg
990 (0 << 28) | //inv990 (0 << 28) | //inv
991 (C67_map_regn(c) << 23) | //dst991 (C67_map_regn(S, c) << 23) | //dst
992 (C67_map_regn(b) << 18) | //src2 (possible x path)992 (C67_map_regn(S, b) << 18) | //src2 (possible x path)
993 (C67_map_regn(a) << 13) | //src1 993 (C67_map_regn(S, a) << 13) | //src1
994 (xpath << 12) | //x cross path if opposite sides994 (xpath << 12) | //x cross path if opposite sides
995 (0x7b << 5) | //opcode995 (0x7b << 5) | //opcode
996 (0x6 << 2) | //opcode fixed996 (0x6 << 2) | //opcode fixed
997 (C67_map_regs(c) << 1) | //side of dest997 (C67_map_regs(S, c) << 1) | //side of dest
998 (0 << 0)); //parallel998 (0 << 0)); //parallel
999 } else if (strstr(s, "XOR.L") == s) {999 } else if (strstr(s, "XOR.L") == s) {
1000 xpath = C67_map_regs(b) ^ C67_map_regs(c);1000 xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c);
1001 1001
1002 ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));1002 ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c));
1003 1003
1004 C67_g((0 << 29) | //creg1004 C67_g(S, (0 << 29) | //creg
1005 (0 << 28) | //inv1005 (0 << 28) | //inv
1006 (C67_map_regn(c) << 23) | //dst1006 (C67_map_regn(S, c) << 23) | //dst
1007 (C67_map_regn(b) << 18) | //src2 (possible x path)1007 (C67_map_regn(S, b) << 18) | //src2 (possible x path)
1008 (C67_map_regn(a) << 13) | //src1 1008 (C67_map_regn(S, a) << 13) | //src1
1009 (xpath << 12) | //x cross path if opposite sides1009 (xpath << 12) | //x cross path if opposite sides
1010 (0x6f << 5) | //opcode1010 (0x6f << 5) | //opcode
1011 (0x6 << 2) | //opcode fixed1011 (0x6 << 2) | //opcode fixed
1012 (C67_map_regs(c) << 1) | //side of dest1012 (C67_map_regs(S, c) << 1) | //side of dest
1013 (0 << 0)); //parallel1013 (0 << 0)); //parallel
1014 } else if (strstr(s, "ADDSP.L") == s) {1014 } else if (strstr(s, "ADDSP.L") == s) {
1015 xpath = C67_map_regs(b) ^ C67_map_regs(c);1015 xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c);
1016 1016
1017 ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));1017 ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c));
1018 1018
1019 C67_g((0 << 29) | //creg1019 C67_g(S, (0 << 29) | //creg
1020 (0 << 28) | //inv1020 (0 << 28) | //inv
1021 (C67_map_regn(c) << 23) | //dst1021 (C67_map_regn(S, c) << 23) | //dst
1022 (C67_map_regn(b) << 18) | //src2 (possible x path)1022 (C67_map_regn(S, b) << 18) | //src2 (possible x path)
1023 (C67_map_regn(a) << 13) | //src1 1023 (C67_map_regn(S, a) << 13) | //src1
1024 (xpath << 12) | //x cross path if opposite sides1024 (xpath << 12) | //x cross path if opposite sides
1025 (0x10 << 5) | //opcode1025 (0x10 << 5) | //opcode
1026 (0x6 << 2) | //opcode fixed1026 (0x6 << 2) | //opcode fixed
1027 (C67_map_regs(c) << 1) | //side of dest1027 (C67_map_regs(S, c) << 1) | //side of dest
1028 (0 << 0)); //parallel1028 (0 << 0)); //parallel
1029 } else if (strstr(s, "ADDDP.L") == s) {1029 } else if (strstr(s, "ADDDP.L") == s) {
1030 xpath = C67_map_regs(b) ^ C67_map_regs(c);1030 xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c);
1031 1031
1032 ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));1032 ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c));
1033 1033
1034 C67_g((0 << 29) | //creg1034 C67_g(S, (0 << 29) | //creg
1035 (0 << 28) | //inv1035 (0 << 28) | //inv
1036 (C67_map_regn(c) << 23) | //dst1036 (C67_map_regn(S, c) << 23) | //dst
1037 (C67_map_regn(b) << 18) | //src2 (possible x path)1037 (C67_map_regn(S, b) << 18) | //src2 (possible x path)
1038 (C67_map_regn(a) << 13) | //src1 1038 (C67_map_regn(S, a) << 13) | //src1
1039 (xpath << 12) | //x cross path if opposite sides1039 (xpath << 12) | //x cross path if opposite sides
1040 (0x18 << 5) | //opcode1040 (0x18 << 5) | //opcode
1041 (0x6 << 2) | //opcode fixed1041 (0x6 << 2) | //opcode fixed
1042 (C67_map_regs(c) << 1) | //side of dest1042 (C67_map_regs(S, c) << 1) | //side of dest
1043 (0 << 0)); //parallel1043 (0 << 0)); //parallel
1044 } else if (strstr(s, "SUBSP.L") == s) {1044 } else if (strstr(s, "SUBSP.L") == s) {
1045 xpath = C67_map_regs(b) ^ C67_map_regs(c);1045 xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c);
1046 1046
1047 ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));1047 ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c));
1048 1048
1049 C67_g((0 << 29) | //creg1049 C67_g(S, (0 << 29) | //creg
1050 (0 << 28) | //inv1050 (0 << 28) | //inv
1051 (C67_map_regn(c) << 23) | //dst1051 (C67_map_regn(S, c) << 23) | //dst
1052 (C67_map_regn(b) << 18) | //src2 (possible x path)1052 (C67_map_regn(S, b) << 18) | //src2 (possible x path)
1053 (C67_map_regn(a) << 13) | //src1 1053 (C67_map_regn(S, a) << 13) | //src1
1054 (xpath << 12) | //x cross path if opposite sides1054 (xpath << 12) | //x cross path if opposite sides
1055 (0x11 << 5) | //opcode1055 (0x11 << 5) | //opcode
1056 (0x6 << 2) | //opcode fixed1056 (0x6 << 2) | //opcode fixed
1057 (C67_map_regs(c) << 1) | //side of dest1057 (C67_map_regs(S, c) << 1) | //side of dest
1058 (0 << 0)); //parallel1058 (0 << 0)); //parallel
1059 } else if (strstr(s, "SUBDP.L") == s) {1059 } else if (strstr(s, "SUBDP.L") == s) {
1060 xpath = C67_map_regs(b) ^ C67_map_regs(c);1060 xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c);
1061 1061
1062 ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));1062 ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c));
1063 1063
1064 C67_g((0 << 29) | //creg1064 C67_g(S, (0 << 29) | //creg
1065 (0 << 28) | //inv1065 (0 << 28) | //inv
1066 (C67_map_regn(c) << 23) | //dst1066 (C67_map_regn(S, c) << 23) | //dst
1067 (C67_map_regn(b) << 18) | //src2 (possible x path)1067 (C67_map_regn(S, b) << 18) | //src2 (possible x path)
1068 (C67_map_regn(a) << 13) | //src1 1068 (C67_map_regn(S, a) << 13) | //src1
1069 (xpath << 12) | //x cross path if opposite sides1069 (xpath << 12) | //x cross path if opposite sides
1070 (0x19 << 5) | //opcode1070 (0x19 << 5) | //opcode
1071 (0x6 << 2) | //opcode fixed1071 (0x6 << 2) | //opcode fixed
1072 (C67_map_regs(c) << 1) | //side of dest1072 (C67_map_regs(S, c) << 1) | //side of dest
1073 (0 << 0)); //parallel1073 (0 << 0)); //parallel
1074 } else if (strstr(s, "MPYSP.M") == s) {1074 } else if (strstr(s, "MPYSP.M") == s) {
1075 xpath = C67_map_regs(b) ^ C67_map_regs(c);1075 xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c);
1076 1076
1077 ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));1077 ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c));
1078 1078
1079 C67_g((0 << 29) | //creg1079 C67_g(S, (0 << 29) | //creg
1080 (0 << 28) | //inv1080 (0 << 28) | //inv
1081 (C67_map_regn(c) << 23) | //dst1081 (C67_map_regn(S, c) << 23) | //dst
1082 (C67_map_regn(b) << 18) | //src2 (possible x path)1082 (C67_map_regn(S, b) << 18) | //src2 (possible x path)
1083 (C67_map_regn(a) << 13) | //src1 1083 (C67_map_regn(S, a) << 13) | //src1
1084 (xpath << 12) | //x cross path if opposite sides1084 (xpath << 12) | //x cross path if opposite sides
1085 (0x1c << 7) | //opcode1085 (0x1c << 7) | //opcode
1086 (0x0 << 2) | //opcode fixed1086 (0x0 << 2) | //opcode fixed
1087 (C67_map_regs(c) << 1) | //side of dest1087 (C67_map_regs(S, c) << 1) | //side of dest
1088 (0 << 0)); //parallel1088 (0 << 0)); //parallel
1089 } else if (strstr(s, "MPYDP.M") == s) {1089 } else if (strstr(s, "MPYDP.M") == s) {
1090 xpath = C67_map_regs(b) ^ C67_map_regs(c);1090 xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c);
1091 1091
1092 ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));1092 ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c));
1093 1093
1094 C67_g((0 << 29) | //creg1094 C67_g(S, (0 << 29) | //creg
1095 (0 << 28) | //inv1095 (0 << 28) | //inv
1096 (C67_map_regn(c) << 23) | //dst1096 (C67_map_regn(S, c) << 23) | //dst
1097 (C67_map_regn(b) << 18) | //src2 (possible x path)1097 (C67_map_regn(S, b) << 18) | //src2 (possible x path)
1098 (C67_map_regn(a) << 13) | //src1 1098 (C67_map_regn(S, a) << 13) | //src1
1099 (xpath << 12) | //x cross path if opposite sides1099 (xpath << 12) | //x cross path if opposite sides
1100 (0x0e << 7) | //opcode1100 (0x0e << 7) | //opcode
1101 (0x0 << 2) | //opcode fixed1101 (0x0 << 2) | //opcode fixed
1102 (C67_map_regs(c) << 1) | //side of dest1102 (C67_map_regs(S, c) << 1) | //side of dest
1103 (0 << 0)); //parallel1103 (0 << 0)); //parallel
1104 } else if (strstr(s, "MPYI.M") == s) {1104 } else if (strstr(s, "MPYI.M") == s) {
1105 xpath = C67_map_regs(b) ^ C67_map_regs(c);1105 xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c);
1106 1106
1107 ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));1107 ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c));
1108 1108
1109 C67_g((0 << 29) | //creg1109 C67_g(S, (0 << 29) | //creg
1110 (0 << 28) | //inv1110 (0 << 28) | //inv
1111 (C67_map_regn(c) << 23) | //dst1111 (C67_map_regn(S, c) << 23) | //dst
1112 (C67_map_regn(b) << 18) | //src21112 (C67_map_regn(S, b) << 18) | //src2
1113 (C67_map_regn(a) << 13) | //src1 (cst5)1113 (C67_map_regn(S, a) << 13) | //src1 (cst5)
1114 (xpath << 12) | //x cross path if opposite sides1114 (xpath << 12) | //x cross path if opposite sides
1115 (0x4 << 7) | //opcode1115 (0x4 << 7) | //opcode
1116 (0x0 << 2) | //opcode fixed1116 (0x0 << 2) | //opcode fixed
1117 (C67_map_regs(c) << 1) | //side of dest1117 (C67_map_regs(S, c) << 1) | //side of dest
1118 (0 << 0)); //parallel1118 (0 << 0)); //parallel
1119 } else if (strstr(s, "SHR.S") == s) {1119 } else if (strstr(s, "SHR.S") == s) {
1120 xpath = C67_map_regs(b) ^ C67_map_regs(c);1120 xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c);
1121 1121
1122 ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));1122 ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a));
1123 1123
1124 C67_g((0 << 29) | //creg1124 C67_g(S, (0 << 29) | //creg
1125 (0 << 28) | //inv1125 (0 << 28) | //inv
1126 (C67_map_regn(c) << 23) | //dst1126 (C67_map_regn(S, c) << 23) | //dst
1127 (C67_map_regn(b) << 18) | //src21127 (C67_map_regn(S, b) << 18) | //src2
1128 (C67_map_regn(a) << 13) | //src1 1128 (C67_map_regn(S, a) << 13) | //src1
1129 (xpath << 12) | //x cross path if opposite sides1129 (xpath << 12) | //x cross path if opposite sides
1130 (0x37 << 6) | //opcode1130 (0x37 << 6) | //opcode
1131 (0x8 << 2) | //opcode fixed1131 (0x8 << 2) | //opcode fixed
1132 (C67_map_regs(c) << 1) | //side of dest1132 (C67_map_regs(S, c) << 1) | //side of dest
1133 (0 << 0)); //parallel1133 (0 << 0)); //parallel
1134 } else if (strstr(s, "SHRU.S") == s) {1134 } else if (strstr(s, "SHRU.S") == s) {
1135 xpath = C67_map_regs(b) ^ C67_map_regs(c);1135 xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c);
1136 1136
1137 ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));1137 ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a));
1138 1138
1139 C67_g((0 << 29) | //creg1139 C67_g(S, (0 << 29) | //creg
1140 (0 << 28) | //inv1140 (0 << 28) | //inv
1141 (C67_map_regn(c) << 23) | //dst1141 (C67_map_regn(S, c) << 23) | //dst
1142 (C67_map_regn(b) << 18) | //src21142 (C67_map_regn(S, b) << 18) | //src2
1143 (C67_map_regn(a) << 13) | //src1 1143 (C67_map_regn(S, a) << 13) | //src1
1144 (xpath << 12) | //x cross path if opposite sides1144 (xpath << 12) | //x cross path if opposite sides
1145 (0x27 << 6) | //opcode1145 (0x27 << 6) | //opcode
1146 (0x8 << 2) | //opcode fixed1146 (0x8 << 2) | //opcode fixed
1147 (C67_map_regs(c) << 1) | //side of dest1147 (C67_map_regs(S, c) << 1) | //side of dest
1148 (0 << 0)); //parallel1148 (0 << 0)); //parallel
1149 } else if (strstr(s, "SHL.S") == s) {1149 } else if (strstr(s, "SHL.S") == s) {
1150 xpath = C67_map_regs(b) ^ C67_map_regs(c);1150 xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c);
1151 1151
1152 ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));1152 ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a));
1153 1153
1154 C67_g((0 << 29) | //creg1154 C67_g(S, (0 << 29) | //creg
1155 (0 << 28) | //inv1155 (0 << 28) | //inv
1156 (C67_map_regn(c) << 23) | //dst1156 (C67_map_regn(S, c) << 23) | //dst
1157 (C67_map_regn(b) << 18) | //src21157 (C67_map_regn(S, b) << 18) | //src2
1158 (C67_map_regn(a) << 13) | //src1 1158 (C67_map_regn(S, a) << 13) | //src1
1159 (xpath << 12) | //x cross path if opposite sides1159 (xpath << 12) | //x cross path if opposite sides
1160 (0x33 << 6) | //opcode1160 (0x33 << 6) | //opcode
1161 (0x8 << 2) | //opcode fixed1161 (0x8 << 2) | //opcode fixed
1162 (C67_map_regs(c) << 1) | //side of dest1162 (C67_map_regs(S, c) << 1) | //side of dest
1163 (0 << 0)); //parallel1163 (0 << 0)); //parallel
1164 } else if (strstr(s, "||ADDK") == s) {1164 } else if (strstr(s, "||ADDK") == s) {
1165 xpath = 0; // no xpath required just use the side of the src/dst1165 xpath = 0; // no xpath required just use the side of the src/dst
1166 1166
1167 C67_g((0 << 29) | //creg1167 C67_g(S, (0 << 29) | //creg
1168 (0 << 28) | //inv1168 (0 << 28) | //inv
1169 (C67_map_regn(b) << 23) | //dst1169 (C67_map_regn(S, b) << 23) | //dst
1170 (a << 07) | //scst161170 (a << 07) | //scst16
1171 (0x14 << 2) | //opcode fixed1171 (0x14 << 2) | //opcode fixed
1172 (C67_map_regs(b) << 1) | //side of dst1172 (C67_map_regs(S, b) << 1) | //side of dst
1173 (1 << 0)); //parallel1173 (1 << 0)); //parallel
1174 } else if (strstr(s, "ADDK") == s) {1174 } else if (strstr(s, "ADDK") == s) {
1175 xpath = 0; // no xpath required just use the side of the src/dst1175 xpath = 0; // no xpath required just use the side of the src/dst
1176 1176
1177 C67_g((0 << 29) | //creg1177 C67_g(S, (0 << 29) | //creg
1178 (0 << 28) | //inv1178 (0 << 28) | //inv
1179 (C67_map_regn(b) << 23) | //dst1179 (C67_map_regn(S, b) << 23) | //dst
1180 (a << 07) | //scst161180 (a << 07) | //scst16
1181 (0x14 << 2) | //opcode fixed1181 (0x14 << 2) | //opcode fixed
1182 (C67_map_regs(b) << 1) | //side of dst1182 (C67_map_regs(S, b) << 1) | //side of dst
1183 (0 << 0)); //parallel1183 (0 << 0)); //parallel
1184 } else if (strstr(s, "NOP") == s) {1184 } else if (strstr(s, "NOP") == s) {
1185 C67_g(((a - 1) << 13) | //no of cycles1185 C67_g(S, ((a - 1) << 13) | //no of cycles
1186 (0 << 0)); //parallel1186 (0 << 0)); //parallel
1187 } else1187 } else
1188 ALWAYS_ASSERT(FALSE);1188 ALWAYS_ASSERT(FALSE);
@@ -1195,198 +1195,198 @@ void C67_asm(const char *s, int a, int b, int c) · 6 unmodified lines
1195 1195
1196//r=reg to load, fr=from reg, symbol for relocation, constant1196//r=reg to load, fr=from reg, symbol for relocation, constant
1197 1197
1198void C67_MVKL(int r, int fc)1198void C67_MVKL(TCCState* S, int r, int fc)
1199{1199{
1200 C67_asm("MVKL.", fc, r, 0);1200 C67_asm(S, "MVKL.", fc, r, 0);
1201}1201}
1202 1202
1203void C67_MVKH(int r, int fc)1203void C67_MVKH(TCCState* S, int r, int fc)
1204{1204{
1205 C67_asm("MVKH.", fc, r, 0);1205 C67_asm(S, "MVKH.", fc, r, 0);
1206}1206}
1207 1207
1208void C67_STB_SP_A0(int r)1208void C67_STB_SP_A0(TCCState* S, int r)
1209{1209{
1210 C67_asm("STB.D *+SP[A0]", r, 0, 0); // STB r,*+SP[A0]1210 C67_asm(S, "STB.D *+SP[A0]", r, 0, 0); // STB r,*+SP[A0]
1211}1211}
1212 1212
1213void C67_STH_SP_A0(int r)1213void C67_STH_SP_A0(TCCState* S, int r)
1214{1214{
1215 C67_asm("STH.D *+SP[A0]", r, 0, 0); // STH r,*+SP[A0]1215 C67_asm(S, "STH.D *+SP[A0]", r, 0, 0); // STH r,*+SP[A0]
1216}1216}
1217 1217
1218void C67_STW_SP_A0(int r)1218void C67_STW_SP_A0(TCCState* S, int r)
1219{1219{
1220 C67_asm("STW.D *+SP[A0]", r, 0, 0); // STW r,*+SP[A0]1220 C67_asm(S, "STW.D *+SP[A0]", r, 0, 0); // STW r,*+SP[A0]
1221}1221}
1222 1222
1223void C67_STB_PTR(int r, int r2)1223void C67_STB_PTR(TCCState* S, int r, int r2)
1224{1224{
1225 C67_asm("STB.D *", r, r2, 0); // STB r, *r21225 C67_asm(S, "STB.D *", r, r2, 0); // STB r, *r2
1226}1226}
1227 1227
1228void C67_STH_PTR(int r, int r2)1228void C67_STH_PTR(TCCState* S, int r, int r2)
1229{1229{
1230 C67_asm("STH.D *", r, r2, 0); // STH r, *r21230 C67_asm(S, "STH.D *", r, r2, 0); // STH r, *r2
1231}1231}
1232 1232
1233void C67_STW_PTR(int r, int r2)1233void C67_STW_PTR(TCCState* S, int r, int r2)
1234{1234{
1235 C67_asm("STW.D *", r, r2, 0); // STW r, *r21235 C67_asm(S, "STW.D *", r, r2, 0); // STW r, *r2
1236}1236}
1237 1237
1238void C67_STW_PTR_PRE_INC(int r, int r2, int n)1238void C67_STW_PTR_PRE_INC(TCCState* S, int r, int r2, int n)
1239{1239{
1240 C67_asm("STW.D +*", r, r2, n); // STW r, *+r21240 C67_asm(S, "STW.D +*", r, r2, n); // STW r, *+r2
1241}1241}
1242 1242
1243void C67_PUSH(int r)1243void C67_PUSH(TCCState* S, int r)
1244{1244{
1245 C67_asm("STW.D SP POST DEC", r, 0, 0); // STW r,*SP--1245 C67_asm(S, "STW.D SP POST DEC", r, 0, 0); // STW r,*SP--
1246}1246}
1247 1247
1248void C67_LDW_SP_A0(int r)1248void C67_LDW_SP_A0(TCCState* S, int r)
1249{1249{
1250 C67_asm("LDW.D *+SP[A0]", r, 0, 0); // LDW *+SP[A0],r1250 C67_asm(S, "LDW.D *+SP[A0]", r, 0, 0); // LDW *+SP[A0],r
1251}1251}
1252 1252
1253void C67_LDDW_SP_A0(int r)1253void C67_LDDW_SP_A0(TCCState* S, int r)
1254{1254{
1255 C67_asm("LDDW.D *+SP[A0]", r, 0, 0); // LDDW *+SP[A0],r1255 C67_asm(S, "LDDW.D *+SP[A0]", r, 0, 0); // LDDW *+SP[A0],r
1256}1256}
1257 1257
1258void C67_LDH_SP_A0(int r)1258void C67_LDH_SP_A0(TCCState* S, int r)
1259{1259{
1260 C67_asm("LDH.D *+SP[A0]", r, 0, 0); // LDH *+SP[A0],r1260 C67_asm(S, "LDH.D *+SP[A0]", r, 0, 0); // LDH *+SP[A0],r
1261}1261}
1262 1262
1263void C67_LDB_SP_A0(int r)1263void C67_LDB_SP_A0(TCCState* S, int r)
1264{1264{
1265 C67_asm("LDB.D *+SP[A0]", r, 0, 0); // LDB *+SP[A0],r1265 C67_asm(S, "LDB.D *+SP[A0]", r, 0, 0); // LDB *+SP[A0],r
1266}1266}
1267 1267
1268void C67_LDHU_SP_A0(int r)1268void C67_LDHU_SP_A0(TCCState* S, int r)
1269{1269{
1270 C67_asm("LDHU.D *+SP[A0]", r, 0, 0); // LDHU *+SP[A0],r1270 C67_asm(S, "LDHU.D *+SP[A0]", r, 0, 0); // LDHU *+SP[A0],r
1271}1271}
1272 1272
1273void C67_LDBU_SP_A0(int r)1273void C67_LDBU_SP_A0(TCCState* S, int r)
1274{1274{
1275 C67_asm("LDBU.D *+SP[A0]", r, 0, 0); // LDBU *+SP[A0],r1275 C67_asm(S, "LDBU.D *+SP[A0]", r, 0, 0); // LDBU *+SP[A0],r
1276}1276}
1277 1277
1278void C67_LDW_PTR(int r, int r2)1278void C67_LDW_PTR(TCCState* S, int r, int r2)
1279{1279{
1280 C67_asm("LDW.D *", r, r2, 0); // LDW *r,r21280 C67_asm(S, "LDW.D *", r, r2, 0); // LDW *r,r2
1281}1281}
1282 1282
1283void C67_LDDW_PTR(int r, int r2)1283void C67_LDDW_PTR(TCCState* S, int r, int r2)
1284{1284{
1285 C67_asm("LDDW.D *", r, r2, 0); // LDDW *r,r21285 C67_asm(S, "LDDW.D *", r, r2, 0); // LDDW *r,r2
1286}1286}
1287 1287
1288void C67_LDH_PTR(int r, int r2)1288void C67_LDH_PTR(TCCState* S, int r, int r2)
1289{1289{
1290 C67_asm("LDH.D *", r, r2, 0); // LDH *r,r21290 C67_asm(S, "LDH.D *", r, r2, 0); // LDH *r,r2
1291}1291}
1292 1292
1293void C67_LDB_PTR(int r, int r2)1293void C67_LDB_PTR(TCCState* S, int r, int r2)
1294{1294{
1295 C67_asm("LDB.D *", r, r2, 0); // LDB *r,r21295 C67_asm(S, "LDB.D *", r, r2, 0); // LDB *r,r2
1296}1296}
1297 1297
1298void C67_LDHU_PTR(int r, int r2)1298void C67_LDHU_PTR(TCCState* S, int r, int r2)
1299{1299{
1300 C67_asm("LDHU.D *", r, r2, 0); // LDHU *r,r21300 C67_asm(S, "LDHU.D *", r, r2, 0); // LDHU *r,r2
1301}1301}
1302 1302
1303void C67_LDBU_PTR(int r, int r2)1303void C67_LDBU_PTR(TCCState* S, int r, int r2)
1304{1304{
1305 C67_asm("LDBU.D *", r, r2, 0); // LDBU *r,r21305 C67_asm(S, "LDBU.D *", r, r2, 0); // LDBU *r,r2
1306}1306}
1307 1307
1308void C67_LDW_PTR_PRE_INC(int r, int r2)1308void C67_LDW_PTR_PRE_INC(TCCState* S, int r, int r2)
1309{1309{
1310 C67_asm("LDW.D +*", r, r2, 0); // LDW *+r,r21310 C67_asm(S, "LDW.D +*", r, r2, 0); // LDW *+r,r2
1311}1311}
1312 1312
1313void C67_POP(int r)1313void C67_POP(TCCState* S, int r)
1314{1314{
1315 C67_asm("LDW.D SP PRE INC", r, 0, 0); // LDW *++SP,r1315 C67_asm(S, "LDW.D SP PRE INC", r, 0, 0); // LDW *++SP,r
1316}1316}
1317 1317
1318void C67_POP_DW(int r)1318void C67_POP_DW(TCCState* S, int r)
1319{1319{
1320 C67_asm("LDDW.D SP PRE INC", r, 0, 0); // LDDW *++SP,r1320 C67_asm(S, "LDDW.D SP PRE INC", r, 0, 0); // LDDW *++SP,r
1321}1321}
1322 1322
1323void C67_CMPLT(int s1, int s2, int dst)1323void C67_CMPLT(TCCState* S, int s1, int s2, int dst)
1324{1324{
1325 C67_asm("CMPLT.L1", s1, s2, dst);1325 C67_asm(S, "CMPLT.L1", s1, s2, dst);
1326}1326}
1327 1327
1328void C67_CMPGT(int s1, int s2, int dst)1328void C67_CMPGT(TCCState* S, int s1, int s2, int dst)
1329{1329{
1330 C67_asm("CMPGT.L1", s1, s2, dst);1330 C67_asm(S, "CMPGT.L1", s1, s2, dst);
1331}1331}
1332 1332
1333void C67_CMPEQ(int s1, int s2, int dst)1333void C67_CMPEQ(TCCState* S, int s1, int s2, int dst)
1334{1334{
1335 C67_asm("CMPEQ.L1", s1, s2, dst);1335 C67_asm(S, "CMPEQ.L1", s1, s2, dst);
1336}1336}
1337 1337
1338void C67_CMPLTU(int s1, int s2, int dst)1338void C67_CMPLTU(TCCState* S, int s1, int s2, int dst)
1339{1339{
1340 C67_asm("CMPLTU.L1", s1, s2, dst);1340 C67_asm(S, "CMPLTU.L1", s1, s2, dst);
1341}1341}
1342 1342
1343void C67_CMPGTU(int s1, int s2, int dst)1343void C67_CMPGTU(TCCState* S, int s1, int s2, int dst)
1344{1344{
1345 C67_asm("CMPGTU.L1", s1, s2, dst);1345 C67_asm(S, "CMPGTU.L1", s1, s2, dst);
1346}1346}
1347 1347
1348 1348
1349void C67_CMPLTSP(int s1, int s2, int dst)1349void C67_CMPLTSP(TCCState* S, int s1, int s2, int dst)
1350{1350{
1351 C67_asm("CMPLTSP.S1", s1, s2, dst);1351 C67_asm(S, "CMPLTSP.S1", s1, s2, dst);
1352}1352}
1353 1353
1354void C67_CMPGTSP(int s1, int s2, int dst)1354void C67_CMPGTSP(TCCState* S, int s1, int s2, int dst)
1355{1355{
1356 C67_asm("CMPGTSP.S1", s1, s2, dst);1356 C67_asm(S, "CMPGTSP.S1", s1, s2, dst);
1357}1357}
1358 1358
1359void C67_CMPEQSP(int s1, int s2, int dst)1359void C67_CMPEQSP(TCCState* S, int s1, int s2, int dst)
1360{1360{
1361 C67_asm("CMPEQSP.S1", s1, s2, dst);1361 C67_asm(S, "CMPEQSP.S1", s1, s2, dst);
1362}1362}
1363 1363
1364void C67_CMPLTDP(int s1, int s2, int dst)1364void C67_CMPLTDP(TCCState* S, int s1, int s2, int dst)
1365{1365{
1366 C67_asm("CMPLTDP.S1", s1, s2, dst);1366 C67_asm(S, "CMPLTDP.S1", s1, s2, dst);
1367}1367}
1368 1368
1369void C67_CMPGTDP(int s1, int s2, int dst)1369void C67_CMPGTDP(TCCState* S, int s1, int s2, int dst)
1370{1370{
1371 C67_asm("CMPGTDP.S1", s1, s2, dst);1371 C67_asm(S, "CMPGTDP.S1", s1, s2, dst);
1372}1372}
1373 1373
1374void C67_CMPEQDP(int s1, int s2, int dst)1374void C67_CMPEQDP(TCCState* S, int s1, int s2, int dst)
1375{1375{
1376 C67_asm("CMPEQDP.S1", s1, s2, dst);1376 C67_asm(S, "CMPEQDP.S1", s1, s2, dst);
1377}1377}
1378 1378
1379 1379
1380void C67_IREG_B_REG(int inv, int r1, int r2) // [!R] B r21380void C67_IREG_B_REG(TCCState* S, int inv, int r1, int r2) // [!R] B r2
1381{1381{
1382 C67_asm("B.S2", inv, r1, r2);1382 C67_asm(S, "B.S2", inv, r1, r2);
1383}1383}
1384 1384
1385 1385
1386// call with how many 32 bit words to skip1386// call with how many 32 bit words to skip
1387// (0 would branch to the branch instruction)1387// (0 would branch to the branch instruction)
1388 1388
1389void C67_B_DISP(int disp) // B +2 Branch with constant displacement1389void C67_B_DISP(TCCState* S, int disp) // B +2 Branch with constant displacement
1390{1390{
1391 // Branch point is relative to the 8 word fetch packet1391 // Branch point is relative to the 8 word fetch packet
1392 //1392 //
@@ -1395,160 +1395,160 @@ void C67_B_DISP(int disp) // B +2 Branch with constant displacement · 2 unmodified lines
1395 // so add in how many words into the fetch packet the branch is1395 // so add in how many words into the fetch packet the branch is
1396 1396
1397 1397
1398 C67_asm("B DISP", disp + ((ind & 31) >> 2), 0, 0);1398 C67_asm(S, "B DISP", disp + ((S->tccgen_ind & 31) >> 2), 0, 0);
1399}1399}
1400 1400
1401void C67_NOP(int n)1401void C67_NOP(TCCState* S, int n)
1402{1402{
1403 C67_asm("NOP", n, 0, 0);1403 C67_asm(S, "NOP", n, 0, 0);
1404}1404}
1405 1405
1406void C67_ADDK(int n, int r)1406void C67_ADDK(TCCState* S, int n, int r)
1407{1407{
1408 ALWAYS_ASSERT(abs(n) < 32767);1408 ALWAYS_ASSERT(abs(n) < 32767);
1409 1409
1410 C67_asm("ADDK", n, r, 0);1410 C67_asm(S, "ADDK", n, r, 0);
1411}1411}
1412 1412
1413void C67_ADDK_PARALLEL(int n, int r)1413void C67_ADDK_PARALLEL(TCCState* S, int n, int r)
1414{1414{
1415 ALWAYS_ASSERT(abs(n) < 32767);1415 ALWAYS_ASSERT(abs(n) < 32767);
1416 1416
1417 C67_asm("||ADDK", n, r, 0);1417 C67_asm(S, "||ADDK", n, r, 0);
1418}1418}
1419 1419
1420void C67_Adjust_ADDK(int *inst, int n)1420void C67_Adjust_ADDK(TCCState* S, int *inst, int n)
1421{1421{
1422 ALWAYS_ASSERT(abs(n) < 32767);1422 ALWAYS_ASSERT(abs(n) < 32767);
1423 1423
1424 *inst = (*inst & (~(0xffff << 7))) | ((n & 0xffff) << 7);1424 *inst = (*inst & (~(0xffff << 7))) | ((n & 0xffff) << 7);
1425}1425}
1426 1426
1427void C67_MV(int r, int v)1427void C67_MV(TCCState* S, int r, int v)
1428{1428{
1429 C67_asm("MV.L", 0, r, v);1429 C67_asm(S, "MV.L", 0, r, v);
1430}1430}
1431 1431
1432 1432
1433void C67_DPTRUNC(int r, int v)1433void C67_DPTRUNC(TCCState* S, int r, int v)
1434{1434{
1435 C67_asm("DPTRUNC.L", 0, r, v);1435 C67_asm(S, "DPTRUNC.L", 0, r, v);
1436}1436}
1437 1437
1438void C67_SPTRUNC(int r, int v)1438void C67_SPTRUNC(TCCState* S, int r, int v)
1439{1439{
1440 C67_asm("SPTRUNC.L", 0, r, v);1440 C67_asm(S, "SPTRUNC.L", 0, r, v);
1441}1441}
1442 1442
1443void C67_INTSP(int r, int v)1443void C67_INTSP(TCCState* S, int r, int v)
1444{1444{
1445 C67_asm("INTSP.L", 0, r, v);1445 C67_asm(S, "INTSP.L", 0, r, v);
1446}1446}
1447 1447
1448void C67_INTDP(int r, int v)1448void C67_INTDP(TCCState* S, int r, int v)
1449{1449{
1450 C67_asm("INTDP.L", 0, r, v);1450 C67_asm(S, "INTDP.L", 0, r, v);
1451}1451}
1452 1452
1453void C67_INTSPU(int r, int v)1453void C67_INTSPU(TCCState* S, int r, int v)
1454{1454{
1455 C67_asm("INTSPU.L", 0, r, v);1455 C67_asm(S, "INTSPU.L", 0, r, v);
1456}1456}
1457 1457
1458void C67_INTDPU(int r, int v)1458void C67_INTDPU(TCCState* S, int r, int v)
1459{1459{
1460 C67_asm("INTDPU.L", 0, r, v);1460 C67_asm(S, "INTDPU.L", 0, r, v);
1461}1461}
1462 1462
1463void C67_SPDP(int r, int v)1463void C67_SPDP(TCCState* S, int r, int v)
1464{1464{
1465 C67_asm("SPDP.L", 0, r, v);1465 C67_asm(S, "SPDP.L", 0, r, v);
1466}1466}
1467 1467
1468void C67_DPSP(int r, int v) // note regs must be on the same side1468void C67_DPSP(TCCState* S, int r, int v) // note regs must be on the same side
1469{1469{
1470 C67_asm("DPSP.L", 0, r, v);1470 C67_asm(S, "DPSP.L", 0, r, v);
1471}1471}
1472 1472
1473void C67_ADD(int r, int v)1473void C67_ADD(TCCState* S, int r, int v)
1474{1474{
1475 C67_asm("ADD.L", v, r, v);1475 C67_asm(S, "ADD.L", v, r, v);
1476}1476}
1477 1477
1478void C67_SUB(int r, int v)1478void C67_SUB(TCCState* S, int r, int v)
1479{1479{
1480 C67_asm("SUB.L", v, r, v);1480 C67_asm(S, "SUB.L", v, r, v);
1481}1481}
1482 1482
1483void C67_AND(int r, int v)1483void C67_AND(TCCState* S, int r, int v)
1484{1484{
1485 C67_asm("AND.L", v, r, v);1485 C67_asm(S, "AND.L", v, r, v);
1486}1486}
1487 1487
1488void C67_OR(int r, int v)1488void C67_OR(TCCState* S, int r, int v)
1489{1489{
1490 C67_asm("OR.L", v, r, v);1490 C67_asm(S, "OR.L", v, r, v);
1491}1491}
1492 1492
1493void C67_XOR(int r, int v)1493void C67_XOR(TCCState* S, int r, int v)
1494{1494{
1495 C67_asm("XOR.L", v, r, v);1495 C67_asm(S, "XOR.L", v, r, v);
1496}1496}
1497 1497
1498void C67_ADDSP(int r, int v)1498void C67_ADDSP(TCCState* S, int r, int v)
1499{1499{
1500 C67_asm("ADDSP.L", v, r, v);1500 C67_asm(S, "ADDSP.L", v, r, v);
1501}1501}
1502 1502
1503void C67_SUBSP(int r, int v)1503void C67_SUBSP(TCCState* S, int r, int v)
1504{1504{
1505 C67_asm("SUBSP.L", v, r, v);1505 C67_asm(S, "SUBSP.L", v, r, v);
1506}1506}
1507 1507
1508void C67_MPYSP(int r, int v)1508void C67_MPYSP(TCCState* S, int r, int v)
1509{1509{
1510 C67_asm("MPYSP.M", v, r, v);1510 C67_asm(S, "MPYSP.M", v, r, v);
1511}1511}
1512 1512
1513void C67_ADDDP(int r, int v)1513void C67_ADDDP(TCCState* S, int r, int v)
1514{1514{
1515 C67_asm("ADDDP.L", v, r, v);1515 C67_asm(S, "ADDDP.L", v, r, v);
1516}1516}
1517 1517
1518void C67_SUBDP(int r, int v)1518void C67_SUBDP(TCCState* S, int r, int v)
1519{1519{
1520 C67_asm("SUBDP.L", v, r, v);1520 C67_asm(S, "SUBDP.L", v, r, v);
1521}1521}
1522 1522
1523void C67_MPYDP(int r, int v)1523void C67_MPYDP(TCCState* S, int r, int v)
1524{1524{
1525 C67_asm("MPYDP.M", v, r, v);1525 C67_asm(S, "MPYDP.M", v, r, v);
1526}1526}
1527 1527
1528void C67_MPYI(int r, int v)1528void C67_MPYI(TCCState* S, int r, int v)
1529{1529{
1530 C67_asm("MPYI.M", v, r, v);1530 C67_asm(S, "MPYI.M", v, r, v);
1531}1531}
1532 1532
1533void C67_SHL(int r, int v)1533void C67_SHL(TCCState* S, int r, int v)
1534{1534{
1535 C67_asm("SHL.S", r, v, v);1535 C67_asm(S, "SHL.S", r, v, v);
1536}1536}
1537 1537
1538void C67_SHRU(int r, int v)1538void C67_SHRU(TCCState* S, int r, int v)
1539{1539{
1540 C67_asm("SHRU.S", r, v, v);1540 C67_asm(S, "SHRU.S", r, v, v);
1541}1541}
1542 1542
1543void C67_SHR(int r, int v)1543void C67_SHR(TCCState* S, int r, int v)
1544{1544{
1545 C67_asm("SHR.S", r, v, v);1545 C67_asm(S, "SHR.S", r, v, v);
1546}1546}
1547 1547
1548 1548
1549 1549
1550/* load 'r' from value 'sv' */1550/* load 'r' from value 'sv' */
1551void load(int r, SValue * sv)1551void load(TCCState* S, int r, SValue * sv)
1552{1552{
1553 int v, t, ft, fc, fr, size = 0, element;1553 int v, t, ft, fc, fr, size = 0, element;
1554 BOOL Unsigned = FALSE;1554 BOOL Unsigned = FALSE;
@@ -1564,10 +1564,10 @@ void load(int r, SValue * sv) · 9 unmodified lines
1564 v1.type.t = VT_INT;1564 v1.type.t = VT_INT;
1565 v1.r = VT_LOCAL | VT_LVAL;1565 v1.r = VT_LOCAL | VT_LVAL;
1566 v1.c.i = fc;1566 v1.c.i = fc;
1567 load(r, &v1);1567 load(S, r, &v1);
1568 fr = r;1568 fr = r;
1569 } else if ((ft & VT_BTYPE) == VT_LDOUBLE) {1569 } else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
1570 tcc_error("long double not supported");1570 tcc_error(S, "long double not supported");
1571 } else if ((ft & VT_TYPE) == VT_BYTE) {1571 } else if ((ft & VT_TYPE) == VT_BYTE) {
1572 size = 1;1572 size = 1;
1573 } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {1573 } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
@@ -1608,109 +1608,109 @@ void load(int r, SValue * sv) · 34 unmodified lines
1608 {1608 {
1609 if (size == 1) {1609 if (size == 1) {
1610 if (Unsigned)1610 if (Unsigned)
1611 C67_LDBU_PTR(v, r); // LDBU *v,r1611 C67_LDBU_PTR(S, v, r); // LDBU *v,r
1612 else1612 else
1613 C67_LDB_PTR(v, r); // LDB *v,r1613 C67_LDB_PTR(S, v, r); // LDB *v,r
1614 } else if (size == 2) {1614 } else if (size == 2) {
1615 if (Unsigned)1615 if (Unsigned)
1616 C67_LDHU_PTR(v, r); // LDHU *v,r1616 C67_LDHU_PTR(S, v, r); // LDHU *v,r
1617 else1617 else
1618 C67_LDH_PTR(v, r); // LDH *v,r1618 C67_LDH_PTR(S, v, r); // LDH *v,r
1619 } else if (size == 4) {1619 } else if (size == 4) {
1620 C67_LDW_PTR(v, r); // LDW *v,r1620 C67_LDW_PTR(S, v, r); // LDW *v,r
1621 } else if (size == 8) {1621 } else if (size == 8) {
1622 C67_LDDW_PTR(v, r); // LDDW *v,r1622 C67_LDDW_PTR(S, v, r); // LDDW *v,r
1623 }1623 }
1624 1624
1625 C67_NOP(4); // NOP 41625 C67_NOP(S, 4); // NOP 4
1626 return;1626 return;
1627 } else if (fr & VT_SYM) {1627 } else if (fr & VT_SYM) {
1628 greloc(cur_text_section, sv->sym, ind, R_C60LO16); // rem the inst need to be patched1628 greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched
1629 greloc(cur_text_section, sv->sym, ind + 4, R_C60HI16);1629 greloc(S, cur_text_section, sv->sym, S->tccgen_ind + 4, R_C60HI16);
1630 1630
1631 1631
1632 C67_MVKL(C67_A0, fc); //r=reg to load, constant1632 C67_MVKL(S, C67_A0, fc); //r=reg to load, constant
1633 C67_MVKH(C67_A0, fc); //r=reg to load, constant1633 C67_MVKH(S, C67_A0, fc); //r=reg to load, constant
1634 1634
1635 1635
1636 if (size == 1) {1636 if (size == 1) {
1637 if (Unsigned)1637 if (Unsigned)
1638 C67_LDBU_PTR(C67_A0, r); // LDBU *A0,r1638 C67_LDBU_PTR(S, C67_A0, r); // LDBU *A0,r
1639 else1639 else
1640 C67_LDB_PTR(C67_A0, r); // LDB *A0,r1640 C67_LDB_PTR(S, C67_A0, r); // LDB *A0,r
1641 } else if (size == 2) {1641 } else if (size == 2) {
1642 if (Unsigned)1642 if (Unsigned)
1643 C67_LDHU_PTR(C67_A0, r); // LDHU *A0,r1643 C67_LDHU_PTR(S, C67_A0, r); // LDHU *A0,r
1644 else1644 else
1645 C67_LDH_PTR(C67_A0, r); // LDH *A0,r1645 C67_LDH_PTR(S, C67_A0, r); // LDH *A0,r
1646 } else if (size == 4) {1646 } else if (size == 4) {
1647 C67_LDW_PTR(C67_A0, r); // LDW *A0,r1647 C67_LDW_PTR(S, C67_A0, r); // LDW *A0,r
1648 } else if (size == 8) {1648 } else if (size == 8) {
1649 C67_LDDW_PTR(C67_A0, r); // LDDW *A0,r1649 C67_LDDW_PTR(S, C67_A0, r); // LDDW *A0,r
1650 }1650 }
1651 1651
1652 C67_NOP(4); // NOP 41652 C67_NOP(S, 4); // NOP 4
1653 return;1653 return;
1654 } else {1654 } else {
1655 element = size;1655 element = size;
1656 1656
1657 // divide offset in bytes to create element index1657 // divide offset in bytes to create element index
1658 C67_MVKL(C67_A0, (fc / element) + 8 / element); //r=reg to load, constant1658 C67_MVKL(S, C67_A0, (fc / element) + 8 / element); //r=reg to load, constant
1659 C67_MVKH(C67_A0, (fc / element) + 8 / element); //r=reg to load, constant1659 C67_MVKH(S, C67_A0, (fc / element) + 8 / element); //r=reg to load, constant
1660 1660
1661 if (size == 1) {1661 if (size == 1) {
1662 if (Unsigned)1662 if (Unsigned)
1663 C67_LDBU_SP_A0(r); // LDBU r, SP[A0]1663 C67_LDBU_SP_A0(S, r); // LDBU r, SP[A0]
1664 else1664 else
1665 C67_LDB_SP_A0(r); // LDB r, SP[A0]1665 C67_LDB_SP_A0(S, r); // LDB r, SP[A0]
1666 } else if (size == 2) {1666 } else if (size == 2) {
1667 if (Unsigned)1667 if (Unsigned)
1668 C67_LDHU_SP_A0(r); // LDHU r, SP[A0]1668 C67_LDHU_SP_A0(S, r); // LDHU r, SP[A0]
1669 else1669 else
1670 C67_LDH_SP_A0(r); // LDH r, SP[A0]1670 C67_LDH_SP_A0(S, r); // LDH r, SP[A0]
1671 } else if (size == 4) {1671 } else if (size == 4) {
1672 C67_LDW_SP_A0(r); // LDW r, SP[A0]1672 C67_LDW_SP_A0(S, r); // LDW r, SP[A0]
1673 } else if (size == 8) {1673 } else if (size == 8) {
1674 C67_LDDW_SP_A0(r); // LDDW r, SP[A0]1674 C67_LDDW_SP_A0(S, r); // LDDW r, SP[A0]
1675 }1675 }
1676 1676
1677 1677
1678 C67_NOP(4); // NOP 41678 C67_NOP(S, 4); // NOP 4
1679 return;1679 return;
1680 }1680 }
1681 } else {1681 } else {
1682 if (v == VT_CONST) {1682 if (v == VT_CONST) {
1683 if (fr & VT_SYM) {1683 if (fr & VT_SYM) {
1684 greloc(cur_text_section, sv->sym, ind, R_C60LO16); // rem the inst need to be patched1684 greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched
1685 greloc(cur_text_section, sv->sym, ind + 4, R_C60HI16);1685 greloc(S, cur_text_section, sv->sym, S->tccgen_ind + 4, R_C60HI16);
1686 }1686 }
1687 C67_MVKL(r, fc); //r=reg to load, constant1687 C67_MVKL(S, r, fc); //r=reg to load, constant
1688 C67_MVKH(r, fc); //r=reg to load, constant1688 C67_MVKH(S, r, fc); //r=reg to load, constant
1689 } else if (v == VT_LOCAL) {1689 } else if (v == VT_LOCAL) {
1690 C67_MVKL(r, fc + 8); //r=reg to load, constant C67 stack points to next free1690 C67_MVKL(S, r, fc + 8); //r=reg to load, constant C67 stack points to next free
1691 C67_MVKH(r, fc + 8); //r=reg to load, constant1691 C67_MVKH(S, r, fc + 8); //r=reg to load, constant
1692 C67_ADD(C67_FP, r); // MV v,r v -> r1692 C67_ADD(S, C67_FP, r); // MV v,r v -> r
1693 } else if (v == VT_CMP) {1693 } else if (v == VT_CMP) {
1694 C67_MV(C67_compare_reg, r); // MV v,r v -> r1694 C67_MV(S, C67_compare_reg, r); // MV v,r v -> r
1695 } else if (v == VT_JMP || v == VT_JMPI) {1695 } else if (v == VT_JMP || v == VT_JMPI) {
1696 t = v & 1;1696 t = v & 1;
1697 C67_B_DISP(4); // Branch with constant displacement, skip over this branch, load, nop, load1697 C67_B_DISP(S, 4); // Branch with constant displacement, skip over this branch, load, nop, load
1698 C67_MVKL(r, t); // r=reg to load, 0 or 1 (do this while branching)1698 C67_MVKL(S, r, t); // r=reg to load, 0 or 1 (do this while branching)
1699 C67_NOP(4); // NOP 41699 C67_NOP(S, 4); // NOP 4
1700 gsym(fc); // modifies other branches to branch here1700 gsym(S, fc); // modifies other branches to branch here
1701 C67_MVKL(r, t ^ 1); // r=reg to load, 0 or 11701 C67_MVKL(S, r, t ^ 1); // r=reg to load, 0 or 1
1702 } else if (v != r) {1702 } else if (v != r) {
1703 C67_MV(v, r); // MV v,r v -> r1703 C67_MV(S, v, r); // MV v,r v -> r
1704 1704
1705 if ((ft & VT_BTYPE) == VT_DOUBLE)1705 if ((ft & VT_BTYPE) == VT_DOUBLE)
1706 C67_MV(v + 1, r + 1); // MV v,r v -> r1706 C67_MV(S, v + 1, r + 1); // MV v,r v -> r
1707 }1707 }
1708 }1708 }
1709}1709}
1710 1710
1711 1711
1712/* store register 'r' in lvalue 'v' */1712/* store register 'r' in lvalue 'v' */
1713void store(int r, SValue * v)1713void store(TCCState* S, int r, SValue * v)
1714{1714{
1715 int fr, bt, ft, fc, size, t, element;1715 int fr, bt, ft, fc, size, t, element;
1716 1716
@@ -1721,7 +1721,7 @@ void store(int r, SValue * v) · 4 unmodified lines
1721 /* XXX: incorrect if float reg to reg */1721 /* XXX: incorrect if float reg to reg */
1722 1722
1723 if (bt == VT_LDOUBLE) {1723 if (bt == VT_LDOUBLE) {
1724 tcc_error("long double not supported");1724 tcc_error(S, "long double not supported");
1725 } else {1725 } else {
1726 if (bt == VT_SHORT)1726 if (bt == VT_SHORT)
1727 size = 2;1727 size = 2;
@@ -1736,21 +1736,21 @@ void store(int r, SValue * v) · 8 unmodified lines
1736 /* constant memory reference */1736 /* constant memory reference */
1737 1737
1738 if (v->r & VT_SYM) {1738 if (v->r & VT_SYM) {
1739 greloc(cur_text_section, v->sym, ind, R_C60LO16); // rem the inst need to be patched1739 greloc(S, cur_text_section, v->sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched
1740 greloc(cur_text_section, v->sym, ind + 4, R_C60HI16);1740 greloc(S, cur_text_section, v->sym, S->tccgen_ind + 4, R_C60HI16);
1741 }1741 }
1742 C67_MVKL(C67_A0, fc); //r=reg to load, constant1742 C67_MVKL(S, C67_A0, fc); //r=reg to load, constant
1743 C67_MVKH(C67_A0, fc); //r=reg to load, constant1743 C67_MVKH(S, C67_A0, fc); //r=reg to load, constant
1744 1744
1745 if (size == 1)1745 if (size == 1)
1746 C67_STB_PTR(r, C67_A0); // STB r, *A01746 C67_STB_PTR(S, r, C67_A0); // STB r, *A0
1747 else if (size == 2)1747 else if (size == 2)
1748 C67_STH_PTR(r, C67_A0); // STH r, *A01748 C67_STH_PTR(S, r, C67_A0); // STH r, *A0
1749 else if (size == 4 || size == 8)1749 else if (size == 4 || size == 8)
1750 C67_STW_PTR(r, C67_A0); // STW r, *A01750 C67_STW_PTR(S, r, C67_A0); // STW r, *A0
1751 1751
1752 if (size == 8)1752 if (size == 8)
1753 C67_STW_PTR_PRE_INC(r + 1, C67_A0, 1); // STW r, *+A0[1]1753 C67_STW_PTR_PRE_INC(S, r + 1, C67_A0, 1); // STW r, *+A0[1]
1754 } else if ((v->r & VT_VALMASK) == VT_LOCAL) {1754 } else if ((v->r & VT_VALMASK) == VT_LOCAL) {
1755 // check case of storing to passed argument that1755 // check case of storing to passed argument that
1756 // tcc thinks is on the stack but for C67 is1756 // tcc thinks is on the stack but for C67 is
@@ -1781,68 +1781,68 @@ void store(int r, SValue * v) · 24 unmodified lines
1781 element = size;1781 element = size;
1782 1782
1783 // divide offset in bytes to create word index1783 // divide offset in bytes to create word index
1784 C67_MVKL(C67_A0, (fc / element) + 8 / element); //r=reg to load, constant1784 C67_MVKL(S, C67_A0, (fc / element) + 8 / element); //r=reg to load, constant
1785 C67_MVKH(C67_A0, (fc / element) + 8 / element); //r=reg to load, constant1785 C67_MVKH(S, C67_A0, (fc / element) + 8 / element); //r=reg to load, constant
1786 1786
1787 1787
1788 1788
1789 if (size == 1)1789 if (size == 1)
1790 C67_STB_SP_A0(r); // STB r, SP[A0]1790 C67_STB_SP_A0(S, r); // STB r, SP[A0]
1791 else if (size == 2)1791 else if (size == 2)
1792 C67_STH_SP_A0(r); // STH r, SP[A0]1792 C67_STH_SP_A0(S, r); // STH r, SP[A0]
1793 else if (size == 4 || size == 8)1793 else if (size == 4 || size == 8)
1794 C67_STW_SP_A0(r); // STW r, SP[A0]1794 C67_STW_SP_A0(S, r); // STW r, SP[A0]
1795 1795
1796 if (size == 8) {1796 if (size == 8) {
1797 C67_ADDK(1, C67_A0); // ADDK 1,A01797 C67_ADDK(S, 1, C67_A0); // ADDK 1,A0
1798 C67_STW_SP_A0(r + 1); // STW r, SP[A0]1798 C67_STW_SP_A0(S, r + 1); // STW r, SP[A0]
1799 }1799 }
1800 } else {1800 } else {
1801 if (size == 1)1801 if (size == 1)
1802 C67_STB_PTR(r, fr); // STB r, *fr1802 C67_STB_PTR(S, r, fr); // STB r, *fr
1803 else if (size == 2)1803 else if (size == 2)
1804 C67_STH_PTR(r, fr); // STH r, *fr1804 C67_STH_PTR(S, r, fr); // STH r, *fr
1805 else if (size == 4 || size == 8)1805 else if (size == 4 || size == 8)
1806 C67_STW_PTR(r, fr); // STW r, *fr1806 C67_STW_PTR(S, r, fr); // STW r, *fr
1807 1807
1808 if (size == 8) {1808 if (size == 8) {
1809 C67_STW_PTR_PRE_INC(r + 1, fr, 1); // STW r, *+fr[1]1809 C67_STW_PTR_PRE_INC(S, r + 1, fr, 1); // STW r, *+fr[1]
1810 }1810 }
1811 }1811 }
1812 }1812 }
1813}1813}
1814 1814
1815/* 'is_jmp' is '1' if it is a jump */1815/* 'is_jmp' is '1' if it is a jump */
1816static void gcall_or_jmp(int is_jmp)1816static void gcall_or_jmp(TCCState* S, int is_jmp)
1817{1817{
1818 int r;1818 int r;
1819 Sym *sym;1819 Sym *sym;
1820 1820
1821 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {1821 if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
1822 /* constant case */1822 /* constant case */
1823 if (vtop->r & VT_SYM) {1823 if (S->tccgen_vtop->r & VT_SYM) {
1824 /* relocation case */1824 /* relocation case */
1825 1825
1826 // get add into A0, then start the jump B31826 // get add into A0, then start the jump B3
1827 1827
1828 greloc(cur_text_section, vtop->sym, ind, R_C60LO16); // rem the inst need to be patched1828 greloc(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched
1829 greloc(cur_text_section, vtop->sym, ind + 4, R_C60HI16);1829 greloc(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind + 4, R_C60HI16);
1830 1830
1831 C67_MVKL(C67_A0, 0); //r=reg to load, constant1831 C67_MVKL(S, C67_A0, 0); //r=reg to load, constant
1832 C67_MVKH(C67_A0, 0); //r=reg to load, constant1832 C67_MVKH(S, C67_A0, 0); //r=reg to load, constant
1833 C67_IREG_B_REG(0, C67_CREG_ZERO, C67_A0); // B.S2x A01833 C67_IREG_B_REG(S, 0, C67_CREG_ZERO, C67_A0); // B.S2x A0
1834 1834
1835 if (is_jmp) {1835 if (is_jmp) {
1836 C67_NOP(5); // simple jump, just put NOP1836 C67_NOP(S, 5); // simple jump, just put NOP
1837 } else {1837 } else {
1838 // Call, must load return address into B3 during delay slots1838 // Call, must load return address into B3 during delay slots
1839 1839
1840 sym = get_sym_ref(&char_pointer_type, cur_text_section, ind + 12, 0); // symbol for return address1840 sym = get_sym_ref(S, &S->tccgen_char_pointer_type, cur_text_section, S->tccgen_ind + 12, 0); // symbol for return address
1841 greloc(cur_text_section, sym, ind, R_C60LO16); // rem the inst need to be patched1841 greloc(S, cur_text_section, sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched
1842 greloc(cur_text_section, sym, ind + 4, R_C60HI16);1842 greloc(S, cur_text_section, sym, S->tccgen_ind + 4, R_C60HI16);
1843 C67_MVKL(C67_B3, 0); //r=reg to load, constant1843 C67_MVKL(S, C67_B3, 0); //r=reg to load, constant
1844 C67_MVKH(C67_B3, 0); //r=reg to load, constant1844 C67_MVKH(S, C67_B3, 0); //r=reg to load, constant
1845 C67_NOP(3); // put remaining NOPs1845 C67_NOP(S, 3); // put remaining NOPs
1846 }1846 }
1847 } else {1847 } else {
1848 /* put an empty PC32 relocation */1848 /* put an empty PC32 relocation */
@@ -1850,20 +1850,20 @@ static void gcall_or_jmp(int is_jmp) · 1 unmodified line
1850 }1850 }
1851 } else {1851 } else {
1852 /* otherwise, indirect call */1852 /* otherwise, indirect call */
1853 r = gv(RC_INT);1853 r = gv(S, RC_INT);
1854 C67_IREG_B_REG(0, C67_CREG_ZERO, r); // B.S2x r1854 C67_IREG_B_REG(S, 0, C67_CREG_ZERO, r); // B.S2x r
1855 1855
1856 if (is_jmp) {1856 if (is_jmp) {
1857 C67_NOP(5); // simple jump, just put NOP1857 C67_NOP(S, 5); // simple jump, just put NOP
1858 } else {1858 } else {
1859 // Call, must load return address into B3 during delay slots1859 // Call, must load return address into B3 during delay slots
1860 1860
1861 sym = get_sym_ref(&char_pointer_type, cur_text_section, ind + 12, 0); // symbol for return address1861 sym = get_sym_ref(S, &S->tccgen_char_pointer_type, cur_text_section, S->tccgen_ind + 12, 0); // symbol for return address
1862 greloc(cur_text_section, sym, ind, R_C60LO16); // rem the inst need to be patched1862 greloc(S, cur_text_section, sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched
1863 greloc(cur_text_section, sym, ind + 4, R_C60HI16);1863 greloc(S, cur_text_section, sym, S->tccgen_ind + 4, R_C60HI16);
1864 C67_MVKL(C67_B3, 0); //r=reg to load, constant1864 C67_MVKL(S, C67_B3, 0); //r=reg to load, constant
1865 C67_MVKH(C67_B3, 0); //r=reg to load, constant1865 C67_MVKH(S, C67_B3, 0); //r=reg to load, constant
1866 C67_NOP(3); // put remaining NOPs1866 C67_NOP(S, 3); // put remaining NOPs
1867 }1867 }
1868 }1868 }
1869}1869}
@@ -1877,29 +1877,29 @@ ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int · 7 unmodified lines
1877 1877
1878/* generate function call with address in (vtop->t, vtop->c) and free function1878/* generate function call with address in (vtop->t, vtop->c) and free function
1879 context. Stack entry is popped */1879 context. Stack entry is popped */
1880void gfunc_call(int nb_args)1880void gfunc_call(TCCState* S, int nb_args)
1881{1881{
1882 int i, r, size = 0;1882 int i, r, size = 0;
1883 int args_sizes[NoCallArgsPassedOnStack];1883 int args_sizes[NoCallArgsPassedOnStack];
1884 1884
1885 if (nb_args > NoCallArgsPassedOnStack) {1885 if (nb_args > NoCallArgsPassedOnStack) {
1886 tcc_error("more than 10 function params not currently supported");1886 tcc_error(S, "more than 10 function params not currently supported");
1887 // handle more than 10, put some on the stack1887 // handle more than 10, put some on the stack
1888 }1888 }
1889 1889
1890 for (i = 0; i < nb_args; i++) {1890 for (i = 0; i < nb_args; i++) {
1891 if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {1891 if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_STRUCT) {
1892 ALWAYS_ASSERT(FALSE);1892 ALWAYS_ASSERT(FALSE);
1893 } else {1893 } else {
1894 /* simple type (currently always same size) */1894 /* simple type (currently always same size) */
1895 /* XXX: implicit cast ? */1895 /* XXX: implicit cast ? */
1896 1896
1897 1897
1898 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {1898 if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG) {
1899 tcc_error("long long not supported");1899 tcc_error(S, "long long not supported");
1900 } else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {1900 } else if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
1901 tcc_error("long double not supported");1901 tcc_error(S, "long double not supported");
1902 } else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) {1902 } else if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_DOUBLE) {
1903 size = 8;1903 size = 8;
1904 } else {1904 } else {
1905 size = 4;1905 size = 4;
@@ -1907,19 +1907,19 @@ void gfunc_call(int nb_args) · 1 unmodified line
1907 1907
1908 // put the parameter into the corresponding reg (pair)1908 // put the parameter into the corresponding reg (pair)
1909 1909
1910 r = gv(RC_C67_A4 << (2 * i));1910 r = gv(S, RC_C67_A4 << (2 * i));
1911 1911
1912 // must put on stack because with 1 pass compiler , no way to tell1912 // must put on stack because with 1 pass compiler , no way to tell
1913 // if an up coming nested call might overwrite these regs1913 // if an up coming nested call might overwrite these regs
1914 1914
1915 C67_PUSH(r);1915 C67_PUSH(S, r);
1916 1916
1917 if (size == 8) {1917 if (size == 8) {
1918 C67_STW_PTR_PRE_INC(r + 1, C67_SP, 3); // STW r, *+SP[3] (go back and put the other)1918 C67_STW_PTR_PRE_INC(S, r + 1, C67_SP, 3); // STW r, *+SP[3] (go back and put the other)
1919 }1919 }
1920 args_sizes[i] = size;1920 args_sizes[i] = size;
1921 }1921 }
1922 vtop--;1922 S->tccgen_vtop--;
1923 }1923 }
1924 // POP all the params on the stack into registers for the1924 // POP all the params on the stack into registers for the
1925 // immediate call (in reverse order)1925 // immediate call (in reverse order)
@@ -1927,12 +1927,12 @@ void gfunc_call(int nb_args) · 1 unmodified line
1927 for (i = nb_args - 1; i >= 0; i--) {1927 for (i = nb_args - 1; i >= 0; i--) {
1928 1928
1929 if (args_sizes[i] == 8)1929 if (args_sizes[i] == 8)
1930 C67_POP_DW(TREG_C67_A4 + i * 2);1930 C67_POP_DW(S, TREG_C67_A4 + i * 2);
1931 else1931 else
1932 C67_POP(TREG_C67_A4 + i * 2);1932 C67_POP(S, TREG_C67_A4 + i * 2);
1933 }1933 }
1934 gcall_or_jmp(0);1934 gcall_or_jmp(S, 0);
1935 vtop--;1935 S->tccgen_vtop--;
1936}1936}
1937 1937
1938 1938
@@ -1946,7 +1946,7 @@ void gfunc_call(int nb_args) · 7 unmodified lines
1946// parameters are loaded and restored upon return (or if/when needed).1946// parameters are loaded and restored upon return (or if/when needed).
1947 1947
1948/* generate function prolog of type 't' */1948/* generate function prolog of type 't' */
1949void gfunc_prolog(Sym *func_sym)1949void gfunc_prolog(TCCState* S, Sym *func_sym)
1950{1950{
1951 CType *func_type = &func_sym->type;1951 CType *func_type = &func_sym->type;
1952 int addr, align, size, func_call, i;1952 int addr, align, size, func_call, i;
@@ -1958,8 +1958,8 @@ void gfunc_prolog(Sym *func_sym) · 5 unmodified lines
1958 addr = 8;1958 addr = 8;
1959 /* if the function returns a structure, then add an1959 /* if the function returns a structure, then add an
1960 implicit pointer parameter */1960 implicit pointer parameter */
1961 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {1961 if ((S->tccgen_func_vt.t & VT_BTYPE) == VT_STRUCT) {
1962 func_vc = addr;1962 S->tccgen_func_vc = addr;
1963 addr += 4;1963 addr += 4;
1964 }1964 }
1965 1965
@@ -1968,7 +1968,7 @@ void gfunc_prolog(Sym *func_sym) · 2 unmodified lines
1968 /* define parameters */1968 /* define parameters */
1969 while ((sym = sym->next) != NULL) {1969 while ((sym = sym->next) != NULL) {
1970 type = &sym->type;1970 type = &sym->type;
1971 sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL, addr);1971 sym_push(S, sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL, addr);
1972 size = type_size(type, &align);1972 size = type_size(type, &align);
1973 size = (size + 3) & ~3;1973 size = (size + 3) & ~3;
1974 1974
@@ -1992,76 +1992,76 @@ void gfunc_prolog(Sym *func_sym) · 17 unmodified lines
1992 if (func_call == FUNC_STDCALL)1992 if (func_call == FUNC_STDCALL)
1993 func_ret_sub = addr - 8;1993 func_ret_sub = addr - 8;
1994 1994
1995 C67_MV(C67_FP, C67_A0); // move FP -> A01995 C67_MV(S, C67_FP, C67_A0); // move FP -> A0
1996 C67_MV(C67_SP, C67_FP); // move SP -> FP1996 C67_MV(S, C67_SP, C67_FP); // move SP -> FP
1997 1997
1998 // place all the args passed in regs onto the stack1998 // place all the args passed in regs onto the stack
1999 1999
2000 loc = 0;2000 S->tccgen_loc = 0;
2001 for (i = 0; i < NoOfCurFuncArgs; i++) {2001 for (i = 0; i < NoOfCurFuncArgs; i++) {
2002 2002
2003 ParamLocOnStack[i] = loc; // remember where the param is2003 ParamLocOnStack[i] = S->tccgen_loc; // remember where the param is
2004 loc += -8;2004 S->tccgen_loc += -8;
2005 2005
2006 C67_PUSH(TREG_C67_A4 + i * 2);2006 C67_PUSH(S, TREG_C67_A4 + i * 2);
2007 2007
2008 if (TranslateStackToReg[i] == 8) {2008 if (TranslateStackToReg[i] == 8) {
2009 C67_STW_PTR_PRE_INC(TREG_C67_A4 + i * 2 + 1, C67_SP, 3); // STW r, *+SP[1] (go back and put the other)2009 C67_STW_PTR_PRE_INC(S, TREG_C67_A4 + i * 2 + 1, C67_SP, 3); // STW r, *+SP[1] (go back and put the other)
2010 }2010 }
2011 }2011 }
2012 2012
2013 TotalBytesPushedOnStack = -loc;2013 TotalBytesPushedOnStack = -S->tccgen_loc;
2014 2014
2015 func_sub_sp_offset = ind; // remember where we put the stack instruction 2015 func_sub_sp_offset = S->tccgen_ind; // remember where we put the stack instruction
2016 C67_ADDK(0, C67_SP); // ADDK.L2 loc,SP (just put zero temporarily)2016 C67_ADDK(S, 0, C67_SP); // ADDK.L2 loc,SP (just put zero temporarily)
2017 2017
2018 C67_PUSH(C67_A0);2018 C67_PUSH(S, C67_A0);
2019 C67_PUSH(C67_B3);2019 C67_PUSH(S, C67_B3);
2020}2020}
2021 2021
2022/* generate function epilog */2022/* generate function epilog */
2023void gfunc_epilog(void)2023void gfunc_epilog(TCCState* S)
2024{2024{
2025 {2025 {
2026 int local = (-loc + 7) & -8; // stack must stay aligned to 8 bytes for LDDW instr2026 int local = (-S->tccgen_loc + 7) & -8; // stack must stay aligned to 8 bytes for LDDW instr
2027 C67_POP(C67_B3);2027 C67_POP(S, C67_B3);
2028 C67_NOP(4); // NOP wait for load2028 C67_NOP(S, 4); // NOP wait for load
2029 C67_IREG_B_REG(0, C67_CREG_ZERO, C67_B3); // B.S2 B32029 C67_IREG_B_REG(S, 0, C67_CREG_ZERO, C67_B3); // B.S2 B3
2030 C67_POP(C67_FP);2030 C67_POP(S, C67_FP);
2031 C67_ADDK(local, C67_SP); // ADDK.L2 loc,SP 2031 C67_ADDK(S, local, C67_SP); // ADDK.L2 loc,SP
2032 C67_Adjust_ADDK((int *) (cur_text_section->data +2032 C67_Adjust_ADDK(S, (int *) (cur_text_section->data +
2033 func_sub_sp_offset),2033 func_sub_sp_offset),
2034 -local + TotalBytesPushedOnStack);2034 -local + TotalBytesPushedOnStack);
2035 C67_NOP(3); // NOP 2035 C67_NOP(S, 3); // NOP
2036 }2036 }
2037}2037}
2038 2038
2039ST_FUNC void gen_fill_nops(int bytes)2039ST_FUNC void gen_fill_nops(TCCState* S, int bytes)
2040{2040{
2041 if ((bytes & 3))2041 if ((bytes & 3))
2042 tcc_error("alignment of code section not multiple of 4");2042 tcc_error(S, "alignment of code section not multiple of 4");
2043 while (bytes > 0) {2043 while (bytes > 0) {
2044 C67_NOP(4);2044 C67_NOP(S, 4);
2045 bytes -= 4;2045 bytes -= 4;
2046 }2046 }
2047}2047}
2048 2048
2049/* generate a jump to a label */2049/* generate a jump to a label */
2050int gjmp(int t)2050int gjmp(TCCState* S, int t)
2051{2051{
2052 int ind1 = ind;2052 int ind1 = S->tccgen_ind;
2053 if (nocode_wanted)2053 if (S->tccgen_nocode_wanted)
2054 return t;2054 return t;
2055 2055
2056 C67_MVKL(C67_A0, t); //r=reg to load, constant2056 C67_MVKL(S, C67_A0, t); //r=reg to load, constant
2057 C67_MVKH(C67_A0, t); //r=reg to load, constant2057 C67_MVKH(S, C67_A0, t); //r=reg to load, constant
2058 C67_IREG_B_REG(0, C67_CREG_ZERO, C67_A0); // [!R] B.S2x A02058 C67_IREG_B_REG(S, 0, C67_CREG_ZERO, C67_A0); // [!R] B.S2x A0
2059 C67_NOP(5);2059 C67_NOP(S, 5);
2060 return ind1;2060 return ind1;
2061}2061}
2062 2062
2063/* generate a jump to a fixed address */2063/* generate a jump to a fixed address */
2064void gjmp_addr(int a)2064void gjmp_addr(TCCState* S, int a)
2065{2065{
2066 Sym *sym;2066 Sym *sym;
2067 // I guess this routine is used for relative short2067 // I guess this routine is used for relative short
@@ -2070,42 +2070,42 @@ void gjmp_addr(int a) · 2 unmodified lines
2070 2070
2071 // define a label that will be relocated2071 // define a label that will be relocated
2072 2072
2073 sym = get_sym_ref(&char_pointer_type, cur_text_section, a, 0);2073 sym = get_sym_ref(S, &S->tccgen_char_pointer_type, cur_text_section, a, 0);
2074 greloc(cur_text_section, sym, ind, R_C60LO16);2074 greloc(S, cur_text_section, sym, S->tccgen_ind, R_C60LO16);
2075 greloc(cur_text_section, sym, ind + 4, R_C60HI16);2075 greloc(S, cur_text_section, sym, S->tccgen_ind + 4, R_C60HI16);
2076 2076
2077 gjmp(0); // place a zero there later the symbol will be added to it2077 gjmp(S, 0); // place a zero there later the symbol will be added to it
2078}2078}
2079 2079
2080/* generate a test. set 'inv' to invert test. Stack entry is popped */2080/* generate a test. set 'inv' to invert test. Stack entry is popped */
2081ST_FUNC int gjmp_cond(int op, int t)2081ST_FUNC int gjmp_cond(TCCState* S, int op, int t)
2082{2082{
2083 int ind1;2083 int ind1;
2084 int inv = op & 1;2084 int inv = op & 1;
2085 if (nocode_wanted)2085 if (S->tccgen_nocode_wanted)
2086 return t;2086 return t;
2087 2087
2088 /* fast case : can jump directly since flags are set */2088 /* fast case : can jump directly since flags are set */
2089 // C67 uses B2 sort of as flags register2089 // C67 uses B2 sort of as flags register
2090 ind1 = ind;2090 ind1 = S->tccgen_ind;
2091 C67_MVKL(C67_A0, t); //r=reg to load, constant2091 C67_MVKL(S, C67_A0, t); //r=reg to load, constant
2092 C67_MVKH(C67_A0, t); //r=reg to load, constant2092 C67_MVKH(S, C67_A0, t); //r=reg to load, constant
2093 2093
2094 if (C67_compare_reg != TREG_EAX && // check if not already in a conditional test reg2094 if (C67_compare_reg != TREG_EAX && // check if not already in a conditional test reg
2095 C67_compare_reg != TREG_EDX &&2095 C67_compare_reg != TREG_EDX &&
2096 C67_compare_reg != TREG_ST0 && C67_compare_reg != C67_B2) {2096 C67_compare_reg != TREG_ST0 && C67_compare_reg != C67_B2) {
2097 C67_MV(C67_compare_reg, C67_B2);2097 C67_MV(S, C67_compare_reg, C67_B2);
2098 C67_compare_reg = C67_B2;2098 C67_compare_reg = C67_B2;
2099 }2099 }
2100 2100
2101 C67_IREG_B_REG(C67_invert_test ^ inv, C67_compare_reg, C67_A0); // [!R] B.S2x A02101 C67_IREG_B_REG(S, C67_invert_test ^ inv, C67_compare_reg, C67_A0); // [!R] B.S2x A0
2102 C67_NOP(5);2102 C67_NOP(S, 5);
2103 t = ind1; //return where we need to patch2103 t = ind1; //return where we need to patch
2104 2104
2105 return t;2105 return t;
2106}2106}
2107 2107
2108ST_FUNC int gjmp_append(int n0, int t)2108ST_FUNC int gjmp_append(TCCState* S, int n0, int t)
2109{2109{
2110 if (n0) {2110 if (n0) {
2111 int n = n0, *p;2111 int n = n0, *p;
@@ -2129,7 +2129,7 @@ ST_FUNC int gjmp_append(int n0, int t) · 17 unmodified lines
2129}2129}
2130 2130
2131/* generate an integer binary operation */2131/* generate an integer binary operation */
2132void gen_opi(int op)2132void gen_opi(TCCState* S, int op)
2133{2133{
2134 int r, fr, opc, t;2134 int r, fr, opc, t;
2135 2135
@@ -2146,62 +2146,62 @@ void gen_opi(int op) · 10 unmodified lines
2146 2146
2147 2147
2148 if (op >= TOK_ULT && op <= TOK_GT)2148 if (op >= TOK_ULT && op <= TOK_GT)
2149 gv2(RC_INT_BSIDE, RC_INT); // make sure r (src1) is on the B Side of CPU2149 gv2(S, RC_INT_BSIDE, RC_INT); // make sure r (src1) is on the B Side of CPU
2150 else2150 else
2151 gv2(RC_INT, RC_INT);2151 gv2(S, RC_INT, RC_INT);
2152 2152
2153 r = vtop[-1].r;2153 r = S->tccgen_vtop[-1].r;
2154 fr = vtop[0].r;2154 fr = S->tccgen_vtop[0].r;
2155 2155
2156 C67_compare_reg = C67_B2;2156 C67_compare_reg = C67_B2;
2157 2157
2158 2158
2159 if (op == TOK_LT) {2159 if (op == TOK_LT) {
2160 C67_CMPLT(r, fr, C67_B2);2160 C67_CMPLT(S, r, fr, C67_B2);
2161 C67_invert_test = FALSE;2161 C67_invert_test = FALSE;
2162 } else if (op == TOK_GE) {2162 } else if (op == TOK_GE) {
2163 C67_CMPLT(r, fr, C67_B2);2163 C67_CMPLT(S, r, fr, C67_B2);
2164 C67_invert_test = TRUE;2164 C67_invert_test = TRUE;
2165 } else if (op == TOK_GT) {2165 } else if (op == TOK_GT) {
2166 C67_CMPGT(r, fr, C67_B2);2166 C67_CMPGT(S, r, fr, C67_B2);
2167 C67_invert_test = FALSE;2167 C67_invert_test = FALSE;
2168 } else if (op == TOK_LE) {2168 } else if (op == TOK_LE) {
2169 C67_CMPGT(r, fr, C67_B2);2169 C67_CMPGT(S, r, fr, C67_B2);
2170 C67_invert_test = TRUE;2170 C67_invert_test = TRUE;
2171 } else if (op == TOK_EQ) {2171 } else if (op == TOK_EQ) {
2172 C67_CMPEQ(r, fr, C67_B2);2172 C67_CMPEQ(S, r, fr, C67_B2);
2173 C67_invert_test = FALSE;2173 C67_invert_test = FALSE;
2174 } else if (op == TOK_NE) {2174 } else if (op == TOK_NE) {
2175 C67_CMPEQ(r, fr, C67_B2);2175 C67_CMPEQ(S, r, fr, C67_B2);
2176 C67_invert_test = TRUE;2176 C67_invert_test = TRUE;
2177 } else if (op == TOK_ULT) {2177 } else if (op == TOK_ULT) {
2178 C67_CMPLTU(r, fr, C67_B2);2178 C67_CMPLTU(S, r, fr, C67_B2);
2179 C67_invert_test = FALSE;2179 C67_invert_test = FALSE;
2180 } else if (op == TOK_UGE) {2180 } else if (op == TOK_UGE) {
2181 C67_CMPLTU(r, fr, C67_B2);2181 C67_CMPLTU(S, r, fr, C67_B2);
2182 C67_invert_test = TRUE;2182 C67_invert_test = TRUE;
2183 } else if (op == TOK_UGT) {2183 } else if (op == TOK_UGT) {
2184 C67_CMPGTU(r, fr, C67_B2);2184 C67_CMPGTU(S, r, fr, C67_B2);
2185 C67_invert_test = FALSE;2185 C67_invert_test = FALSE;
2186 } else if (op == TOK_ULE) {2186 } else if (op == TOK_ULE) {
2187 C67_CMPGTU(r, fr, C67_B2);2187 C67_CMPGTU(S, r, fr, C67_B2);
2188 C67_invert_test = TRUE;2188 C67_invert_test = TRUE;
2189 } else if (op == '+')2189 } else if (op == '+')
2190 C67_ADD(fr, r); // ADD r,fr,r2190 C67_ADD(S, fr, r); // ADD r,fr,r
2191 else if (op == '-')2191 else if (op == '-')
2192 C67_SUB(fr, r); // SUB r,fr,r2192 C67_SUB(S, fr, r); // SUB r,fr,r
2193 else if (op == '&')2193 else if (op == '&')
2194 C67_AND(fr, r); // AND r,fr,r2194 C67_AND(S, fr, r); // AND r,fr,r
2195 else if (op == '|')2195 else if (op == '|')
2196 C67_OR(fr, r); // OR r,fr,r2196 C67_OR(S, fr, r); // OR r,fr,r
2197 else if (op == '^')2197 else if (op == '^')
2198 C67_XOR(fr, r); // XOR r,fr,r2198 C67_XOR(S, fr, r); // XOR r,fr,r
2199 else2199 else
2200 ALWAYS_ASSERT(FALSE);2200 ALWAYS_ASSERT(FALSE);
2201 2201
2202 vtop--;2202 S->tccgen_vtop--;
2203 if (op >= TOK_ULT && op <= TOK_GT)2203 if (op >= TOK_ULT && op <= TOK_GT)
2204 vset_VT_CMP(0x80);2204 vset_VT_CMP(S, 0x80);
2205 break;2205 break;
2206 case '-':2206 case '-':
2207 case TOK_SUBC1: /* sub with carry generation */2207 case TOK_SUBC1: /* sub with carry generation */
@@ -2224,48 +2224,48 @@ void gen_opi(int op) · 16 unmodified lines
2224 goto gen_op8;2224 goto gen_op8;
2225 case '*':2225 case '*':
2226 case TOK_UMULL:2226 case TOK_UMULL:
2227 gv2(RC_INT, RC_INT);2227 gv2(S, RC_INT, RC_INT);
2228 r = vtop[-1].r;2228 r = S->tccgen_vtop[-1].r;
2229 fr = vtop[0].r;2229 fr = S->tccgen_vtop[0].r;
2230 vtop--;2230 S->tccgen_vtop--;
2231 C67_MPYI(fr, r); // 32 bit multiply fr,r,fr2231 C67_MPYI(S, fr, r); // 32 bit multiply fr,r,fr
2232 C67_NOP(8); // NOP 8 for worst case2232 C67_NOP(S, 8); // NOP 8 for worst case
2233 break;2233 break;
2234 case TOK_SHL:2234 case TOK_SHL:
2235 gv2(RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst2235 gv2(S, RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst
2236 r = vtop[-1].r;2236 r = S->tccgen_vtop[-1].r;
2237 fr = vtop[0].r;2237 fr = S->tccgen_vtop[0].r;
2238 vtop--;2238 S->tccgen_vtop--;
2239 C67_SHL(fr, r); // arithmetic/logical shift2239 C67_SHL(S, fr, r); // arithmetic/logical shift
2240 break;2240 break;
2241 2241
2242 case TOK_SHR:2242 case TOK_SHR:
2243 gv2(RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst2243 gv2(S, RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst
2244 r = vtop[-1].r;2244 r = S->tccgen_vtop[-1].r;
2245 fr = vtop[0].r;2245 fr = S->tccgen_vtop[0].r;
2246 vtop--;2246 S->tccgen_vtop--;
2247 C67_SHRU(fr, r); // logical shift2247 C67_SHRU(S, fr, r); // logical shift
2248 break;2248 break;
2249 2249
2250 case TOK_SAR:2250 case TOK_SAR:
2251 gv2(RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst2251 gv2(S, RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst
2252 r = vtop[-1].r;2252 r = S->tccgen_vtop[-1].r;
2253 fr = vtop[0].r;2253 fr = S->tccgen_vtop[0].r;
2254 vtop--;2254 S->tccgen_vtop--;
2255 C67_SHR(fr, r); // arithmetic shift2255 C67_SHR(S, fr, r); // arithmetic shift
2256 break;2256 break;
2257 2257
2258 case '/':2258 case '/':
2259 t = TOK__divi;2259 t = TOK__divi;
2260 call_func:2260 call_func:
2261 vswap();2261 vswap(S);
2262 /* call generic idiv function */2262 /* call generic idiv function */
2263 vpush_helper_func(t);2263 vpush_helper_func(S, t);
2264 vrott(3);2264 vrott(S, 3);
2265 gfunc_call(2);2265 gfunc_call(S, 2);
2266 vpushi(0);2266 vpushi(S, 0);
2267 vtop->r = REG_IRET;2267 S->tccgen_vtop->r = REG_IRET;
2268 vtop->r2 = VT_CONST;2268 S->tccgen_vtop->r2 = VT_CONST;
2269 break;2269 break;
2270 case TOK_UDIV:2270 case TOK_UDIV:
2271 case TOK_PDIV:2271 case TOK_PDIV:
@@ -2287,127 +2287,127 @@ void gen_opi(int op) · 15 unmodified lines
2287/* generate a floating point operation 'v = t1 op t2' instruction. The2287/* generate a floating point operation 'v = t1 op t2' instruction. The
2288 two operands are guaranteed to have the same floating point type */2288 two operands are guaranteed to have the same floating point type */
2289/* XXX: need to use ST1 too */2289/* XXX: need to use ST1 too */
2290void gen_opf(int op)2290void gen_opf(TCCState* S, int op)
2291{2291{
2292 int ft, fc, fr, r;2292 int ft, fc, fr, r;
2293 2293
2294 if (op >= TOK_ULT && op <= TOK_GT)2294 if (op >= TOK_ULT && op <= TOK_GT)
2295 gv2(RC_EDX, RC_EAX); // make sure src2 is on b side2295 gv2(S, RC_EDX, RC_EAX); // make sure src2 is on b side
2296 else2296 else
2297 gv2(RC_FLOAT, RC_FLOAT); // make sure src2 is on b side2297 gv2(S, RC_FLOAT, RC_FLOAT); // make sure src2 is on b side
2298 2298
2299 ft = vtop->type.t;2299 ft = S->tccgen_vtop->type.t;
2300 fc = vtop->c.i;2300 fc = S->tccgen_vtop->c.i;
2301 r = vtop->r;2301 r = S->tccgen_vtop->r;
2302 fr = vtop[-1].r;2302 fr = S->tccgen_vtop[-1].r;
2303 2303
2304 2304
2305 if ((ft & VT_BTYPE) == VT_LDOUBLE)2305 if ((ft & VT_BTYPE) == VT_LDOUBLE)
2306 tcc_error("long doubles not supported");2306 tcc_error(S, "long doubles not supported");
2307 2307
2308 if (op >= TOK_ULT && op <= TOK_GT) {2308 if (op >= TOK_ULT && op <= TOK_GT) {
2309 2309
2310 r = vtop[-1].r;2310 r = S->tccgen_vtop[-1].r;
2311 fr = vtop[0].r;2311 fr = S->tccgen_vtop[0].r;
2312 2312
2313 C67_compare_reg = C67_B2;2313 C67_compare_reg = C67_B2;
2314 2314
2315 if (op == TOK_LT) {2315 if (op == TOK_LT) {
2316 if ((ft & VT_BTYPE) == VT_DOUBLE)2316 if ((ft & VT_BTYPE) == VT_DOUBLE)
2317 C67_CMPLTDP(r, fr, C67_B2);2317 C67_CMPLTDP(S, r, fr, C67_B2);
2318 else2318 else
2319 C67_CMPLTSP(r, fr, C67_B2);2319 C67_CMPLTSP(S, r, fr, C67_B2);
2320 2320
2321 C67_invert_test = FALSE;2321 C67_invert_test = FALSE;
2322 } else if (op == TOK_GE) {2322 } else if (op == TOK_GE) {
2323 if ((ft & VT_BTYPE) == VT_DOUBLE)2323 if ((ft & VT_BTYPE) == VT_DOUBLE)
2324 C67_CMPLTDP(r, fr, C67_B2);2324 C67_CMPLTDP(S, r, fr, C67_B2);
2325 else2325 else
2326 C67_CMPLTSP(r, fr, C67_B2);2326 C67_CMPLTSP(S, r, fr, C67_B2);
2327 2327
2328 C67_invert_test = TRUE;2328 C67_invert_test = TRUE;
2329 } else if (op == TOK_GT) {2329 } else if (op == TOK_GT) {
2330 if ((ft & VT_BTYPE) == VT_DOUBLE)2330 if ((ft & VT_BTYPE) == VT_DOUBLE)
2331 C67_CMPGTDP(r, fr, C67_B2);2331 C67_CMPGTDP(S, r, fr, C67_B2);
2332 else2332 else
2333 C67_CMPGTSP(r, fr, C67_B2);2333 C67_CMPGTSP(S, r, fr, C67_B2);
2334 2334
2335 C67_invert_test = FALSE;2335 C67_invert_test = FALSE;
2336 } else if (op == TOK_LE) {2336 } else if (op == TOK_LE) {
2337 if ((ft & VT_BTYPE) == VT_DOUBLE)2337 if ((ft & VT_BTYPE) == VT_DOUBLE)
2338 C67_CMPGTDP(r, fr, C67_B2);2338 C67_CMPGTDP(S, r, fr, C67_B2);
2339 else2339 else
2340 C67_CMPGTSP(r, fr, C67_B2);2340 C67_CMPGTSP(S, r, fr, C67_B2);
2341 2341
2342 C67_invert_test = TRUE;2342 C67_invert_test = TRUE;
2343 } else if (op == TOK_EQ) {2343 } else if (op == TOK_EQ) {
2344 if ((ft & VT_BTYPE) == VT_DOUBLE)2344 if ((ft & VT_BTYPE) == VT_DOUBLE)
2345 C67_CMPEQDP(r, fr, C67_B2);2345 C67_CMPEQDP(S, r, fr, C67_B2);
2346 else2346 else
2347 C67_CMPEQSP(r, fr, C67_B2);2347 C67_CMPEQSP(S, r, fr, C67_B2);
2348 2348
2349 C67_invert_test = FALSE;2349 C67_invert_test = FALSE;
2350 } else if (op == TOK_NE) {2350 } else if (op == TOK_NE) {
2351 if ((ft & VT_BTYPE) == VT_DOUBLE)2351 if ((ft & VT_BTYPE) == VT_DOUBLE)
2352 C67_CMPEQDP(r, fr, C67_B2);2352 C67_CMPEQDP(S, r, fr, C67_B2);
2353 else2353 else
2354 C67_CMPEQSP(r, fr, C67_B2);2354 C67_CMPEQSP(S, r, fr, C67_B2);
2355 2355
2356 C67_invert_test = TRUE;2356 C67_invert_test = TRUE;
2357 } else {2357 } else {
2358 ALWAYS_ASSERT(FALSE);2358 ALWAYS_ASSERT(FALSE);
2359 }2359 }
2360 vset_VT_CMP(0x80);2360 vset_VT_CMP(S, 0x80);
2361 } else {2361 } else {
2362 if (op == '+') {2362 if (op == '+') {
2363 if ((ft & VT_BTYPE) == VT_DOUBLE) {2363 if ((ft & VT_BTYPE) == VT_DOUBLE) {
2364 C67_ADDDP(r, fr); // ADD fr,r,fr2364 C67_ADDDP(S, r, fr); // ADD fr,r,fr
2365 C67_NOP(6);2365 C67_NOP(S, 6);
2366 } else {2366 } else {
2367 C67_ADDSP(r, fr); // ADD fr,r,fr2367 C67_ADDSP(S, r, fr); // ADD fr,r,fr
2368 C67_NOP(3);2368 C67_NOP(S, 3);
2369 }2369 }
2370 vtop--;2370 S->tccgen_vtop--;
2371 } else if (op == '-') {2371 } else if (op == '-') {
2372 if ((ft & VT_BTYPE) == VT_DOUBLE) {2372 if ((ft & VT_BTYPE) == VT_DOUBLE) {
2373 C67_SUBDP(r, fr); // SUB fr,r,fr2373 C67_SUBDP(S, r, fr); // SUB fr,r,fr
2374 C67_NOP(6);2374 C67_NOP(S, 6);
2375 } else {2375 } else {
2376 C67_SUBSP(r, fr); // SUB fr,r,fr2376 C67_SUBSP(S, r, fr); // SUB fr,r,fr
2377 C67_NOP(3);2377 C67_NOP(S, 3);
2378 }2378 }
2379 vtop--;2379 S->tccgen_vtop--;
2380 } else if (op == '*') {2380 } else if (op == '*') {
2381 if ((ft & VT_BTYPE) == VT_DOUBLE) {2381 if ((ft & VT_BTYPE) == VT_DOUBLE) {
2382 C67_MPYDP(r, fr); // MPY fr,r,fr2382 C67_MPYDP(S, r, fr); // MPY fr,r,fr
2383 C67_NOP(9);2383 C67_NOP(S, 9);
2384 } else {2384 } else {
2385 C67_MPYSP(r, fr); // MPY fr,r,fr2385 C67_MPYSP(S, r, fr); // MPY fr,r,fr
2386 C67_NOP(3);2386 C67_NOP(S, 3);
2387 }2387 }
2388 vtop--;2388 S->tccgen_vtop--;
2389 } else if (op == '/') {2389 } else if (op == '/') {
2390 if ((ft & VT_BTYPE) == VT_DOUBLE) {2390 if ((ft & VT_BTYPE) == VT_DOUBLE) {
2391 // must call intrinsic DP floating point divide2391 // must call intrinsic DP floating point divide
2392 vswap();2392 vswap(S);
2393 /* call generic idiv function */2393 /* call generic idiv function */
2394 vpush_helper_func(TOK__divd);2394 vpush_helper_func(S, TOK__divd);
2395 vrott(3);2395 vrott(S, 3);
2396 gfunc_call(2);2396 gfunc_call(S, 2);
2397 vpushi(0);2397 vpushi(S, 0);
2398 vtop->r = REG_FRET;2398 S->tccgen_vtop->r = REG_FRET;
2399 vtop->r2 = REG_IRE2;2399 S->tccgen_vtop->r2 = REG_IRE2;
2400 2400
2401 } else {2401 } else {
2402 // must call intrinsic SP floating point divide2402 // must call intrinsic SP floating point divide
2403 vswap();2403 vswap(S);
2404 /* call generic idiv function */2404 /* call generic idiv function */
2405 vpush_helper_func(TOK__divf);2405 vpush_helper_func(S, TOK__divf);
2406 vrott(3);2406 vrott(S, 3);
2407 gfunc_call(2);2407 gfunc_call(S, 2);
2408 vpushi(0);2408 vpushi(S, 0);
2409 vtop->r = REG_FRET;2409 S->tccgen_vtop->r = REG_FRET;
2410 vtop->r2 = VT_CONST;2410 S->tccgen_vtop->r2 = VT_CONST;
2411 }2411 }
2412 } else2412 } else
2413 ALWAYS_ASSERT(FALSE);2413 ALWAYS_ASSERT(FALSE);
@@ -2419,122 +2419,122 @@ void gen_opf(int op) · 5 unmodified lines
2419 2419
2420/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'2420/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
2421 and 'long long' cases. */2421 and 'long long' cases. */
2422void gen_cvt_itof(int t)2422void gen_cvt_itof(TCCState* S, int t)
2423{2423{
2424 int r;2424 int r;
2425 2425
2426 gv(RC_INT);2426 gv(S, RC_INT);
2427 r = vtop->r;2427 r = S->tccgen_vtop->r;
2428 2428
2429 if ((t & VT_BTYPE) == VT_DOUBLE) {2429 if ((t & VT_BTYPE) == VT_DOUBLE) {
2430 if (t & VT_UNSIGNED)2430 if (t & VT_UNSIGNED)
2431 C67_INTDPU(r, r);2431 C67_INTDPU(S, r, r);
2432 else2432 else
2433 C67_INTDP(r, r);2433 C67_INTDP(S, r, r);
2434 2434
2435 C67_NOP(4);2435 C67_NOP(S, 4);
2436 vtop->type.t = VT_DOUBLE;2436 S->tccgen_vtop->type.t = VT_DOUBLE;
2437 } else {2437 } else {
2438 if (t & VT_UNSIGNED)2438 if (t & VT_UNSIGNED)
2439 C67_INTSPU(r, r);2439 C67_INTSPU(S, r, r);
2440 else2440 else
2441 C67_INTSP(r, r);2441 C67_INTSP(S, r, r);
2442 C67_NOP(3);2442 C67_NOP(S, 3);
2443 vtop->type.t = VT_FLOAT;2443 S->tccgen_vtop->type.t = VT_FLOAT;
2444 }2444 }
2445 2445
2446}2446}
2447 2447
2448/* convert fp to int 't' type */2448/* convert fp to int 't' type */
2449/* XXX: handle long long case */2449/* XXX: handle long long case */
2450void gen_cvt_ftoi(int t)2450void gen_cvt_ftoi(TCCState* S, int t)
2451{2451{
2452 int r;2452 int r;
2453 2453
2454 gv(RC_FLOAT);2454 gv(S, RC_FLOAT);
2455 r = vtop->r;2455 r = S->tccgen_vtop->r;
2456 2456
2457 if (t != VT_INT)2457 if (t != VT_INT)
2458 tcc_error("long long not supported");2458 tcc_error(S, "long long not supported");
2459 else {2459 else {
2460 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) {2460 if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_DOUBLE) {
2461 C67_DPTRUNC(r, r);2461 C67_DPTRUNC(S, r, r);
2462 C67_NOP(3);2462 C67_NOP(S, 3);
2463 } else {2463 } else {
2464 C67_SPTRUNC(r, r);2464 C67_SPTRUNC(S, r, r);
2465 C67_NOP(3);2465 C67_NOP(S, 3);
2466 }2466 }
2467 2467
2468 vtop->type.t = VT_INT;2468 S->tccgen_vtop->type.t = VT_INT;
2469 2469
2470 }2470 }
2471}2471}
2472 2472
2473/* convert from one floating point type to another */2473/* convert from one floating point type to another */
2474void gen_cvt_ftof(int t)2474void gen_cvt_ftof(TCCState* S, int t)
2475{2475{
2476 int r, r2;2476 int r, r2;
2477 2477
2478 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE &&2478 if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_DOUBLE &&
2479 (t & VT_BTYPE) == VT_FLOAT) {2479 (t & VT_BTYPE) == VT_FLOAT) {
2480 // convert double to float2480 // convert double to float
2481 2481
2482 gv(RC_FLOAT); // get it in a register pair2482 gv(S, RC_FLOAT); // get it in a register pair
2483 2483
2484 r = vtop->r;2484 r = S->tccgen_vtop->r;
2485 2485
2486 C67_DPSP(r, r); // convert it to SP same register2486 C67_DPSP(S, r, r); // convert it to SP same register
2487 C67_NOP(3);2487 C67_NOP(S, 3);
2488 2488
2489 vtop->type.t = VT_FLOAT;2489 S->tccgen_vtop->type.t = VT_FLOAT;
2490 vtop->r2 = VT_CONST; // set this as unused2490 S->tccgen_vtop->r2 = VT_CONST; // set this as unused
2491 } else if ((vtop->type.t & VT_BTYPE) == VT_FLOAT &&2491 } else if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_FLOAT &&
2492 (t & VT_BTYPE) == VT_DOUBLE) {2492 (t & VT_BTYPE) == VT_DOUBLE) {
2493 // convert float to double2493 // convert float to double
2494 2494
2495 gv(RC_FLOAT); // get it in a register2495 gv(S, RC_FLOAT); // get it in a register
2496 2496
2497 r = vtop->r;2497 r = S->tccgen_vtop->r;
2498 2498
2499 if (r == TREG_EAX) { // make sure the paired reg is avail2499 if (r == TREG_EAX) { // make sure the paired reg is avail
2500 r2 = get_reg(RC_ECX);2500 r2 = get_reg(S, RC_ECX);
2501 } else if (r == TREG_EDX) {2501 } else if (r == TREG_EDX) {
2502 r2 = get_reg(RC_ST0);2502 r2 = get_reg(S, RC_ST0);
2503 } else {2503 } else {
2504 ALWAYS_ASSERT(FALSE);2504 ALWAYS_ASSERT(FALSE);
2505 r2 = 0; /* avoid warning */2505 r2 = 0; /* avoid warning */
2506 }2506 }
2507 2507
2508 C67_SPDP(r, r); // convert it to DP same register2508 C67_SPDP(S, r, r); // convert it to DP same register
2509 C67_NOP(1);2509 C67_NOP(S, 1);
2510 2510
2511 vtop->type.t = VT_DOUBLE;2511 S->tccgen_vtop->type.t = VT_DOUBLE;
2512 vtop->r2 = r2; // set this as unused2512 S->tccgen_vtop->r2 = r2; // set this as unused
2513 } else {2513 } else {
2514 ALWAYS_ASSERT(FALSE);2514 ALWAYS_ASSERT(FALSE);
2515 }2515 }
2516}2516}
2517 2517
2518/* computed goto support */2518/* computed goto support */
2519void ggoto(void)2519void ggoto(TCCState* S)
2520{2520{
2521 gcall_or_jmp(1);2521 gcall_or_jmp(S, 1);
2522 vtop--;2522 S->tccgen_vtop--;
2523}2523}
2524 2524
2525/* Save the stack pointer onto the stack and return the location of its address */2525/* Save the stack pointer onto the stack and return the location of its address */
2526ST_FUNC void gen_vla_sp_save(int addr) {2526ST_FUNC void gen_vla_sp_save(TCCState* S, int addr) {
2527 tcc_error("variable length arrays unsupported for this target");2527 tcc_error(S, "variable length arrays unsupported for this target");
2528}2528}
2529 2529
2530/* Restore the SP from a location on the stack */2530/* Restore the SP from a location on the stack */
2531ST_FUNC void gen_vla_sp_restore(int addr) {2531ST_FUNC void gen_vla_sp_restore(TCCState* S, int addr) {
2532 tcc_error("variable length arrays unsupported for this target");2532 tcc_error(S, "variable length arrays unsupported for this target");
2533}2533}
2534 2534
2535/* Subtract from the stack pointer, and push the resulting value onto the stack */2535/* Subtract from the stack pointer, and push the resulting value onto the stack */
2536ST_FUNC void gen_vla_alloc(CType *type, int align) {2536ST_FUNC void gen_vla_alloc(TCCState* S, CType *type, int align) {
2537 tcc_error("variable length arrays unsupported for this target");2537 tcc_error(S, "variable length arrays unsupported for this target");
2538}2538}
2539 2539
2540/* end of C67 code generator */2540/* end of C67 code generator */
c67-link.c+7−7
@@ -65,23 +65,23 @@ int gotplt_entry_type (int reloc_type) · 64 unmodified lines
65 return -1;65 return -1;
66}66}
67 67
68ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)68ST_FUNC unsigned create_plt_entry(TCCState *S, unsigned got_offset, struct sym_attr *attr)
69{69{
70 tcc_error("C67 got not implemented");70 tcc_error(S, "C67 got not implemented");
71 return 0;71 return 0;
72}72}
73 73
74/* relocate the PLT: compute addresses and offsets in the PLT now that final74/* relocate the PLT: compute addresses and offsets in the PLT now that final
75 address for PLT and GOT are known (see fill_program_header) */75 address for PLT and GOT are known (see fill_program_header) */
76ST_FUNC void relocate_plt(TCCState *s1)76ST_FUNC void relocate_plt(TCCState *S)
77{77{
78 uint8_t *p, *p_end;78 uint8_t *p, *p_end;
79 79
80 if (!s1->plt)80 if (!S->plt)
81 return;81 return;
82 82
83 p = s1->plt->data;83 p = S->plt->data;
84 p_end = p + s1->plt->data_offset;84 p_end = p + S->plt->data_offset;
85 85
86 if (p < p_end) {86 if (p < p_end) {
87 /* XXX: TODO */87 /* XXX: TODO */
@@ -91,7 +91,7 @@ ST_FUNC void relocate_plt(TCCState *s1) · 3 unmodified lines
91 }91 }
92}92}
93 93
94void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)94void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
95{95{
96 switch(type) {96 switch(type) {
97 case R_C60_32:97 case R_C60_32:
i386-asm.c+187−187
@@ -253,10 +253,10 @@ static const uint16_t op0_codes[] = { · 252 unmodified lines
253#endif253#endif
254};254};
255 255
256static inline int get_reg_shift(TCCState *s1)256static inline int get_reg_shift(TCCState *S)
257{257{
258 int shift, v;258 int shift, v;
259 v = asm_int_expr(s1);259 v = asm_int_expr(S);
260 switch(v) {260 switch(v) {
261 case 1:261 case 1:
262 shift = 0;262 shift = 0;
@@ -271,7 +271,7 @@ static inline int get_reg_shift(TCCState *s1) · 8 unmodified lines
271 shift = 3;271 shift = 3;
272 break;272 break;
273 default:273 default:
274 expect("1, 2, 4 or 8 constant");274 expect(S, "1, 2, 4 or 8 constant");
275 shift = 0;275 shift = 0;
276 break;276 break;
277 }277 }
@@ -279,11 +279,11 @@ static inline int get_reg_shift(TCCState *s1) · 1 unmodified line
279}279}
280 280
281#ifdef TCC_TARGET_X86_64281#ifdef TCC_TARGET_X86_64
282static int asm_parse_numeric_reg(int t, unsigned int *type)282static int asm_parse_numeric_reg(TCCState *S, int t, unsigned int *type)
283{283{
284 int reg = -1;284 int reg = -1;
285 if (t >= TOK_IDENT && t < tok_ident) {285 if (t >= TOK_IDENT && t < S->tccpp_tok_ident) {
286 const char *s = table_ident[t - TOK_IDENT]->str;286 const char *s = S->tccpp_table_ident[t - TOK_IDENT]->str;
287 char c;287 char c;
288 *type = OP_REG64;288 *type = OP_REG64;
289 if (*s == 'c') {289 if (*s == 'c') {
@@ -318,51 +318,51 @@ static int asm_parse_numeric_reg(int t, unsigned int *type) · 28 unmodified lines
318}318}
319#endif319#endif
320 320
321static int asm_parse_reg(unsigned int *type)321static int asm_parse_reg(TCCState* S, unsigned int *type)
322{322{
323 int reg = 0;323 int reg = 0;
324 *type = 0;324 *type = 0;
325 if (tok != '%')325 if (S->tccpp_tok != '%')
326 goto error_32;326 goto error_32;
327 next();327 next(S);
328 if (tok >= TOK_ASM_eax && tok <= TOK_ASM_edi) {328 if (S->tccpp_tok >= TOK_ASM_eax && S->tccpp_tok <= TOK_ASM_edi) {
329 reg = tok - TOK_ASM_eax;329 reg = S->tccpp_tok - TOK_ASM_eax;
330 *type = OP_REG32;330 *type = OP_REG32;
331#ifdef TCC_TARGET_X86_64331#ifdef TCC_TARGET_X86_64
332 } else if (tok >= TOK_ASM_rax && tok <= TOK_ASM_rdi) {332 } else if (S->tccpp_tok >= TOK_ASM_rax && S->tccpp_tok <= TOK_ASM_rdi) {
333 reg = tok - TOK_ASM_rax;333 reg = S->tccpp_tok - TOK_ASM_rax;
334 *type = OP_REG64;334 *type = OP_REG64;
335 } else if (tok == TOK_ASM_rip) {335 } else if (S->tccpp_tok == TOK_ASM_rip) {
336 reg = -2; /* Probably should use different escape code. */336 reg = -2; /* Probably should use different escape code. */
337 *type = OP_REG64;337 *type = OP_REG64;
338 } else if ((reg = asm_parse_numeric_reg(tok, type)) >= 0338 } else if ((reg = asm_parse_numeric_reg(S, S->tccpp_tok, type)) >= 0
339 && (*type == OP_REG32 || *type == OP_REG64)) {339 && (*type == OP_REG32 || *type == OP_REG64)) {
340 ;340 ;
341#endif341#endif
342 } else {342 } else {
343 error_32:343 error_32:
344 expect("register");344 expect(S, "register");
345 }345 }
346 next();346 next(S);
347 return reg;347 return reg;
348}348}
349 349
350static void parse_operand(TCCState *s1, Operand *op)350static void parse_operand(TCCState *S, Operand *op)
351{351{
352 ExprValue e;352 ExprValue e;
353 int reg, indir;353 int reg, indir;
354 const char *p;354 const char *p;
355 355
356 indir = 0;356 indir = 0;
357 if (tok == '*') {357 if (S->tccpp_tok == '*') {
358 next();358 next(S);
359 indir = OP_INDIR;359 indir = OP_INDIR;
360 }360 }
361 361
362 if (tok == '%') {362 if (S->tccpp_tok == '%') {
363 next();363 next(S);
364 if (tok >= TOK_ASM_al && tok <= TOK_ASM_db7) {364 if (S->tccpp_tok >= TOK_ASM_al && S->tccpp_tok <= TOK_ASM_db7) {
365 reg = tok - TOK_ASM_al;365 reg = S->tccpp_tok - TOK_ASM_al;
366 op->type = 1 << (reg >> 3); /* WARNING: do not change constant order */366 op->type = 1 << (reg >> 3); /* WARNING: do not change constant order */
367 op->reg = reg & 7;367 op->reg = reg & 7;
368 if ((op->type & OP_REG) && op->reg == TREG_XAX)368 if ((op->type & OP_REG) && op->reg == TREG_XAX)
@@ -371,48 +371,48 @@ static void parse_operand(TCCState *s1, Operand *op) · 2 unmodified lines
371 op->type |= OP_CL;371 op->type |= OP_CL;
372 else if (op->type == OP_REG16 && op->reg == TREG_XDX)372 else if (op->type == OP_REG16 && op->reg == TREG_XDX)
373 op->type |= OP_DX;373 op->type |= OP_DX;
374 } else if (tok >= TOK_ASM_dr0 && tok <= TOK_ASM_dr7) {374 } else if (S->tccpp_tok >= TOK_ASM_dr0 && S->tccpp_tok <= TOK_ASM_dr7) {
375 op->type = OP_DB;375 op->type = OP_DB;
376 op->reg = tok - TOK_ASM_dr0;376 op->reg = S->tccpp_tok - TOK_ASM_dr0;
377 } else if (tok >= TOK_ASM_es && tok <= TOK_ASM_gs) {377 } else if (S->tccpp_tok >= TOK_ASM_es && S->tccpp_tok <= TOK_ASM_gs) {
378 op->type = OP_SEG;378 op->type = OP_SEG;
379 op->reg = tok - TOK_ASM_es;379 op->reg = S->tccpp_tok - TOK_ASM_es;
380 } else if (tok == TOK_ASM_st) {380 } else if (S->tccpp_tok == TOK_ASM_st) {
381 op->type = OP_ST;381 op->type = OP_ST;
382 op->reg = 0;382 op->reg = 0;
383 next();383 next(S);
384 if (tok == '(') {384 if (S->tccpp_tok == '(') {
385 next();385 next(S);
386 if (tok != TOK_PPNUM)386 if (S->tccpp_tok != TOK_PPNUM)
387 goto reg_error;387 goto reg_error;
388 p = tokc.str.data;388 p = S->tccpp_tokc.str.data;
389 reg = p[0] - '0';389 reg = p[0] - '0';
390 if ((unsigned)reg >= 8 || p[1] != '\0')390 if ((unsigned)reg >= 8 || p[1] != '\0')
391 goto reg_error;391 goto reg_error;
392 op->reg = reg;392 op->reg = reg;
393 next();393 next(S);
394 skip(')');394 skip(S, ')');
395 }395 }
396 if (op->reg == 0)396 if (op->reg == 0)
397 op->type |= OP_ST0;397 op->type |= OP_ST0;
398 goto no_skip;398 goto no_skip;
399#ifdef TCC_TARGET_X86_64399#ifdef TCC_TARGET_X86_64
400 } else if (tok >= TOK_ASM_spl && tok <= TOK_ASM_dil) {400 } else if (S->tccpp_tok >= TOK_ASM_spl && S->tccpp_tok <= TOK_ASM_dil) {
401 op->type = OP_REG8 | OP_REG8_LOW;401 op->type = OP_REG8 | OP_REG8_LOW;
402 op->reg = 4 + tok - TOK_ASM_spl;402 op->reg = 4 + S->tccpp_tok - TOK_ASM_spl;
403 } else if ((op->reg = asm_parse_numeric_reg(tok, &op->type)) >= 0) {403 } else if ((op->reg = asm_parse_numeric_reg(S, S->tccpp_tok, &op->type)) >= 0) {
404 ;404 ;
405#endif405#endif
406 } else {406 } else {
407 reg_error:407 reg_error:
408 tcc_error("unknown register %%%s", get_tok_str(tok, &tokc));408 tcc_error(S, "unknown register %%%s", get_tok_str(S, S->tccpp_tok, &S->tccpp_tokc));
409 }409 }
410 next();410 next(S);
411 no_skip: ;411 no_skip: ;
412 } else if (tok == '$') {412 } else if (S->tccpp_tok == '$') {
413 /* constant value */413 /* constant value */
414 next();414 next(S);
415 asm_expr(s1, &e);415 asm_expr(S, &e);
416 op->type = OP_IM32;416 op->type = OP_IM32;
417 op->e = e;417 op->e = e;
418 if (!op->e.sym) {418 if (!op->e.sym) {
@@ -433,45 +433,45 @@ static void parse_operand(TCCState *s1, Operand *op) · 14 unmodified lines
433 op->reg = -1;433 op->reg = -1;
434 op->reg2 = -1;434 op->reg2 = -1;
435 op->shift = 0;435 op->shift = 0;
436 if (tok != '(') {436 if (S->tccpp_tok != '(') {
437 asm_expr(s1, &e);437 asm_expr(S, &e);
438 op->e = e;438 op->e = e;
439 } else {439 } else {
440 next();440 next(S);
441 if (tok == '%') {441 if (S->tccpp_tok == '%') {
442 unget_tok('(');442 unget_tok(S, '(');
443 op->e.v = 0;443 op->e.v = 0;
444 op->e.sym = NULL;444 op->e.sym = NULL;
445 } else {445 } else {
446 /* bracketed offset expression */446 /* bracketed offset expression */
447 asm_expr(s1, &e);447 asm_expr(S, &e);
448 if (tok != ')')448 if (S->tccpp_tok != ')')
449 expect(")");449 expect(S, ")");
450 next();450 next(S);
451 op->e.v = e.v;451 op->e.v = e.v;
452 op->e.sym = e.sym;452 op->e.sym = e.sym;
453 }453 }
454 op->e.pcrel = 0;454 op->e.pcrel = 0;
455 }455 }
456 if (tok == '(') {456 if (S->tccpp_tok == '(') {
457 unsigned int type = 0;457 unsigned int type = 0;
458 next();458 next(S);
459 if (tok != ',') {459 if (S->tccpp_tok != ',') {
460 op->reg = asm_parse_reg(&type);460 op->reg = asm_parse_reg(S, &type);
461 }461 }
462 if (tok == ',') {462 if (S->tccpp_tok == ',') {
463 next();463 next(S);
464 if (tok != ',') {464 if (S->tccpp_tok != ',') {
465 op->reg2 = asm_parse_reg(&type);465 op->reg2 = asm_parse_reg(S, &type);
466 }466 }
467 if (tok == ',') {467 if (S->tccpp_tok == ',') {
468 next();468 next(S);
469 op->shift = get_reg_shift(s1);469 op->shift = get_reg_shift(S);
470 }470 }
471 }471 }
472 if (type & OP_REG32)472 if (type & OP_REG32)
473 op->type |= OP_EA32;473 op->type |= OP_EA32;
474 skip(')');474 skip(S, ')');
475 }475 }
476 if (op->reg == -1 && op->reg2 == -1)476 if (op->reg == -1 && op->reg2 == -1)
477 op->type |= OP_ADDR;477 op->type |= OP_ADDR;
@@ -480,65 +480,65 @@ static void parse_operand(TCCState *s1, Operand *op) · 2 unmodified lines
480}480}
481 481
482/* XXX: unify with C code output ? */482/* XXX: unify with C code output ? */
483ST_FUNC void gen_expr32(ExprValue *pe)483ST_FUNC void gen_expr32(TCCState* S, ExprValue *pe)
484{484{
485 if (pe->pcrel)485 if (pe->pcrel)
486 /* If PC-relative, always set VT_SYM, even without symbol,486 /* If PC-relative, always set VT_SYM, even without symbol,
487 so as to force a relocation to be emitted. */487 so as to force a relocation to be emitted. */
488 gen_addrpc32(VT_SYM, pe->sym, pe->v);488 gen_addrpc32(S, VT_SYM, pe->sym, pe->v);
489 else489 else
490 gen_addr32(pe->sym ? VT_SYM : 0, pe->sym, pe->v);490 gen_addr32(S, pe->sym ? VT_SYM : 0, pe->sym, pe->v);
491}491}
492 492
493#ifdef TCC_TARGET_X86_64493#ifdef TCC_TARGET_X86_64
494ST_FUNC void gen_expr64(ExprValue *pe)494ST_FUNC void gen_expr64(TCCState* S, ExprValue *pe)
495{495{
496 gen_addr64(pe->sym ? VT_SYM : 0, pe->sym, pe->v);496 gen_addr64(S, pe->sym ? VT_SYM : 0, pe->sym, pe->v);
497}497}
498#endif498#endif
499 499
500/* XXX: unify with C code output ? */500/* XXX: unify with C code output ? */
501static void gen_disp32(ExprValue *pe)501static void gen_disp32(TCCState* S, ExprValue *pe)
502{502{
503 Sym *sym = pe->sym;503 Sym *sym = pe->sym;
504 ElfSym *esym = elfsym(sym);504 ElfSym *esym = elfsym(S, sym);
505 if (esym && esym->st_shndx == cur_text_section->sh_num) {505 if (esym && esym->st_shndx == cur_text_section->sh_num) {
506 /* same section: we can output an absolute value. Note506 /* same section: we can output an absolute value. Note
507 that the TCC compiler behaves differently here because507 that the TCC compiler behaves differently here because
508 it always outputs a relocation to ease (future) code508 it always outputs a relocation to ease (future) code
509 elimination in the linker */509 elimination in the linker */
510 gen_le32(pe->v + esym->st_value - ind - 4);510 gen_le32(S, pe->v + esym->st_value - S->tccgen_ind - 4);
511 } else {511 } else {
512 if (sym && sym->type.t == VT_VOID) {512 if (sym && sym->type.t == VT_VOID) {
513 sym->type.t = VT_FUNC;513 sym->type.t = VT_FUNC;
514 sym->type.ref = NULL;514 sym->type.ref = NULL;
515 }515 }
516 gen_addrpc32(VT_SYM, sym, pe->v);516 gen_addrpc32(S, VT_SYM, sym, pe->v);
517 }517 }
518}518}
519 519
520/* generate the modrm operand */520/* generate the modrm operand */
521static inline int asm_modrm(int reg, Operand *op)521static inline int asm_modrm(TCCState* S, int reg, Operand *op)
522{522{
523 int mod, reg1, reg2, sib_reg1;523 int mod, reg1, reg2, sib_reg1;
524 524
525 if (op->type & (OP_REG | OP_MMX | OP_SSE)) {525 if (op->type & (OP_REG | OP_MMX | OP_SSE)) {
526 g(0xc0 + (reg << 3) + op->reg);526 g(S, 0xc0 + (reg << 3) + op->reg);
527 } else if (op->reg == -1 && op->reg2 == -1) {527 } else if (op->reg == -1 && op->reg2 == -1) {
528 /* displacement only */528 /* displacement only */
529#ifdef TCC_TARGET_X86_64529#ifdef TCC_TARGET_X86_64
530 g(0x04 + (reg << 3));530 g(S, 0x04 + (reg << 3));
531 g(0x25);531 g(S, 0x25);
532#else532#else
533 g(0x05 + (reg << 3));533 g(S, 0x05 + (reg << 3));
534#endif534#endif
535 gen_expr32(&op->e);535 gen_expr32(S, &op->e);
536#ifdef TCC_TARGET_X86_64536#ifdef TCC_TARGET_X86_64
537 } else if (op->reg == -2) {537 } else if (op->reg == -2) {
538 ExprValue *pe = &op->e;538 ExprValue *pe = &op->e;
539 g(0x05 + (reg << 3));539 g(S, 0x05 + (reg << 3));
540 gen_addrpc32(pe->sym ? VT_SYM : 0, pe->sym, pe->v);540 gen_addrpc32(S, pe->sym ? VT_SYM : 0, pe->sym, pe->v);
541 return ind;541 return S->tccgen_ind;
542#endif542#endif
543 } else {543 } else {
544 sib_reg1 = op->reg;544 sib_reg1 = op->reg;
@@ -557,19 +557,19 @@ static inline int asm_modrm(int reg, Operand *op) · 12 unmodified lines
557 reg1 = op->reg;557 reg1 = op->reg;
558 if (op->reg2 != -1)558 if (op->reg2 != -1)
559 reg1 = 4;559 reg1 = 4;
560 g(mod + (reg << 3) + reg1);560 g(S, mod + (reg << 3) + reg1);
561 if (reg1 == 4) {561 if (reg1 == 4) {
562 /* add sib byte */562 /* add sib byte */
563 reg2 = op->reg2;563 reg2 = op->reg2;
564 if (reg2 == -1)564 if (reg2 == -1)
565 reg2 = 4; /* indicate no index */565 reg2 = 4; /* indicate no index */
566 g((op->shift << 6) + (reg2 << 3) + sib_reg1);566 g(S, (op->shift << 6) + (reg2 << 3) + sib_reg1);
567 }567 }
568 /* add offset */568 /* add offset */
569 if (mod == 0x40) {569 if (mod == 0x40) {
570 g(op->e.v);570 g(S, op->e.v);
571 } else if (mod == 0x80 || op->reg == -1) {571 } else if (mod == 0x80 || op->reg == -1) {
572 gen_expr32(&op->e);572 gen_expr32(S, &op->e);
573 }573 }
574 }574 }
575 return 0;575 return 0;
@@ -581,7 +581,7 @@ static inline int asm_modrm(int reg, Operand *op) · 5 unmodified lines
581#define REX_X 0x42581#define REX_X 0x42
582#define REX_B 0x41582#define REX_B 0x41
583 583
584static void asm_rex(int width64, Operand *ops, int nb_ops, int *op_type,584static void asm_rex(TCCState* S, int width64, Operand *ops, int nb_ops, int *op_type,
585 int regi, int rmi)585 int regi, int rmi)
586{586{
587 unsigned char rex = width64 ? 0x48 : 0;587 unsigned char rex = width64 ? 0x48 : 0;
@@ -631,9 +631,9 @@ static void asm_rex(int width64, Operand *ops, int nb_ops, int *op_type, · 43 unmodified lines
631 }631 }
632 if (rex) {632 if (rex) {
633 if (saw_high_8bit)633 if (saw_high_8bit)
634 tcc_error("can't encode register %%%ch when REX prefix is required",634 tcc_error(S, "can't encode register %%%ch when REX prefix is required",
635 "acdb"[saw_high_8bit-4]);635 "acdb"[saw_high_8bit-4]);
636 g(rex);636 g(S, rex);
637 }637 }
638}638}
639#endif639#endif
@@ -679,7 +679,7 @@ static void maybe_print_stats (void) · 39 unmodified lines
679 }679 }
680}680}
681 681
682ST_FUNC void asm_opcode(TCCState *s1, int opcode)682ST_FUNC void asm_opcode(TCCState *S, int opcode)
683{683{
684 const ASMInstr *pa;684 const ASMInstr *pa;
685 int i, modrm_index, modreg_index, reg, v, op1, seg_prefix, pc;685 int i, modrm_index, modreg_index, reg, v, op1, seg_prefix, pc;
@@ -697,7 +697,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode) · 11 unmodified lines
697 /* force synthetic ';' after prefix instruction, so we can handle */697 /* force synthetic ';' after prefix instruction, so we can handle */
698 /* one-line things like "rep stosb" instead of only "rep\nstosb" */698 /* one-line things like "rep stosb" instead of only "rep\nstosb" */
699 if (opcode >= TOK_ASM_wait && opcode <= TOK_ASM_repnz)699 if (opcode >= TOK_ASM_wait && opcode <= TOK_ASM_repnz)
700 unget_tok(';');700 unget_tok(S, ';');
701 701
702 /* get operands */702 /* get operands */
703 pop = ops;703 pop = ops;
@@ -705,27 +705,27 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode) · 1 unmodified line
705 seg_prefix = 0;705 seg_prefix = 0;
706 alltypes = 0;706 alltypes = 0;
707 for(;;) {707 for(;;) {
708 if (tok == ';' || tok == TOK_LINEFEED)708 if (S->tccpp_tok == ';' || S->tccpp_tok == TOK_LINEFEED)
709 break;709 break;
710 if (nb_ops >= MAX_OPERANDS) {710 if (nb_ops >= MAX_OPERANDS) {
711 tcc_error("incorrect number of operands");711 tcc_error(S, "incorrect number of operands");
712 }712 }
713 parse_operand(s1, pop);713 parse_operand(S, pop);
714 if (tok == ':') {714 if (S->tccpp_tok == ':') {
715 if (pop->type != OP_SEG || seg_prefix)715 if (pop->type != OP_SEG || seg_prefix)
716 tcc_error("incorrect prefix");716 tcc_error(S, "incorrect prefix");
717 seg_prefix = segment_prefixes[pop->reg];717 seg_prefix = segment_prefixes[pop->reg];
718 next();718 next(S);
719 parse_operand(s1, pop);719 parse_operand(S, pop);
720 if (!(pop->type & OP_EA)) {720 if (!(pop->type & OP_EA)) {
721 tcc_error("segment prefix must be followed by memory reference");721 tcc_error(S, "segment prefix must be followed by memory reference");
722 }722 }
723 }723 }
724 pop++;724 pop++;
725 nb_ops++;725 nb_ops++;
726 if (tok != ',')726 if (S->tccpp_tok != ',')
727 break;727 break;
728 next();728 next(S);
729 }729 }
730 730
731 s = 0; /* avoid warning */731 s = 0; /* avoid warning */
@@ -842,23 +842,23 @@ again: · 110 unmodified lines
842 int b;842 int b;
843 b = op0_codes[opcode - TOK_ASM_first];843 b = op0_codes[opcode - TOK_ASM_first];
844 if (b & 0xff00) 844 if (b & 0xff00)
845 g(b >> 8);845 g(S, b >> 8);
846 g(b);846 g(S, b);
847 return;847 return;
848 } else if (opcode <= TOK_ASM_alllast) {848 } else if (opcode <= TOK_ASM_alllast) {
849 tcc_error("bad operand with opcode '%s'",849 tcc_error(S, "bad operand with opcode '%s'",
850 get_tok_str(opcode, NULL));850 get_tok_str(S, opcode, NULL));
851 } else {851 } else {
852 /* Special case for cmovcc, we accept size suffixes but ignore852 /* Special case for cmovcc, we accept size suffixes but ignore
853 them, but we don't want them to blow up our tables. */853 them, but we don't want them to blow up our tables. */
854 TokenSym *ts = table_ident[opcode - TOK_IDENT];854 TokenSym *ts = S->tccpp_table_ident[opcode - TOK_IDENT];
855 if (ts->len >= 6855 if (ts->len >= 6
856 && strchr("wlq", ts->str[ts->len-1])856 && strchr("wlq", ts->str[ts->len-1])
857 && !memcmp(ts->str, "cmov", 4)) {857 && !memcmp(ts->str, "cmov", 4)) {
858 opcode = tok_alloc(ts->str, ts->len-1)->tok;858 opcode = tok_alloc(S, ts->str, ts->len-1)->tok;
859 goto again;859 goto again;
860 }860 }
861 tcc_error("unknown opcode '%s'", ts->str);861 tcc_error(S, "unknown opcode '%s'", ts->str);
862 }862 }
863 }863 }
864 /* if the size is unknown, then evaluate it (OPC_B or OPC_WL case) */864 /* if the size is unknown, then evaluate it (OPC_B or OPC_WL case) */
@@ -886,7 +886,7 @@ again: · 21 unmodified lines
886 (ops[0].type & OP_EA))886 (ops[0].type & OP_EA))
887 s = NBWLX - 2;887 s = NBWLX - 2;
888 else888 else
889 tcc_error("cannot infer opcode suffix");889 tcc_error(S, "cannot infer opcode suffix");
890 }890 }
891 }891 }
892 892
@@ -894,7 +894,7 @@ again: · 1 unmodified line
894 /* Generate addr32 prefix if needed */894 /* Generate addr32 prefix if needed */
895 for(i = 0; i < nb_ops; i++) {895 for(i = 0; i < nb_ops; i++) {
896 if (ops[i].type & OP_EA32) {896 if (ops[i].type & OP_EA32) {
897 g(0x67);897 g(S, 0x67);
898 break;898 break;
899 }899 }
900 }900 }
@@ -913,7 +913,7 @@ again: · 12 unmodified lines
913 p66 = 1;913 p66 = 1;
914 }914 }
915 if (p66)915 if (p66)
916 g(0x66);916 g(S, 0x66);
917#ifdef TCC_TARGET_X86_64917#ifdef TCC_TARGET_X86_64
918 rex64 = 0;918 rex64 = 0;
919 if (pa->instr_type & OPC_48)919 if (pa->instr_type & OPC_48)
@@ -943,9 +943,9 @@ again: · 23 unmodified lines
943 943
944 /* now generates the operation */944 /* now generates the operation */
945 if (OPCT_IS(pa->instr_type, OPC_FWAIT))945 if (OPCT_IS(pa->instr_type, OPC_FWAIT))
946 g(0x9b);946 g(S, 0x9b);
947 if (seg_prefix)947 if (seg_prefix)
948 g(seg_prefix);948 g(S, seg_prefix);
949 949
950 v = pa->opcode;950 v = pa->opcode;
951 if (pa->instr_type & OPC_0F)951 if (pa->instr_type & OPC_0F)
@@ -998,7 +998,7 @@ again: · 46 unmodified lines
998 goto modrm_found;998 goto modrm_found;
999 }999 }
1000#ifdef ASM_DEBUG1000#ifdef ASM_DEBUG
1001 tcc_error("bad op table");1001 tcc_error(S, "bad op table");
1002#endif1002#endif
1003 modrm_found:1003 modrm_found:
1004 modrm_index = i;1004 modrm_index = i;
@@ -1014,7 +1014,7 @@ again: · 9 unmodified lines
1014 }1014 }
1015 }1015 }
1016#ifdef TCC_TARGET_X86_641016#ifdef TCC_TARGET_X86_64
1017 asm_rex (rex64, ops, nb_ops, op_type, modreg_index, modrm_index);1017 asm_rex (S, rex64, ops, nb_ops, op_type, modreg_index, modrm_index);
1018#endif1018#endif
1019 1019
1020 if (pa->instr_type & OPC_REG) {1020 if (pa->instr_type & OPC_REG) {
@@ -1035,10 +1035,10 @@ again: · 14 unmodified lines
1035 int jmp_disp;1035 int jmp_disp;
1036 1036
1037 /* see if we can really generate the jump with a byte offset */1037 /* see if we can really generate the jump with a byte offset */
1038 esym = elfsym(ops[0].e.sym);1038 esym = elfsym(S, ops[0].e.sym);
1039 if (!esym || esym->st_shndx != cur_text_section->sh_num)1039 if (!esym || esym->st_shndx != cur_text_section->sh_num)
1040 goto no_short_jump;1040 goto no_short_jump;
1041 jmp_disp = ops[0].e.v + esym->st_value - ind - 2 - (v >= 0xff);1041 jmp_disp = ops[0].e.v + esym->st_value - S->tccgen_ind - 2 - (v >= 0xff);
1042 if (jmp_disp == (int8_t)jmp_disp) {1042 if (jmp_disp == (int8_t)jmp_disp) {
1043 /* OK to generate jump */1043 /* OK to generate jump */
1044 ops[0].e.sym = 0;1044 ops[0].e.sym = 0;
@@ -1053,18 +1053,18 @@ again: · 8 unmodified lines
1053 else if (v == 0x70) /* jcc */1053 else if (v == 0x70) /* jcc */
1054 v += 0x0f10;1054 v += 0x0f10;
1055 else1055 else
1056 tcc_error("invalid displacement");1056 tcc_error(S, "invalid displacement");
1057 }1057 }
1058 }1058 }
1059 if (OPCT_IS(pa->instr_type, OPC_TEST))1059 if (OPCT_IS(pa->instr_type, OPC_TEST))
1060 v += test_bits[opcode - pa->sym];1060 v += test_bits[opcode - pa->sym];
1061 op1 = v >> 16;1061 op1 = v >> 16;
1062 if (op1)1062 if (op1)
1063 g(op1);1063 g(S, op1);
1064 op1 = (v >> 8) & 0xff;1064 op1 = (v >> 8) & 0xff;
1065 if (op1)1065 if (op1)
1066 g(op1);1066 g(S, op1);
1067 g(v);1067 g(S, v);
1068 1068
1069 if (OPCT_IS(pa->instr_type, OPC_SHIFT)) {1069 if (OPCT_IS(pa->instr_type, OPC_SHIFT)) {
1070 reg = (opcode - pa->sym) / NBWLX;1070 reg = (opcode - pa->sym) / NBWLX;
@@ -1084,7 +1084,7 @@ again: · 13 unmodified lines
1084 used instead of group */1084 used instead of group */
1085 if (modreg_index >= 0)1085 if (modreg_index >= 0)
1086 reg = ops[modreg_index].reg;1086 reg = ops[modreg_index].reg;
1087 pc = asm_modrm(reg, &ops[modrm_index]);1087 pc = asm_modrm(S, reg, &ops[modrm_index]);
1088 }1088 }
1089 1089
1090 /* emit constants */1090 /* emit constants */
@@ -1092,10 +1092,10 @@ again: · 1 unmodified line
1092 if (!(pa->instr_type & OPC_0F)1092 if (!(pa->instr_type & OPC_0F)
1093 && (pa->opcode == 0x9a || pa->opcode == 0xea)) {1093 && (pa->opcode == 0x9a || pa->opcode == 0xea)) {
1094 /* ljmp or lcall kludge */1094 /* ljmp or lcall kludge */
1095 gen_expr32(&ops[1].e);1095 gen_expr32(S, &ops[1].e);
1096 if (ops[0].e.sym)1096 if (ops[0].e.sym)
1097 tcc_error("cannot relocate");1097 tcc_error(S, "cannot relocate");
1098 gen_le16(ops[0].e.v);1098 gen_le16(S, ops[0].e.v);
1099 return;1099 return;
1100 }1100 }
1101#endif1101#endif
@@ -1116,32 +1116,32 @@ again: · 14 unmodified lines
1116 }1116 }
1117 1117
1118 if ((v & (OP_IM8 | OP_IM8S | OP_IM16)) && ops[i].e.sym)1118 if ((v & (OP_IM8 | OP_IM8S | OP_IM16)) && ops[i].e.sym)
1119 tcc_error("cannot relocate");1119 tcc_error(S, "cannot relocate");
1120 1120
1121 if (v & (OP_IM8 | OP_IM8S)) {1121 if (v & (OP_IM8 | OP_IM8S)) {
1122 g(ops[i].e.v);1122 g(S, ops[i].e.v);
1123 } else if (v & OP_IM16) {1123 } else if (v & OP_IM16) {
1124 gen_le16(ops[i].e.v);1124 gen_le16(S, ops[i].e.v);
1125#ifdef TCC_TARGET_X86_641125#ifdef TCC_TARGET_X86_64
1126 } else if (v & OP_IM64) {1126 } else if (v & OP_IM64) {
1127 gen_expr64(&ops[i].e);1127 gen_expr64(S, &ops[i].e);
1128#endif1128#endif
1129 } else if (pa->op_type[i] == OPT_DISP || pa->op_type[i] == OPT_DISP8) {1129 } else if (pa->op_type[i] == OPT_DISP || pa->op_type[i] == OPT_DISP8) {
1130 gen_disp32(&ops[i].e);1130 gen_disp32(S, &ops[i].e);
1131 } else {1131 } else {
1132 gen_expr32(&ops[i].e);1132 gen_expr32(S, &ops[i].e);
1133 }1133 }
1134 }1134 }
1135 }1135 }
1136 1136
1137 /* after immediate operands, adjust pc-relative address */1137 /* after immediate operands, adjust pc-relative address */
1138 if (pc)1138 if (pc)
1139 add32le(cur_text_section->data + pc - 4, pc - ind);1139 add32le(cur_text_section->data + pc - 4, pc - S->tccgen_ind);
1140}1140}
1141 1141
1142/* return the constraint priority (we allocate first the lowest1142/* return the constraint priority (we allocate first the lowest
1143 numbered constraints) */1143 numbered constraints) */
1144static inline int constraint_priority(const char *str)1144static inline int constraint_priority(TCCState* S, const char *str)
1145{1145{
1146 int priority, c, pr;1146 int priority, c, pr;
1147 1147
@@ -1182,7 +1182,7 @@ static inline int constraint_priority(const char *str) · 34 unmodified lines
1182 pr = 4;1182 pr = 4;
1183 break;1183 break;
1184 default:1184 default:
1185 tcc_error("unknown constraint '%c'", c);1185 tcc_error(S, "unknown constraint '%c'", c);
1186 pr = 0;1186 pr = 0;
1187 }1187 }
1188 if (pr > priority)1188 if (pr > priority)
@@ -1200,19 +1200,19 @@ static const char *skip_constraint_modifiers(const char *p) · 11 unmodified lines
1200 1200
1201/* If T (a token) is of the form "%reg" returns the register1201/* If T (a token) is of the form "%reg" returns the register
1202 number and type, otherwise return -1. */1202 number and type, otherwise return -1. */
1203ST_FUNC int asm_parse_regvar (int t)1203ST_FUNC int asm_parse_regvar (TCCState* S, int t)
1204{1204{
1205 const char *s;1205 const char *s;
1206 Operand op;1206 Operand op;
1207 if (t < TOK_IDENT || (t & SYM_FIELD))1207 if (t < TOK_IDENT || (t & SYM_FIELD))
1208 return -1;1208 return -1;
1209 s = table_ident[t - TOK_IDENT]->str;1209 s = S->tccpp_table_ident[t - TOK_IDENT]->str;
1210 if (s[0] != '%')1210 if (s[0] != '%')
1211 return -1;1211 return -1;
1212 t = tok_alloc_const(s + 1);1212 t = tok_alloc_const(S, s + 1);
1213 unget_tok(t);1213 unget_tok(S, t);
1214 unget_tok('%');1214 unget_tok(S, '%');
1215 parse_operand(tcc_state, &op);1215 parse_operand(S, &op);
1216 /* Accept only integer regs for now. */1216 /* Accept only integer regs for now. */
1217 if (op.type & OP_REG)1217 if (op.type & OP_REG)
1218 return op.reg;1218 return op.reg;
@@ -1225,7 +1225,7 @@ ST_FUNC int asm_parse_regvar (int t) · 6 unmodified lines
1225 1225
1226#define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask)1226#define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask)
1227 1227
1228ST_FUNC void asm_compute_constraints(ASMOperand *operands,1228ST_FUNC void asm_compute_constraints(TCCState* S, ASMOperand *operands,
1229 int nb_operands, int nb_outputs,1229 int nb_operands, int nb_outputs,
1230 const uint8_t *clobber_regs,1230 const uint8_t *clobber_regs,
1231 int *pout_reg)1231 int *pout_reg)
@@ -1253,13 +1253,13 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 21 unmodified lines
1253 str = skip_constraint_modifiers(str);1253 str = skip_constraint_modifiers(str);
1254 if (isnum(*str) || *str == '[') {1254 if (isnum(*str) || *str == '[') {
1255 /* this is a reference to another constraint */1255 /* this is a reference to another constraint */
1256 k = find_constraint(operands, nb_operands, str, NULL);1256 k = find_constraint(S, operands, nb_operands, str, NULL);
1257 if ((unsigned)k >= i || i < nb_outputs)1257 if ((unsigned)k >= i || i < nb_outputs)
1258 tcc_error("invalid reference in constraint %d ('%s')",1258 tcc_error(S, "invalid reference in constraint %d ('%s')",
1259 i, str);1259 i, str);
1260 op->ref_index = k;1260 op->ref_index = k;
1261 if (operands[k].input_index >= 0)1261 if (operands[k].input_index >= 0)
1262 tcc_error("cannot reference twice the same operand");1262 tcc_error(S, "cannot reference twice the same operand");
1263 operands[k].input_index = i;1263 operands[k].input_index = i;
1264 op->priority = 5;1264 op->priority = 5;
1265 } else if ((op->vt->r & VT_VALMASK) == VT_LOCAL1265 } else if ((op->vt->r & VT_VALMASK) == VT_LOCAL
@@ -1268,7 +1268,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 2 unmodified lines
1268 op->priority = 1;1268 op->priority = 1;
1269 op->reg = reg;1269 op->reg = reg;
1270 } else {1270 } else {
1271 op->priority = constraint_priority(str);1271 op->priority = constraint_priority(S, str);
1272 }1272 }
1273 }1273 }
1274 1274
@@ -1316,7 +1316,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 41 unmodified lines
1316 }1316 }
1317 if (op->reg >= 0) {1317 if (op->reg >= 0) {
1318 if (is_reg_allocated(op->reg))1318 if (is_reg_allocated(op->reg))
1319 tcc_error("asm regvar requests register that's taken already");1319 tcc_error(S, "asm regvar requests register that's taken already");
1320 reg = op->reg;1320 reg = op->reg;
1321 goto reg_found;1321 goto reg_found;
1322 }1322 }
@@ -1330,7 +1330,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 7 unmodified lines
1330 /* FALL THRU */1330 /* FALL THRU */
1331 case '&':1331 case '&':
1332 if (j >= nb_outputs)1332 if (j >= nb_outputs)
1333 tcc_error("'%c' modifier can only be applied to outputs", c);1333 tcc_error(S, "'%c' modifier can only be applied to outputs", c);
1334 reg_mask = REG_IN_MASK | REG_OUT_MASK;1334 reg_mask = REG_IN_MASK | REG_OUT_MASK;
1335 goto try_next;1335 goto try_next;
1336 case 'A':1336 case 'A':
@@ -1424,7 +1424,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 87 unmodified lines
1424 }1424 }
1425 break;1425 break;
1426 default:1426 default:
1427 tcc_error("asm constraint %d ('%s') could not be satisfied",1427 tcc_error(S, "asm constraint %d ('%s') could not be satisfied",
1428 j, op->constraint);1428 j, op->constraint);
1429 break;1429 break;
1430 }1430 }
@@ -1447,7 +1447,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 16 unmodified lines
1447 if (!(regs_allocated[reg] & REG_OUT_MASK))1447 if (!(regs_allocated[reg] & REG_OUT_MASK))
1448 goto reg_found2;1448 goto reg_found2;
1449 }1449 }
1450 tcc_error("could not find free output register for reloading");1450 tcc_error(S, "could not find free output register for reloading");
1451 reg_found2:1451 reg_found2:
1452 *pout_reg = reg;1452 *pout_reg = reg;
1453 break;1453 break;
@@ -1461,7 +1461,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 7 unmodified lines
1461 op = &operands[j];1461 op = &operands[j];
1462 printf("%%%d [%s]: \"%s\" r=0x%04x reg=%d\n",1462 printf("%%%d [%s]: \"%s\" r=0x%04x reg=%d\n",
1463 j,1463 j,
1464 op->id ? get_tok_str(op->id, NULL) : "",1464 op->id ? get_tok_str(S, op->id, NULL) : "",
1465 op->constraint,1465 op->constraint,
1466 op->vt->r,1466 op->vt->r,
1467 op->reg);1467 op->reg);
@@ -1471,7 +1471,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 3 unmodified lines
1471#endif1471#endif
1472}1472}
1473 1473
1474ST_FUNC void subst_asm_operand(CString *add_str,1474ST_FUNC void subst_asm_operand(TCCState* S, CString *add_str,
1475 SValue *sv, int modifier)1475 SValue *sv, int modifier)
1476{1476{
1477 int r, reg, size, val;1477 int r, reg, size, val;
@@ -1481,33 +1481,33 @@ ST_FUNC void subst_asm_operand(CString *add_str, · 3 unmodified lines
1481 if ((r & VT_VALMASK) == VT_CONST) {1481 if ((r & VT_VALMASK) == VT_CONST) {
1482 if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n' &&1482 if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n' &&
1483 modifier != 'P')1483 modifier != 'P')
1484 cstr_ccat(add_str, '$');1484 cstr_ccat(S, add_str, '$');
1485 if (r & VT_SYM) {1485 if (r & VT_SYM) {
1486 const char *name = get_tok_str(sv->sym->v, NULL);1486 const char *name = get_tok_str(S, sv->sym->v, NULL);
1487 if (sv->sym->v >= SYM_FIRST_ANOM) {1487 if (sv->sym->v >= SYM_FIRST_ANOM) {
1488 /* In case of anonymous symbols ("L.42", used1488 /* In case of anonymous symbols ("L.42", used
1489 for static data labels) we can't find them1489 for static data labels) we can't find them
1490 in the C symbol table when later looking up1490 in the C symbol table when later looking up
1491 this name. So enter them now into the asm label1491 this name. So enter them now into the asm label
1492 list when we still know the symbol. */1492 list when we still know the symbol. */
1493 get_asm_sym(tok_alloc_const(name), sv->sym);1493 get_asm_sym(S, tok_alloc_const(S, name), sv->sym);
1494 }1494 }
1495 if (tcc_state->leading_underscore)1495 if (S->leading_underscore)
1496 cstr_ccat(add_str, '_');1496 cstr_ccat(S, add_str, '_');
1497 cstr_cat(add_str, name, -1);1497 cstr_cat(S, add_str, name, -1);
1498 if ((uint32_t)sv->c.i == 0)1498 if ((uint32_t)sv->c.i == 0)
1499 goto no_offset;1499 goto no_offset;
1500 cstr_ccat(add_str, '+');1500 cstr_ccat(S, add_str, '+');
1501 }1501 }
1502 val = sv->c.i;1502 val = sv->c.i;
1503 if (modifier == 'n')1503 if (modifier == 'n')
1504 val = -val;1504 val = -val;
1505 snprintf(buf, sizeof(buf), "%d", (int)sv->c.i);1505 snprintf(buf, sizeof(buf), "%d", (int)sv->c.i);
1506 cstr_cat(add_str, buf, -1);1506 cstr_cat(S, add_str, buf, -1);
1507 no_offset:;1507 no_offset:;
1508#ifdef TCC_TARGET_X86_641508#ifdef TCC_TARGET_X86_64
1509 if (r & VT_LVAL)1509 if (r & VT_LVAL)
1510 cstr_cat(add_str, "(%rip)", -1);1510 cstr_cat(S, add_str, "(%rip)", -1);
1511#endif1511#endif
1512 } else if ((r & VT_VALMASK) == VT_LOCAL) {1512 } else if ((r & VT_VALMASK) == VT_LOCAL) {
1513#ifdef TCC_TARGET_X86_641513#ifdef TCC_TARGET_X86_64
@@ -1515,24 +1515,24 @@ ST_FUNC void subst_asm_operand(CString *add_str, · 1 unmodified line
1515#else1515#else
1516 snprintf(buf, sizeof(buf), "%d(%%ebp)", (int)sv->c.i);1516 snprintf(buf, sizeof(buf), "%d(%%ebp)", (int)sv->c.i);
1517#endif1517#endif
1518 cstr_cat(add_str, buf, -1);1518 cstr_cat(S, add_str, buf, -1);
1519 } else if (r & VT_LVAL) {1519 } else if (r & VT_LVAL) {
1520 reg = r & VT_VALMASK;1520 reg = r & VT_VALMASK;
1521 if (reg >= VT_CONST)1521 if (reg >= VT_CONST)
1522 tcc_internal_error("");1522 tcc_internal_error(S, "");
1523 snprintf(buf, sizeof(buf), "(%%%s)",1523 snprintf(buf, sizeof(buf), "(%%%s)",
1524#ifdef TCC_TARGET_X86_641524#ifdef TCC_TARGET_X86_64
1525 get_tok_str(TOK_ASM_rax + reg, NULL)1525 get_tok_str(S, TOK_ASM_rax + reg, NULL)
1526#else1526#else
1527 get_tok_str(TOK_ASM_eax + reg, NULL)1527 get_tok_str(S, TOK_ASM_eax + reg, NULL)
1528#endif1528#endif
1529 );1529 );
1530 cstr_cat(add_str, buf, -1);1530 cstr_cat(S, add_str, buf, -1);
1531 } else {1531 } else {
1532 /* register case */1532 /* register case */
1533 reg = r & VT_VALMASK;1533 reg = r & VT_VALMASK;
1534 if (reg >= VT_CONST)1534 if (reg >= VT_CONST)
1535 tcc_internal_error("");1535 tcc_internal_error(S, "");
1536 1536
1537 /* choose register operand size */1537 /* choose register operand size */
1538 if ((sv->type.t & VT_BTYPE) == VT_BYTE ||1538 if ((sv->type.t & VT_BTYPE) == VT_BYTE ||
@@ -1552,11 +1552,11 @@ ST_FUNC void subst_asm_operand(CString *add_str, · 13 unmodified lines
1552 1552
1553 if (modifier == 'b') {1553 if (modifier == 'b') {
1554 if (reg >= 4)1554 if (reg >= 4)
1555 tcc_error("cannot use byte register");1555 tcc_error(S, "cannot use byte register");
1556 size = 1;1556 size = 1;
1557 } else if (modifier == 'h') {1557 } else if (modifier == 'h') {
1558 if (reg >= 4)1558 if (reg >= 4)
1559 tcc_error("cannot use byte register");1559 tcc_error(S, "cannot use byte register");
1560 size = -1;1560 size = -1;
1561 } else if (modifier == 'w') {1561 } else if (modifier == 'w') {
1562 size = 2;1562 size = 2;
@@ -1587,13 +1587,13 @@ ST_FUNC void subst_asm_operand(CString *add_str, · 24 unmodified lines
1587 break;1587 break;
1588#endif1588#endif
1589 }1589 }
1590 snprintf(buf, sizeof(buf), "%%%s", get_tok_str(reg, NULL));1590 snprintf(buf, sizeof(buf), "%%%s", get_tok_str(S, reg, NULL));
1591 cstr_cat(add_str, buf, -1);1591 cstr_cat(S, add_str, buf, -1);
1592 }1592 }
1593}1593}
1594 1594
1595/* generate prolog and epilog code for asm statement */1595/* generate prolog and epilog code for asm statement */
1596ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,1596ST_FUNC void asm_gen_code(TCCState* S, ASMOperand *operands, int nb_operands,
1597 int nb_outputs, int is_output,1597 int nb_outputs, int is_output,
1598 uint8_t *clobber_regs,1598 uint8_t *clobber_regs,
1599 int out_reg)1599 int out_reg)
@@ -1627,8 +1627,8 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, · 27 unmodified lines
1627 reg = reg_saved[i];1627 reg = reg_saved[i];
1628 if (regs_allocated[reg]) {1628 if (regs_allocated[reg]) {
1629 if (reg >= 8)1629 if (reg >= 8)
1630 g(0x41), reg-=8;1630 g(S, 0x41), reg-=8;
1631 g(0x50 + reg);1631 g(S, 0x50 + reg);
1632 }1632 }
1633 }1633 }
1634 1634
@@ -1644,15 +1644,15 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, · 9 unmodified lines
1644 sv = *op->vt;1644 sv = *op->vt;
1645 sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL | VT_LVAL;1645 sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL | VT_LVAL;
1646 sv.type.t = VT_PTR;1646 sv.type.t = VT_PTR;
1647 load(op->reg, &sv);1647 load(S, op->reg, &sv);
1648 } else if (i >= nb_outputs || op->is_rw) {1648 } else if (i >= nb_outputs || op->is_rw) {
1649 /* load value in register */1649 /* load value in register */
1650 load(op->reg, op->vt);1650 load(S, op->reg, op->vt);
1651 if (op->is_llong) {1651 if (op->is_llong) {
1652 SValue sv;1652 SValue sv;
1653 sv = *op->vt;1653 sv = *op->vt;
1654 sv.c.i += 4;1654 sv.c.i += 4;
1655 load(TREG_XDX, &sv);1655 load(S, TREG_XDX, &sv);
1656 }1656 }
1657 }1657 }
1658 }1658 }
@@ -1668,19 +1668,19 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, · 9 unmodified lines
1668 sv = *op->vt;1668 sv = *op->vt;
1669 sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL;1669 sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL;
1670 sv.type.t = VT_PTR;1670 sv.type.t = VT_PTR;
1671 load(out_reg, &sv);1671 load(S, out_reg, &sv);
1672 1672
1673 sv = *op->vt;1673 sv = *op->vt;
1674 sv.r = (sv.r & ~VT_VALMASK) | out_reg;1674 sv.r = (sv.r & ~VT_VALMASK) | out_reg;
1675 store(op->reg, &sv);1675 store(S, op->reg, &sv);
1676 }1676 }
1677 } else {1677 } else {
1678 store(op->reg, op->vt);1678 store(S, op->reg, op->vt);
1679 if (op->is_llong) {1679 if (op->is_llong) {
1680 SValue sv;1680 SValue sv;
1681 sv = *op->vt;1681 sv = *op->vt;
1682 sv.c.i += 4;1682 sv.c.i += 4;
1683 store(TREG_XDX, &sv);1683 store(S, TREG_XDX, &sv);
1684 }1684 }
1685 }1685 }
1686 }1686 }
@@ -1690,14 +1690,14 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, · 3 unmodified lines
1690 reg = reg_saved[i];1690 reg = reg_saved[i];
1691 if (regs_allocated[reg]) {1691 if (regs_allocated[reg]) {
1692 if (reg >= 8)1692 if (reg >= 8)
1693 g(0x41), reg-=8;1693 g(S, 0x41), reg-=8;
1694 g(0x58 + reg);1694 g(S, 0x58 + reg);
1695 }1695 }
1696 }1696 }
1697 }1697 }
1698}1698}
1699 1699
1700ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str)1700ST_FUNC void asm_clobber(TCCState* S, uint8_t *clobber_regs, const char *str)
1701{1701{
1702 int reg;1702 int reg;
1703#ifdef TCC_TARGET_X86_641703#ifdef TCC_TARGET_X86_64
@@ -1708,7 +1708,7 @@ ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str) · 4 unmodified lines
1708 !strcmp(str, "cc") ||1708 !strcmp(str, "cc") ||
1709 !strcmp(str, "flags"))1709 !strcmp(str, "flags"))
1710 return;1710 return;
1711 reg = tok_alloc_const(str);1711 reg = tok_alloc_const(S, str);
1712 if (reg >= TOK_ASM_eax && reg <= TOK_ASM_edi) {1712 if (reg >= TOK_ASM_eax && reg <= TOK_ASM_edi) {
1713 reg -= TOK_ASM_eax;1713 reg -= TOK_ASM_eax;
1714 } else if (reg >= TOK_ASM_ax && reg <= TOK_ASM_di) {1714 } else if (reg >= TOK_ASM_ax && reg <= TOK_ASM_di) {
@@ -1716,11 +1716,11 @@ ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str) · 1 unmodified line
1716#ifdef TCC_TARGET_X86_641716#ifdef TCC_TARGET_X86_64
1717 } else if (reg >= TOK_ASM_rax && reg <= TOK_ASM_rdi) {1717 } else if (reg >= TOK_ASM_rax && reg <= TOK_ASM_rdi) {
1718 reg -= TOK_ASM_rax;1718 reg -= TOK_ASM_rax;
1719 } else if ((reg = asm_parse_numeric_reg(reg, &type)) >= 0) {1719 } else if ((reg = asm_parse_numeric_reg(S, reg, &type)) >= 0) {
1720 ;1720 ;
1721#endif1721#endif
1722 } else {1722 } else {
1723 tcc_error("invalid clobber register '%s'", str);1723 tcc_error(S, "invalid clobber register '%s'", str);
1724 }1724 }
1725 clobber_regs[reg] = 1;1725 clobber_regs[reg] = 1;
1726}1726}
i386-gen.c+365−368
@@ -100,50 +100,47 @@ ST_DATA const int reg_classes[NB_REGS] = { · 99 unmodified lines
100static unsigned long func_sub_sp_offset;100static unsigned long func_sub_sp_offset;
101static int func_ret_sub;101static int func_ret_sub;
102#ifdef CONFIG_TCC_BCHECK102#ifdef CONFIG_TCC_BCHECK
103static addr_t func_bound_offset;103static void gen_bounds_prolog(TCCState* S);
104static unsigned long func_bound_ind;104static void gen_bounds_epilog(TCCState* S);
105ST_DATA int func_bound_add_epilog;
106static void gen_bounds_prolog(void);
107static void gen_bounds_epilog(void);
108#endif105#endif
109 106
110/* XXX: make it faster ? */107/* XXX: make it faster ? */
111ST_FUNC void g(int c)108ST_FUNC void g(TCCState* S, int c)
112{109{
113 int ind1;110 int ind1;
114 if (nocode_wanted)111 if (S->tccgen_nocode_wanted)
115 return;112 return;
116 ind1 = ind + 1;113 ind1 = S->tccgen_ind + 1;
117 if (ind1 > cur_text_section->data_allocated)114 if (ind1 > cur_text_section->data_allocated)
118 section_realloc(cur_text_section, ind1);115 section_realloc(S, cur_text_section, ind1);
119 cur_text_section->data[ind] = c;116 cur_text_section->data[S->tccgen_ind] = c;
120 ind = ind1;117 S->tccgen_ind = ind1;
121}118}
122 119
123ST_FUNC void o(unsigned int c)120ST_FUNC void o(TCCState* S, unsigned int c)
124{121{
125 while (c) {122 while (c) {
126 g(c);123 g(S, c);
127 c = c >> 8;124 c = c >> 8;
128 }125 }
129}126}
130 127
131ST_FUNC void gen_le16(int v)128ST_FUNC void gen_le16(TCCState* S, int v)
132{129{
133 g(v);130 g(S, v);
134 g(v >> 8);131 g(S, v >> 8);
135}132}
136 133
137ST_FUNC void gen_le32(int c)134ST_FUNC void gen_le32(TCCState* S, int c)
138{135{
139 g(c);136 g(S, c);
140 g(c >> 8);137 g(S, c >> 8);
141 g(c >> 16);138 g(S, c >> 16);
142 g(c >> 24);139 g(S, c >> 24);
143}140}
144 141
145/* output a symbol and patch all calls to it */142/* output a symbol and patch all calls to it */
146ST_FUNC void gsym_addr(int t, int a)143ST_FUNC void gsym_addr(TCCState* S, int t, int a)
147{144{
148 while (t) {145 while (t) {
149 unsigned char *ptr = cur_text_section->data + t;146 unsigned char *ptr = cur_text_section->data + t;
@@ -154,73 +151,73 @@ ST_FUNC void gsym_addr(int t, int a) · 4 unmodified lines
154}151}
155 152
156/* instruction + 4 bytes data. Return the address of the data */153/* instruction + 4 bytes data. Return the address of the data */
157static int oad(int c, int s)154static int oad(TCCState* S, int c, int s)
158{155{
159 int t;156 int t;
160 if (nocode_wanted)157 if (S->tccgen_nocode_wanted)
161 return s;158 return s;
162 o(c);159 o(S, c);
163 t = ind;160 t = S->tccgen_ind;
164 gen_le32(s);161 gen_le32(S, s);
165 return t;162 return t;
166}163}
167 164
168ST_FUNC void gen_fill_nops(int bytes)165ST_FUNC void gen_fill_nops(TCCState* S, int bytes)
169{166{
170 while (bytes--)167 while (bytes--)
171 g(0x90);168 g(S, 0x90);
172}169}
173 170
174/* generate jmp to a label */171/* generate jmp to a label */
175#define gjmp2(instr,lbl) oad(instr,lbl)172#define gjmp2(s, instr,lbl) oad(s, instr,lbl)
176 173
177/* output constant with relocation if 'r & VT_SYM' is true */174/* output constant with relocation if 'r & VT_SYM' is true */
178ST_FUNC void gen_addr32(int r, Sym *sym, int c)175ST_FUNC void gen_addr32(TCCState* S, int r, Sym *sym, int c)
179{176{
180 if (r & VT_SYM)177 if (r & VT_SYM)
181 greloc(cur_text_section, sym, ind, R_386_32);178 greloc(S, cur_text_section, sym, S->tccgen_ind, R_386_32);
182 gen_le32(c);179 gen_le32(S, c);
183}180}
184 181
185ST_FUNC void gen_addrpc32(int r, Sym *sym, int c)182ST_FUNC void gen_addrpc32(TCCState* S, int r, Sym *sym, int c)
186{183{
187 if (r & VT_SYM)184 if (r & VT_SYM)
188 greloc(cur_text_section, sym, ind, R_386_PC32);185 greloc(S, cur_text_section, sym, S->tccgen_ind, R_386_PC32);
189 gen_le32(c - 4);186 gen_le32(S, c - 4);
190}187}
191 188
192/* generate a modrm reference. 'op_reg' contains the additional 3189/* generate a modrm reference. 'op_reg' contains the additional 3
193 opcode bits */190 opcode bits */
194static void gen_modrm(int op_reg, int r, Sym *sym, int c)191static void gen_modrm(TCCState* S, int op_reg, int r, Sym *sym, int c)
195{192{
196 op_reg = op_reg << 3;193 op_reg = op_reg << 3;
197 if ((r & VT_VALMASK) == VT_CONST) {194 if ((r & VT_VALMASK) == VT_CONST) {
198 /* constant memory reference */195 /* constant memory reference */
199 o(0x05 | op_reg);196 o(S, 0x05 | op_reg);
200 gen_addr32(r, sym, c);197 gen_addr32(S, r, sym, c);
201 } else if ((r & VT_VALMASK) == VT_LOCAL) {198 } else if ((r & VT_VALMASK) == VT_LOCAL) {
202 /* currently, we use only ebp as base */199 /* currently, we use only ebp as base */
203 if (c == (char)c) {200 if (c == (char)c) {
204 /* short reference */201 /* short reference */
205 o(0x45 | op_reg);202 o(S, 0x45 | op_reg);
206 g(c);203 g(S, c);
207 } else {204 } else {
208 oad(0x85 | op_reg, c);205 oad(S, 0x85 | op_reg, c);
209 }206 }
210 } else {207 } else {
211 g(0x00 | op_reg | (r & VT_VALMASK));208 g(S, 0x00 | op_reg | (r & VT_VALMASK));
212 }209 }
213}210}
214 211
215/* load 'r' from value 'sv' */212/* load 'r' from value 'sv' */
216ST_FUNC void load(int r, SValue *sv)213ST_FUNC void load(TCCState* S, int r, SValue *sv)
217{214{
218 int v, t, ft, fc, fr;215 int v, t, ft, fc, fr;
219 SValue v1;216 SValue v1;
220 217
221#ifdef TCC_TARGET_PE218#ifdef TCC_TARGET_PE
222 SValue v2;219 SValue v2;
223 sv = pe_getimport(sv, &v2);220 sv = pe_getimport(S, sv, &v2);
224#endif221#endif
225 222
226 fr = sv->r;223 fr = sv->r;
@@ -238,68 +235,68 @@ ST_FUNC void load(int r, SValue *sv) · 11 unmodified lines
238 v1.sym = NULL;235 v1.sym = NULL;
239 fr = r;236 fr = r;
240 if (!(reg_classes[fr] & RC_INT))237 if (!(reg_classes[fr] & RC_INT))
241 fr = get_reg(RC_INT);238 fr = get_reg(S, RC_INT);
242 load(fr, &v1);239 load(S, fr, &v1);
243 }240 }
244 if ((ft & VT_BTYPE) == VT_FLOAT) {241 if ((ft & VT_BTYPE) == VT_FLOAT) {
245 o(0xd9); /* flds */242 o(S, 0xd9); /* flds */
246 r = 0;243 r = 0;
247 } else if ((ft & VT_BTYPE) == VT_DOUBLE) {244 } else if ((ft & VT_BTYPE) == VT_DOUBLE) {
248 o(0xdd); /* fldl */245 o(S, 0xdd); /* fldl */
249 r = 0;246 r = 0;
250 } else if ((ft & VT_BTYPE) == VT_LDOUBLE) {247 } else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
251 o(0xdb); /* fldt */248 o(S, 0xdb); /* fldt */
252 r = 5;249 r = 5;
253 } else if ((ft & VT_TYPE) == VT_BYTE || (ft & VT_TYPE) == VT_BOOL) {250 } else if ((ft & VT_TYPE) == VT_BYTE || (ft & VT_TYPE) == VT_BOOL) {
254 o(0xbe0f); /* movsbl */251 o(S, 0xbe0f); /* movsbl */
255 } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {252 } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
256 o(0xb60f); /* movzbl */253 o(S, 0xb60f); /* movzbl */
257 } else if ((ft & VT_TYPE) == VT_SHORT) {254 } else if ((ft & VT_TYPE) == VT_SHORT) {
258 o(0xbf0f); /* movswl */255 o(S, 0xbf0f); /* movswl */
259 } else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) {256 } else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) {
260 o(0xb70f); /* movzwl */257 o(S, 0xb70f); /* movzwl */
261 } else {258 } else {
262 o(0x8b); /* movl */259 o(S, 0x8b); /* movl */
263 }260 }
264 gen_modrm(r, fr, sv->sym, fc);261 gen_modrm(S, r, fr, sv->sym, fc);
265 } else {262 } else {
266 if (v == VT_CONST) {263 if (v == VT_CONST) {
267 o(0xb8 + r); /* mov $xx, r */264 o(S, 0xb8 + r); /* mov $xx, r */
268 gen_addr32(fr, sv->sym, fc);265 gen_addr32(S, fr, sv->sym, fc);
269 } else if (v == VT_LOCAL) {266 } else if (v == VT_LOCAL) {
270 if (fc) {267 if (fc) {
271 o(0x8d); /* lea xxx(%ebp), r */268 o(S, 0x8d); /* lea xxx(%ebp), r */
272 gen_modrm(r, VT_LOCAL, sv->sym, fc);269 gen_modrm(S, r, VT_LOCAL, sv->sym, fc);
273 } else {270 } else {
274 o(0x89);271 o(S, 0x89);
275 o(0xe8 + r); /* mov %ebp, r */272 o(S, 0xe8 + r); /* mov %ebp, r */
276 }273 }
277 } else if (v == VT_CMP) {274 } else if (v == VT_CMP) {
278 o(0x0f); /* setxx %br */275 o(S, 0x0f); /* setxx %br */
279 o(fc);276 o(S, fc);
280 o(0xc0 + r);277 o(S, 0xc0 + r);
281 o(0xc0b60f + r * 0x90000); /* movzbl %al, %eax */278 o(S, 0xc0b60f + r * 0x90000); /* movzbl %al, %eax */
282 } else if (v == VT_JMP || v == VT_JMPI) {279 } else if (v == VT_JMP || v == VT_JMPI) {
283 t = v & 1;280 t = v & 1;
284 oad(0xb8 + r, t); /* mov $1, r */281 oad(S, 0xb8 + r, t); /* mov $1, r */
285 o(0x05eb); /* jmp after */282 o(S, 0x05eb); /* jmp after */
286 gsym(fc);283 gsym(S, fc);
287 oad(0xb8 + r, t ^ 1); /* mov $0, r */284 oad(S, 0xb8 + r, t ^ 1); /* mov $0, r */
288 } else if (v != r) {285 } else if (v != r) {
289 o(0x89);286 o(S, 0x89);
290 o(0xc0 + r + v * 8); /* mov v, r */287 o(S, 0xc0 + r + v * 8); /* mov v, r */
291 }288 }
292 }289 }
293}290}
294 291
295/* store register 'r' in lvalue 'v' */292/* store register 'r' in lvalue 'v' */
296ST_FUNC void store(int r, SValue *v)293ST_FUNC void store(TCCState* S, int r, SValue *v)
297{294{
298 int fr, bt, ft, fc;295 int fr, bt, ft, fc;
299 296
300#ifdef TCC_TARGET_PE297#ifdef TCC_TARGET_PE
301 SValue v2;298 SValue v2;
302 v = pe_getimport(v, &v2);299 v = pe_getimport(S, v, &v2);
303#endif300#endif
304 301
305 ft = v->type.t;302 ft = v->type.t;
@@ -309,66 +306,66 @@ ST_FUNC void store(int r, SValue *v) · 3 unmodified lines
309 bt = ft & VT_BTYPE;306 bt = ft & VT_BTYPE;
310 /* XXX: incorrect if float reg to reg */307 /* XXX: incorrect if float reg to reg */
311 if (bt == VT_FLOAT) {308 if (bt == VT_FLOAT) {
312 o(0xd9); /* fsts */309 o(S, 0xd9); /* fsts */
313 r = 2;310 r = 2;
314 } else if (bt == VT_DOUBLE) {311 } else if (bt == VT_DOUBLE) {
315 o(0xdd); /* fstpl */312 o(S, 0xdd); /* fstpl */
316 r = 2;313 r = 2;
317 } else if (bt == VT_LDOUBLE) {314 } else if (bt == VT_LDOUBLE) {
318 o(0xc0d9); /* fld %st(0) */315 o(S, 0xc0d9); /* fld %st(0) */
319 o(0xdb); /* fstpt */316 o(S, 0xdb); /* fstpt */
320 r = 7;317 r = 7;
321 } else {318 } else {
322 if (bt == VT_SHORT)319 if (bt == VT_SHORT)
323 o(0x66);320 o(S, 0x66);
324 if (bt == VT_BYTE || bt == VT_BOOL)321 if (bt == VT_BYTE || bt == VT_BOOL)
325 o(0x88);322 o(S, 0x88);
326 else323 else
327 o(0x89);324 o(S, 0x89);
328 }325 }
329 if (fr == VT_CONST ||326 if (fr == VT_CONST ||
330 fr == VT_LOCAL ||327 fr == VT_LOCAL ||
331 (v->r & VT_LVAL)) {328 (v->r & VT_LVAL)) {
332 gen_modrm(r, v->r, v->sym, fc);329 gen_modrm(S, r, v->r, v->sym, fc);
333 } else if (fr != r) {330 } else if (fr != r) {
334 o(0xc0 + fr + r * 8); /* mov r, fr */331 o(S, 0xc0 + fr + r * 8); /* mov r, fr */
335 }332 }
336}333}
337 334
338static void gadd_sp(int val)335static void gadd_sp(TCCState* S, int val)
339{336{
340 if (val == (char)val) {337 if (val == (char)val) {
341 o(0xc483);338 o(S, 0xc483);
342 g(val);339 g(S, val);
343 } else {340 } else {
344 oad(0xc481, val); /* add $xxx, %esp */341 oad(S, 0xc481, val); /* add $xxx, %esp */
345 }342 }
346}343}
347 344
348#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_PE345#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_PE
349static void gen_static_call(int v)346static void gen_static_call(TCCState* S, int v)
350{347{
351 Sym *sym;348 Sym *sym;
352 349
353 sym = external_helper_sym(v);350 sym = external_helper_sym(S, v);
354 oad(0xe8, -4);351 oad(S, 0xe8, -4);
355 greloc(cur_text_section, sym, ind-4, R_386_PC32);352 greloc(S, cur_text_section, sym, S->tccgen_ind-4, R_386_PC32);
356}353}
357#endif354#endif
358 355
359/* 'is_jmp' is '1' if it is a jump */356/* 'is_jmp' is '1' if it is a jump */
360static void gcall_or_jmp(int is_jmp)357static void gcall_or_jmp(TCCState* S, int is_jmp)
361{358{
362 int r;359 int r;
363 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (vtop->r & VT_SYM)) {360 if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (S->tccgen_vtop->r & VT_SYM)) {
364 /* constant and relocation case */361 /* constant and relocation case */
365 greloc(cur_text_section, vtop->sym, ind + 1, R_386_PC32);362 greloc(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind + 1, R_386_PC32);
366 oad(0xe8 + is_jmp, vtop->c.i - 4); /* call/jmp im */363 oad(S, 0xe8 + is_jmp, S->tccgen_vtop->c.i - 4); /* call/jmp im */
367 } else {364 } else {
368 /* otherwise, indirect call */365 /* otherwise, indirect call */
369 r = gv(RC_INT);366 r = gv(S, RC_INT);
370 o(0xff); /* call/jmp *r */367 o(S, 0xff); /* call/jmp *r */
371 o(0xd0 + r + (is_jmp << 4));368 o(S, 0xd0 + r + (is_jmp << 4));
372 }369 }
373}370}
374 371
@@ -405,75 +402,75 @@ ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int · 30 unmodified lines
405/* Generate function call. The function address is pushed first, then402/* Generate function call. The function address is pushed first, then
406 all the parameters in call order. This functions pops all the403 all the parameters in call order. This functions pops all the
407 parameters and the function address. */404 parameters and the function address. */
408ST_FUNC void gfunc_call(int nb_args)405ST_FUNC void gfunc_call(TCCState* S, int nb_args)
409{406{
410 int size, align, r, args_size, i, func_call;407 int size, align, r, args_size, i, func_call;
411 Sym *func_sym;408 Sym *func_sym;
412 409
413#ifdef CONFIG_TCC_BCHECK410#ifdef CONFIG_TCC_BCHECK
414 if (tcc_state->do_bounds_check)411 if (S->do_bounds_check)
415 gbound_args(nb_args);412 gbound_args(S, nb_args);
416#endif413#endif
417 414
418 args_size = 0;415 args_size = 0;
419 for(i = 0;i < nb_args; i++) {416 for(i = 0;i < nb_args; i++) {
420 if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {417 if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_STRUCT) {
421 size = type_size(&vtop->type, &align);418 size = type_size(&S->tccgen_vtop->type, &align);
422 /* align to stack align size */419 /* align to stack align size */
423 size = (size + 3) & ~3;420 size = (size + 3) & ~3;
424 /* allocate the necessary size on stack */421 /* allocate the necessary size on stack */
425#ifdef TCC_TARGET_PE422#ifdef TCC_TARGET_PE
426 if (size >= 4096) {423 if (size >= 4096) {
427 r = get_reg(RC_EAX);424 r = get_reg(S, RC_EAX);
428 oad(0x68, size); // push size425 oad(S, 0x68, size); // push size
429 /* cannot call normal 'alloca' with bound checking */426 /* cannot call normal 'alloca' with bound checking */
430 gen_static_call(tok_alloc_const("__alloca"));427 gen_static_call(S, tok_alloc_const(S, "__alloca"));
431 gadd_sp(4);428 gadd_sp(S, 4);
432 } else429 } else
433#endif430#endif
434 {431 {
435 oad(0xec81, size); /* sub $xxx, %esp */432 oad(S, 0xec81, size); /* sub $xxx, %esp */
436 /* generate structure store */433 /* generate structure store */
437 r = get_reg(RC_INT);434 r = get_reg(S, RC_INT);
438 o(0xe089 + (r << 8)); /* mov %esp, r */435 o(S, 0xe089 + (r << 8)); /* mov %esp, r */
439 }436 }
440 vset(&vtop->type, r | VT_LVAL, 0);437 vset(S, &S->tccgen_vtop->type, r | VT_LVAL, 0);
441 vswap();438 vswap(S);
442 vstore();439 vstore(S);
443 args_size += size;440 args_size += size;
444 } else if (is_float(vtop->type.t)) {441 } else if (is_float(S->tccgen_vtop->type.t)) {
445 gv(RC_FLOAT); /* only one float register */442 gv(S, RC_FLOAT); /* only one float register */
446 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT)443 if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_FLOAT)
447 size = 4;444 size = 4;
448 else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)445 else if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_DOUBLE)
449 size = 8;446 size = 8;
450 else447 else
451 size = 12;448 size = 12;
452 oad(0xec81, size); /* sub $xxx, %esp */449 oad(S, 0xec81, size); /* sub $xxx, %esp */
453 if (size == 12)450 if (size == 12)
454 o(0x7cdb);451 o(S, 0x7cdb);
455 else452 else
456 o(0x5cd9 + size - 4); /* fstp[s|l] 0(%esp) */453 o(S, 0x5cd9 + size - 4); /* fstp[s|l] 0(%esp) */
457 g(0x24);454 g(S, 0x24);
458 g(0x00);455 g(S, 0x00);
459 args_size += size;456 args_size += size;
460 } else {457 } else {
461 /* simple type (currently always same size) */458 /* simple type (currently always same size) */
462 /* XXX: implicit cast ? */459 /* XXX: implicit cast ? */
463 r = gv(RC_INT);460 r = gv(S, RC_INT);
464 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {461 if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG) {
465 size = 8;462 size = 8;
466 o(0x50 + vtop->r2); /* push r */463 o(S, 0x50 + S->tccgen_vtop->r2); /* push r */
467 } else {464 } else {
468 size = 4;465 size = 4;
469 }466 }
470 o(0x50 + r); /* push r */467 o(S, 0x50 + r); /* push r */
471 args_size += size;468 args_size += size;
472 }469 }
473 vtop--;470 S->tccgen_vtop--;
474 }471 }
475 save_regs(0); /* save used temporary registers */472 save_regs(S, 0); /* save used temporary registers */
476 func_sym = vtop->type.ref;473 func_sym = S->tccgen_vtop->type.ref;
477 func_call = func_sym->f.func_call;474 func_call = func_sym->f.func_call;
478 /* fast call case */475 /* fast call case */
479 if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) ||476 if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) ||
@@ -490,21 +487,21 @@ ST_FUNC void gfunc_call(int nb_args) · 10 unmodified lines
490 for(i = 0;i < fastcall_nb_regs; i++) {487 for(i = 0;i < fastcall_nb_regs; i++) {
491 if (args_size <= 0)488 if (args_size <= 0)
492 break;489 break;
493 o(0x58 + fastcall_regs_ptr[i]); /* pop r */490 o(S, 0x58 + fastcall_regs_ptr[i]); /* pop r */
494 /* XXX: incorrect for struct/floats */491 /* XXX: incorrect for struct/floats */
495 args_size -= 4;492 args_size -= 4;
496 }493 }
497 }494 }
498#if !defined(TCC_TARGET_PE) && !TARGETOS_FreeBSD || TARGETOS_OpenBSD495#if !defined(TCC_TARGET_PE) && !TARGETOS_FreeBSD || TARGETOS_OpenBSD
499 else if ((vtop->type.ref->type.t & VT_BTYPE) == VT_STRUCT)496 else if ((S->tccgen_vtop->type.ref->type.t & VT_BTYPE) == VT_STRUCT)
500 args_size -= 4;497 args_size -= 4;
501#endif498#endif
502 499
503 gcall_or_jmp(0);500 gcall_or_jmp(S, 0);
504 501
505 if (args_size && func_call != FUNC_STDCALL && func_call != FUNC_FASTCALLW)502 if (args_size && func_call != FUNC_STDCALL && func_call != FUNC_FASTCALLW)
506 gadd_sp(args_size);503 gadd_sp(S, args_size);
507 vtop--;504 S->tccgen_vtop--;
508}505}
509 506
510#ifdef TCC_TARGET_PE507#ifdef TCC_TARGET_PE
@@ -514,7 +511,7 @@ ST_FUNC void gfunc_call(int nb_args) · 3 unmodified lines
514#endif511#endif
515 512
516/* generate function prolog of type 't' */513/* generate function prolog of type 't' */
517ST_FUNC void gfunc_prolog(Sym *func_sym)514ST_FUNC void gfunc_prolog(TCCState* S, Sym *func_sym)
518{515{
519 CType *func_type = &func_sym->type;516 CType *func_type = &func_sym->type;
520 int addr, align, size, func_call, fastcall_nb_regs;517 int addr, align, size, func_call, fastcall_nb_regs;
@@ -526,8 +523,8 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 5 unmodified lines
526 sym = func_type->ref;523 sym = func_type->ref;
527 func_call = sym->f.func_call;524 func_call = sym->f.func_call;
528 addr = 8;525 addr = 8;
529 loc = 0;526 S->tccgen_loc = 0;
530 func_vc = 0;527 S->tccgen_func_vc = 0;
531 528
532 if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {529 if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
533 fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;530 fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
@@ -541,19 +538,19 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 7 unmodified lines
541 }538 }
542 param_index = 0;539 param_index = 0;
543 540
544 ind += FUNC_PROLOG_SIZE;541 S->tccgen_ind += FUNC_PROLOG_SIZE;
545 func_sub_sp_offset = ind;542 func_sub_sp_offset = S->tccgen_ind;
546 /* if the function returns a structure, then add an543 /* if the function returns a structure, then add an
547 implicit pointer parameter */544 implicit pointer parameter */
548#if defined(TCC_TARGET_PE) || TARGETOS_FreeBSD || TARGETOS_OpenBSD545#if defined(TCC_TARGET_PE) || TARGETOS_FreeBSD || TARGETOS_OpenBSD
549 size = type_size(&func_vt,&align);546 size = type_size(&S->tccgen_func_vt,&align);
550 if (((func_vt.t & VT_BTYPE) == VT_STRUCT)547 if (((S->tccgen_func_vt.t & VT_BTYPE) == VT_STRUCT)
551 && (size > 8 || (size & (size - 1)))) {548 && (size > 8 || (size & (size - 1)))) {
552#else549#else
553 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {550 if ((S->tccgen_func_vt.t & VT_BTYPE) == VT_STRUCT) {
554#endif551#endif
555 /* XXX: fastcall case ? */552 /* XXX: fastcall case ? */
556 func_vc = addr;553 S->tccgen_func_vc = addr;
557 addr += 4;554 addr += 4;
558 param_index++;555 param_index++;
559 }556 }
@@ -570,15 +567,15 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 10 unmodified lines
570#endif567#endif
571 if (param_index < fastcall_nb_regs) {568 if (param_index < fastcall_nb_regs) {
572 /* save FASTCALL register */569 /* save FASTCALL register */
573 loc -= 4;570 S->tccgen_loc -= 4;
574 o(0x89); /* movl */571 o(S, 0x89); /* movl */
575 gen_modrm(fastcall_regs_ptr[param_index], VT_LOCAL, NULL, loc);572 gen_modrm(S, fastcall_regs_ptr[param_index], VT_LOCAL, NULL, S->tccgen_loc);
576 param_addr = loc;573 param_addr = S->tccgen_loc;
577 } else {574 } else {
578 param_addr = addr;575 param_addr = addr;
579 addr += size;576 addr += size;
580 }577 }
581 sym_push(sym->v & ~SYM_FIELD, type,578 sym_push(S, sym->v & ~SYM_FIELD, type,
582 VT_LOCAL | VT_LVAL, param_addr);579 VT_LOCAL | VT_LVAL, param_addr);
583 param_index++;580 param_index++;
584 }581 }
@@ -587,94 +584,94 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 2 unmodified lines
587 if (func_call == FUNC_STDCALL || func_call == FUNC_FASTCALLW)584 if (func_call == FUNC_STDCALL || func_call == FUNC_FASTCALLW)
588 func_ret_sub = addr - 8;585 func_ret_sub = addr - 8;
589#if !defined(TCC_TARGET_PE) && !TARGETOS_FreeBSD || TARGETOS_OpenBSD586#if !defined(TCC_TARGET_PE) && !TARGETOS_FreeBSD || TARGETOS_OpenBSD
590 else if (func_vc)587 else if (S->tccgen_func_vc)
591 func_ret_sub = 4;588 func_ret_sub = 4;
592#endif589#endif
593 590
594#ifdef CONFIG_TCC_BCHECK591#ifdef CONFIG_TCC_BCHECK
595 if (tcc_state->do_bounds_check)592 if (S->do_bounds_check)
596 gen_bounds_prolog();593 gen_bounds_prolog(S);
597#endif594#endif
598}595}
599 596
600/* generate function epilog */597/* generate function epilog */
601ST_FUNC void gfunc_epilog(void)598ST_FUNC void gfunc_epilog(TCCState* S)
602{599{
603 addr_t v, saved_ind;600 addr_t v, saved_ind;
604 601
605#ifdef CONFIG_TCC_BCHECK602#ifdef CONFIG_TCC_BCHECK
606 if (tcc_state->do_bounds_check)603 if (S->do_bounds_check)
607 gen_bounds_epilog();604 gen_bounds_epilog(S);
608#endif605#endif
609 606
610 /* align local size to word & save local variables */607 /* align local size to word & save local variables */
611 v = (-loc + 3) & -4;608 v = (-S->tccgen_loc + 3) & -4;
612 609
613#if USE_EBX610#if USE_EBX
614 o(0x8b);611 o(S, 0x8b);
615 gen_modrm(TREG_EBX, VT_LOCAL, NULL, -(v+4));612 gen_modrm(S, TREG_EBX, VT_LOCAL, NULL, -(v+4));
616#endif613#endif
617 614
618 o(0xc9); /* leave */615 o(S, 0xc9); /* leave */
619 if (func_ret_sub == 0) {616 if (func_ret_sub == 0) {
620 o(0xc3); /* ret */617 o(S, 0xc3); /* ret */
621 } else {618 } else {
622 o(0xc2); /* ret n */619 o(S, 0xc2); /* ret n */
623 g(func_ret_sub);620 g(S, func_ret_sub);
624 g(func_ret_sub >> 8);621 g(S, func_ret_sub >> 8);
625 }622 }
626 saved_ind = ind;623 saved_ind = S->tccgen_ind;
627 ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;624 S->tccgen_ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
628#ifdef TCC_TARGET_PE625#ifdef TCC_TARGET_PE
629 if (v >= 4096) {626 if (v >= 4096) {
630 oad(0xb8, v); /* mov stacksize, %eax */627 oad(S, 0xb8, v); /* mov stacksize, %eax */
631 gen_static_call(TOK___chkstk); /* call __chkstk, (does the stackframe too) */628 gen_static_call(S, TOK___chkstk); /* call __chkstk, (does the stackframe too) */
632 } else629 } else
633#endif630#endif
634 {631 {
635 o(0xe58955); /* push %ebp, mov %esp, %ebp */632 o(S, 0xe58955); /* push %ebp, mov %esp, %ebp */
636 o(0xec81); /* sub esp, stacksize */633 o(S, 0xec81); /* sub esp, stacksize */
637 gen_le32(v);634 gen_le32(S, v);
638#ifdef TCC_TARGET_PE635#ifdef TCC_TARGET_PE
639 o(0x90); /* adjust to FUNC_PROLOG_SIZE */636 o(S, 0x90); /* adjust to FUNC_PROLOG_SIZE */
640#endif637#endif
641 }638 }
642 o(0x53 * USE_EBX); /* push ebx */639 o(S, 0x53 * USE_EBX); /* push ebx */
643 ind = saved_ind;640 S->tccgen_ind = saved_ind;
644}641}
645 642
646/* generate a jump to a label */643/* generate a jump to a label */
647ST_FUNC int gjmp(int t)644ST_FUNC int gjmp(TCCState* S, int t)
648{645{
649 return gjmp2(0xe9, t);646 return gjmp2(S, 0xe9, t);
650}647}
651 648
652/* generate a jump to a fixed address */649/* generate a jump to a fixed address */
653ST_FUNC void gjmp_addr(int a)650ST_FUNC void gjmp_addr(TCCState* S, int a)
654{651{
655 int r;652 int r;
656 r = a - ind - 2;653 r = a - S->tccgen_ind - 2;
657 if (r == (char)r) {654 if (r == (char)r) {
658 g(0xeb);655 g(S, 0xeb);
659 g(r);656 g(S, r);
660 } else {657 } else {
661 oad(0xe9, a - ind - 5);658 oad(S, 0xe9, a - S->tccgen_ind - 5);
662 }659 }
663}660}
664 661
665#if 0662#if 0
666/* generate a jump to a fixed address */663/* generate a jump to a fixed address */
667ST_FUNC void gjmp_cond_addr(int a, int op)664ST_FUNC void gjmp_cond_addr(TCCState* S, int a, int op)
668{665{
669 int r = a - ind - 2;666 int r = a - S->tccgen_ind - 2;
670 if (r == (char)r)667 if (r == (char)r)
671 g(op - 32), g(r);668 g(S, op - 32), g(r);
672 else669 else
673 g(0x0f), gjmp2(op - 16, r - 4);670 g(S, 0x0f), gjmp2(S, op - 16, r - 4);
674}671}
675#endif672#endif
676 673
677ST_FUNC int gjmp_append(int n, int t)674ST_FUNC int gjmp_append(TCCState* S, int n, int t)
678{675{
679 void *p;676 void *p;
680 /* insert vtop->c jump list in t */677 /* insert vtop->c jump list in t */
@@ -688,14 +685,14 @@ ST_FUNC int gjmp_append(int n, int t) · 7 unmodified lines
688 return t;685 return t;
689}686}
690 687
691ST_FUNC int gjmp_cond(int op, int t)688ST_FUNC int gjmp_cond(TCCState* S, int op, int t)
692{689{
693 g(0x0f);690 g(S, 0x0f);
694 t = gjmp2(op - 16, t);691 t = gjmp2(S, op - 16, t);
695 return t;692 return t;
696}693}
697 694
698ST_FUNC void gen_opi(int op)695ST_FUNC void gen_opi(TCCState* S, int op)
699{696{
700 int r, fr, opc, c;697 int r, fr, opc, c;
701 698
@@ -704,36 +701,36 @@ ST_FUNC void gen_opi(int op) · 2 unmodified lines
704 case TOK_ADDC1: /* add with carry generation */701 case TOK_ADDC1: /* add with carry generation */
705 opc = 0;702 opc = 0;
706 gen_op8:703 gen_op8:
707 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {704 if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
708 /* constant case */705 /* constant case */
709 vswap();706 vswap(S);
710 r = gv(RC_INT);707 r = gv(S, RC_INT);
711 vswap();708 vswap(S);
712 c = vtop->c.i;709 c = S->tccgen_vtop->c.i;
713 if (c == (char)c) {710 if (c == (char)c) {
714 /* generate inc and dec for smaller code */711 /* generate inc and dec for smaller code */
715 if ((c == 1 || c == -1) && (op == '+' || op == '-')) {712 if ((c == 1 || c == -1) && (op == '+' || op == '-')) {
716 opc = (c == 1) ^ (op == '+');713 opc = (c == 1) ^ (op == '+');
717 o (0x40 | (opc << 3) | r); // inc,dec714 o(S, 0x40 | (opc << 3) | r); // inc,dec
718 } else {715 } else {
719 o(0x83);716 o(S, 0x83);
720 o(0xc0 | (opc << 3) | r);717 o(S, 0xc0 | (opc << 3) | r);
721 g(c);718 g(S, c);
722 }719 }
723 } else {720 } else {
724 o(0x81);721 o(S, 0x81);
725 oad(0xc0 | (opc << 3) | r, c);722 oad(S, 0xc0 | (opc << 3) | r, c);
726 }723 }
727 } else {724 } else {
728 gv2(RC_INT, RC_INT);725 gv2(S, RC_INT, RC_INT);
729 r = vtop[-1].r;726 r = S->tccgen_vtop[-1].r;
730 fr = vtop[0].r;727 fr = S->tccgen_vtop[0].r;
731 o((opc << 3) | 0x01);728 o(S, (opc << 3) | 0x01);
732 o(0xc0 + r + fr * 8); 729 o(S, 0xc0 + r + fr * 8);
733 }730 }
734 vtop--;731 S->tccgen_vtop--;
735 if (op >= TOK_ULT && op <= TOK_GT)732 if (op >= TOK_ULT && op <= TOK_GT)
736 vset_VT_CMP(op);733 vset_VT_CMP(S, op);
737 break;734 break;
738 case '-':735 case '-':
739 case TOK_SUBC1: /* sub with carry generation */736 case TOK_SUBC1: /* sub with carry generation */
@@ -755,12 +752,12 @@ ST_FUNC void gen_opi(int op) · 15 unmodified lines
755 opc = 1;752 opc = 1;
756 goto gen_op8;753 goto gen_op8;
757 case '*':754 case '*':
758 gv2(RC_INT, RC_INT);755 gv2(S, RC_INT, RC_INT);
759 r = vtop[-1].r;756 r = S->tccgen_vtop[-1].r;
760 fr = vtop[0].r;757 fr = S->tccgen_vtop[0].r;
761 vtop--;758 S->tccgen_vtop--;
762 o(0xaf0f); /* imul fr, r */759 o(S, 0xaf0f); /* imul fr, r */
763 o(0xc0 + fr + r * 8);760 o(S, 0xc0 + fr + r * 8);
764 break;761 break;
765 case TOK_SHL:762 case TOK_SHL:
766 opc = 4;763 opc = 4;
@@ -772,23 +769,23 @@ ST_FUNC void gen_opi(int op) · 5 unmodified lines
772 opc = 7;769 opc = 7;
773 gen_shift:770 gen_shift:
774 opc = 0xc0 | (opc << 3);771 opc = 0xc0 | (opc << 3);
775 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {772 if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
776 /* constant case */773 /* constant case */
777 vswap();774 vswap(S);
778 r = gv(RC_INT);775 r = gv(S, RC_INT);
779 vswap();776 vswap(S);
780 c = vtop->c.i & 0x1f;777 c = S->tccgen_vtop->c.i & 0x1f;
781 o(0xc1); /* shl/shr/sar $xxx, r */778 o(S, 0xc1); /* shl/shr/sar $xxx, r */
782 o(opc | r);779 o(S, opc | r);
783 g(c);780 g(S, c);
784 } else {781 } else {
785 /* we generate the shift in ecx */782 /* we generate the shift in ecx */
786 gv2(RC_INT, RC_ECX);783 gv2(S, RC_INT, RC_ECX);
787 r = vtop[-1].r;784 r = S->tccgen_vtop[-1].r;
788 o(0xd3); /* shl/shr/sar %cl, r */785 o(S, 0xd3); /* shl/shr/sar %cl, r */
789 o(opc | r);786 o(S, opc | r);
790 }787 }
791 vtop--;788 S->tccgen_vtop--;
792 break;789 break;
793 case '/':790 case '/':
794 case TOK_UDIV:791 case TOK_UDIV:
@@ -798,32 +795,32 @@ ST_FUNC void gen_opi(int op) · 3 unmodified lines
798 case TOK_UMULL:795 case TOK_UMULL:
799 /* first operand must be in eax */796 /* first operand must be in eax */
800 /* XXX: need better constraint for second operand */797 /* XXX: need better constraint for second operand */
801 gv2(RC_EAX, RC_ECX);798 gv2(S, RC_EAX, RC_ECX);
802 r = vtop[-1].r;799 r = S->tccgen_vtop[-1].r;
803 fr = vtop[0].r;800 fr = S->tccgen_vtop[0].r;
804 vtop--;801 S->tccgen_vtop--;
805 save_reg(TREG_EDX);802 save_reg(S, TREG_EDX);
806 /* save EAX too if used otherwise */803 /* save EAX too if used otherwise */
807 save_reg_upstack(TREG_EAX, 1);804 save_reg_upstack(S, TREG_EAX, 1);
808 if (op == TOK_UMULL) {805 if (op == TOK_UMULL) {
809 o(0xf7); /* mul fr */806 o(S, 0xf7); /* mul fr */
810 o(0xe0 + fr);807 o(S, 0xe0 + fr);
811 vtop->r2 = TREG_EDX;808 S->tccgen_vtop->r2 = TREG_EDX;
812 r = TREG_EAX;809 r = TREG_EAX;
813 } else {810 } else {
814 if (op == TOK_UDIV || op == TOK_UMOD) {811 if (op == TOK_UDIV || op == TOK_UMOD) {
815 o(0xf7d231); /* xor %edx, %edx, div fr, %eax */812 o(S, 0xf7d231); /* xor %edx, %edx, div fr, %eax */
816 o(0xf0 + fr);813 o(S, 0xf0 + fr);
817 } else {814 } else {
818 o(0xf799); /* cltd, idiv fr, %eax */815 o(S, 0xf799); /* cltd, idiv fr, %eax */
819 o(0xf8 + fr);816 o(S, 0xf8 + fr);
820 }817 }
821 if (op == '%' || op == TOK_UMOD)818 if (op == '%' || op == TOK_UMOD)
822 r = TREG_EDX;819 r = TREG_EDX;
823 else820 else
824 r = TREG_EAX;821 r = TREG_EAX;
825 }822 }
826 vtop->r = r;823 S->tccgen_vtop->r = r;
827 break;824 break;
828 default:825 default:
829 opc = 7;826 opc = 7;
@@ -834,74 +831,74 @@ ST_FUNC void gen_opi(int op) · 4 unmodified lines
834/* generate a floating point operation 'v = t1 op t2' instruction. The831/* generate a floating point operation 'v = t1 op t2' instruction. The
835 two operands are guaranteed to have the same floating point type */832 two operands are guaranteed to have the same floating point type */
836/* XXX: need to use ST1 too */833/* XXX: need to use ST1 too */
837ST_FUNC void gen_opf(int op)834ST_FUNC void gen_opf(TCCState* S, int op)
838{835{
839 int a, ft, fc, swapped, r;836 int a, ft, fc, swapped, r;
840 837
841 if (op == TOK_NEG) { /* unary minus */838 if (op == TOK_NEG) { /* unary minus */
842 gv(RC_FLOAT);839 gv(S, RC_FLOAT);
843 o(0xe0d9); /* fchs */840 o(S, 0xe0d9); /* fchs */
844 return;841 return;
845 }842 }
846 843
847 /* convert constants to memory references */844 /* convert constants to memory references */
848 if ((vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {845 if ((S->tccgen_vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
849 vswap();846 vswap(S);
850 gv(RC_FLOAT);847 gv(S, RC_FLOAT);
851 vswap();848 vswap(S);
852 }849 }
853 if ((vtop[0].r & (VT_VALMASK | VT_LVAL)) == VT_CONST)850 if ((S->tccgen_vtop[0].r & (VT_VALMASK | VT_LVAL)) == VT_CONST)
854 gv(RC_FLOAT);851 gv(S, RC_FLOAT);
855 852
856 /* must put at least one value in the floating point register */853 /* must put at least one value in the floating point register */
857 if ((vtop[-1].r & VT_LVAL) &&854 if ((S->tccgen_vtop[-1].r & VT_LVAL) &&
858 (vtop[0].r & VT_LVAL)) {855 (S->tccgen_vtop[0].r & VT_LVAL)) {
859 vswap();856 vswap(S);
860 gv(RC_FLOAT);857 gv(S, RC_FLOAT);
861 vswap();858 vswap(S);
862 }859 }
863 swapped = 0;860 swapped = 0;
864 /* swap the stack if needed so that t1 is the register and t2 is861 /* swap the stack if needed so that t1 is the register and t2 is
865 the memory reference */862 the memory reference */
866 if (vtop[-1].r & VT_LVAL) {863 if (S->tccgen_vtop[-1].r & VT_LVAL) {
867 vswap();864 vswap(S);
868 swapped = 1;865 swapped = 1;
869 }866 }
870 if (op >= TOK_ULT && op <= TOK_GT) {867 if (op >= TOK_ULT && op <= TOK_GT) {
871 /* load on stack second operand */868 /* load on stack second operand */
872 load(TREG_ST0, vtop);869 load(S, TREG_ST0, S->tccgen_vtop);
873 save_reg(TREG_EAX); /* eax is used by FP comparison code */870 save_reg(S, TREG_EAX); /* eax is used by FP comparison code */
874 if (op == TOK_GE || op == TOK_GT)871 if (op == TOK_GE || op == TOK_GT)
875 swapped = !swapped;872 swapped = !swapped;
876 else if (op == TOK_EQ || op == TOK_NE)873 else if (op == TOK_EQ || op == TOK_NE)
877 swapped = 0;874 swapped = 0;
878 if (swapped)875 if (swapped)
879 o(0xc9d9); /* fxch %st(1) */876 o(S, 0xc9d9); /* fxch %st(1) */
880 if (op == TOK_EQ || op == TOK_NE)877 if (op == TOK_EQ || op == TOK_NE)
881 o(0xe9da); /* fucompp */878 o(S, 0xe9da); /* fucompp */
882 else879 else
883 o(0xd9de); /* fcompp */880 o(S, 0xd9de); /* fcompp */
884 o(0xe0df); /* fnstsw %ax */881 o(S, 0xe0df); /* fnstsw %ax */
885 if (op == TOK_EQ) {882 if (op == TOK_EQ) {
886 o(0x45e480); /* and $0x45, %ah */883 o(S, 0x45e480); /* and $0x45, %ah */
887 o(0x40fC80); /* cmp $0x40, %ah */884 o(S, 0x40fC80); /* cmp $0x40, %ah */
888 } else if (op == TOK_NE) {885 } else if (op == TOK_NE) {
889 o(0x45e480); /* and $0x45, %ah */886 o(S, 0x45e480); /* and $0x45, %ah */
890 o(0x40f480); /* xor $0x40, %ah */887 o(S, 0x40f480); /* xor $0x40, %ah */
891 op = TOK_NE;888 op = TOK_NE;
892 } else if (op == TOK_GE || op == TOK_LE) {889 } else if (op == TOK_GE || op == TOK_LE) {
893 o(0x05c4f6); /* test $0x05, %ah */890 o(S, 0x05c4f6); /* test $0x05, %ah */
894 op = TOK_EQ;891 op = TOK_EQ;
895 } else {892 } else {
896 o(0x45c4f6); /* test $0x45, %ah */893 o(S, 0x45c4f6); /* test $0x45, %ah */
897 op = TOK_EQ;894 op = TOK_EQ;
898 }895 }
899 vtop--;896 S->tccgen_vtop--;
900 vset_VT_CMP(op);897 vset_VT_CMP(S, op);
901 } else {898 } else {
902 /* no memory reference possible for long double operations */899 /* no memory reference possible for long double operations */
903 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {900 if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
904 load(TREG_ST0, vtop);901 load(S, TREG_ST0, S->tccgen_vtop);
905 swapped = !swapped;902 swapped = !swapped;
906 }903 }
907 904
@@ -924,213 +921,213 @@ ST_FUNC void gen_opf(int op) · 16 unmodified lines
924 a++;921 a++;
925 break;922 break;
926 }923 }
927 ft = vtop->type.t;924 ft = S->tccgen_vtop->type.t;
928 fc = vtop->c.i;925 fc = S->tccgen_vtop->c.i;
929 if ((ft & VT_BTYPE) == VT_LDOUBLE) {926 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
930 o(0xde); /* fxxxp %st, %st(1) */927 o(S, 0xde); /* fxxxp %st, %st(1) */
931 o(0xc1 + (a << 3));928 o(S, 0xc1 + (a << 3));
932 } else {929 } else {
933 /* if saved lvalue, then we must reload it */930 /* if saved lvalue, then we must reload it */
934 r = vtop->r;931 r = S->tccgen_vtop->r;
935 if ((r & VT_VALMASK) == VT_LLOCAL) {932 if ((r & VT_VALMASK) == VT_LLOCAL) {
936 SValue v1;933 SValue v1;
937 r = get_reg(RC_INT);934 r = get_reg(S, RC_INT);
938 v1.type.t = VT_INT;935 v1.type.t = VT_INT;
939 v1.r = VT_LOCAL | VT_LVAL;936 v1.r = VT_LOCAL | VT_LVAL;
940 v1.c.i = fc;937 v1.c.i = fc;
941 v1.sym = NULL;938 v1.sym = NULL;
942 load(r, &v1);939 load(S, r, &v1);
943 fc = 0;940 fc = 0;
944 }941 }
945 942
946 if ((ft & VT_BTYPE) == VT_DOUBLE)943 if ((ft & VT_BTYPE) == VT_DOUBLE)
947 o(0xdc);944 o(S, 0xdc);
948 else945 else
949 o(0xd8);946 o(S, 0xd8);
950 gen_modrm(a, r, vtop->sym, fc);947 gen_modrm(S, a, r, S->tccgen_vtop->sym, fc);
951 }948 }
952 vtop--;949 S->tccgen_vtop--;
953 }950 }
954}951}
955 952
956/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'953/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
957 and 'long long' cases. */954 and 'long long' cases. */
958ST_FUNC void gen_cvt_itof(int t)955ST_FUNC void gen_cvt_itof(TCCState* S, int t)
959{956{
960 save_reg(TREG_ST0);957 save_reg(S, TREG_ST0);
961 gv(RC_INT);958 gv(S, RC_INT);
962 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {959 if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG) {
963 /* signed long long to float/double/long double (unsigned case960 /* signed long long to float/double/long double (unsigned case
964 is handled generically) */961 is handled generically) */
965 o(0x50 + vtop->r2); /* push r2 */962 o(S, 0x50 + S->tccgen_vtop->r2); /* push r2 */
966 o(0x50 + (vtop->r & VT_VALMASK)); /* push r */963 o(S, 0x50 + (S->tccgen_vtop->r & VT_VALMASK)); /* push r */
967 o(0x242cdf); /* fildll (%esp) */964 o(S, 0x242cdf); /* fildll (%esp) */
968 o(0x08c483); /* add $8, %esp */965 o(S, 0x08c483); /* add $8, %esp */
969 vtop->r2 = VT_CONST;966 S->tccgen_vtop->r2 = VT_CONST;
970 } else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == 967 } else if ((S->tccgen_vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
971 (VT_INT | VT_UNSIGNED)) {968 (VT_INT | VT_UNSIGNED)) {
972 /* unsigned int to float/double/long double */969 /* unsigned int to float/double/long double */
973 o(0x6a); /* push $0 */970 o(S, 0x6a); /* push $0 */
974 g(0x00);971 g(S, 0x00);
975 o(0x50 + (vtop->r & VT_VALMASK)); /* push r */972 o(S, 0x50 + (S->tccgen_vtop->r & VT_VALMASK)); /* push r */
976 o(0x242cdf); /* fildll (%esp) */973 o(S, 0x242cdf); /* fildll (%esp) */
977 o(0x08c483); /* add $8, %esp */974 o(S, 0x08c483); /* add $8, %esp */
978 } else {975 } else {
979 /* int to float/double/long double */976 /* int to float/double/long double */
980 o(0x50 + (vtop->r & VT_VALMASK)); /* push r */977 o(S, 0x50 + (S->tccgen_vtop->r & VT_VALMASK)); /* push r */
981 o(0x2404db); /* fildl (%esp) */978 o(S, 0x2404db); /* fildl (%esp) */
982 o(0x04c483); /* add $4, %esp */979 o(S, 0x04c483); /* add $4, %esp */
983 }980 }
984 vtop->r2 = VT_CONST;981 S->tccgen_vtop->r2 = VT_CONST;
985 vtop->r = TREG_ST0;982 S->tccgen_vtop->r = TREG_ST0;
986}983}
987 984
988/* convert fp to int 't' type */985/* convert fp to int 't' type */
989ST_FUNC void gen_cvt_ftoi(int t)986ST_FUNC void gen_cvt_ftoi(TCCState* S, int t)
990{987{
991 int bt = vtop->type.t & VT_BTYPE;988 int bt = S->tccgen_vtop->type.t & VT_BTYPE;
992 if (bt == VT_FLOAT)989 if (bt == VT_FLOAT)
993 vpush_helper_func(TOK___fixsfdi);990 vpush_helper_func(S, TOK___fixsfdi);
994 else if (bt == VT_LDOUBLE)991 else if (bt == VT_LDOUBLE)
995 vpush_helper_func(TOK___fixxfdi);992 vpush_helper_func(S, TOK___fixxfdi);
996 else993 else
997 vpush_helper_func(TOK___fixdfdi);994 vpush_helper_func(S, TOK___fixdfdi);
998 vswap();995 vswap(S);
999 gfunc_call(1);996 gfunc_call(S, 1);
1000 vpushi(0);997 vpushi(S, 0);
1001 vtop->r = REG_IRET;998 S->tccgen_vtop->r = REG_IRET;
1002 if ((t & VT_BTYPE) == VT_LLONG)999 if ((t & VT_BTYPE) == VT_LLONG)
1003 vtop->r2 = REG_IRE2;1000 S->tccgen_vtop->r2 = REG_IRE2;
1004}1001}
1005 1002
1006/* convert from one floating point type to another */1003/* convert from one floating point type to another */
1007ST_FUNC void gen_cvt_ftof(int t)1004ST_FUNC void gen_cvt_ftof(TCCState* S, int t)
1008{1005{
1009 /* all we have to do on i386 is to put the float in a register */1006 /* all we have to do on i386 is to put the float in a register */
1010 gv(RC_FLOAT);1007 gv(S, RC_FLOAT);
1011}1008}
1012 1009
1013/* char/short to int conversion */1010/* char/short to int conversion */
1014ST_FUNC void gen_cvt_csti(int t)1011ST_FUNC void gen_cvt_csti(TCCState* S, int t)
1015{1012{
1016 int r, sz, xl;1013 int r, sz, xl;
1017 r = gv(RC_INT);1014 r = gv(S, RC_INT);
1018 sz = !(t & VT_UNSIGNED);1015 sz = !(t & VT_UNSIGNED);
1019 xl = (t & VT_BTYPE) == VT_SHORT;1016 xl = (t & VT_BTYPE) == VT_SHORT;
1020 o(0xc0b60f /* mov[sz] %a[xl], %eax */1017 o(S, 0xc0b60f /* mov[sz] %a[xl], %eax */
1021 | (sz << 3 | xl) << 81018 | (sz << 3 | xl) << 8
1022 | (r << 3 | r) << 161019 | (r << 3 | r) << 16
1023 );1020 );
1024}1021}
1025 1022
1026/* increment tcov counter */1023/* increment tcov counter */
1027ST_FUNC void gen_increment_tcov (SValue *sv)1024ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv)
1028{1025{
1029 o(0x0583); /* addl $1, xxx */1026 o(S, 0x0583); /* addl $1, xxx */
1030 greloc(cur_text_section, sv->sym, ind, R_386_32);1027 greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_386_32);
1031 gen_le32(0);1028 gen_le32(S, 0);
1032 o(1);1029 o(S, 1);
1033 o(0x1583); /* addcl $0, xxx */1030 o(S, 0x1583); /* addcl $0, xxx */
1034 greloc(cur_text_section, sv->sym, ind, R_386_32);1031 greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_386_32);
1035 gen_le32(4);1032 gen_le32(S, 4);
1036 g(0);1033 g(S, 0);
1037}1034}
1038 1035
1039/* computed goto support */1036/* computed goto support */
1040ST_FUNC void ggoto(void)1037ST_FUNC void ggoto(TCCState* S)
1041{1038{
1042 gcall_or_jmp(1);1039 gcall_or_jmp(S, 1);
1043 vtop--;1040 S->tccgen_vtop--;
1044}1041}
1045 1042
1046/* bound check support functions */1043/* bound check support functions */
1047#ifdef CONFIG_TCC_BCHECK1044#ifdef CONFIG_TCC_BCHECK
1048 1045
1049static void gen_bounds_prolog(void)1046static void gen_bounds_prolog(TCCState* S)
1050{1047{
1051 /* leave some room for bound checking code */1048 /* leave some room for bound checking code */
1052 func_bound_offset = lbounds_section->data_offset;1049 S->func_bound_offset = lbounds_section->data_offset;
1053 func_bound_ind = ind;1050 S->func_bound_ind = S->tccgen_ind;
1054 func_bound_add_epilog = 0;1051 S->func_bound_add_epilog = 0;
1055 oad(0xb8, 0); /* lbound section pointer */1052 oad(S, 0xb8, 0); /* lbound section pointer */
1056 oad(0xb8, 0); /* call to function */1053 oad(S, 0xb8, 0); /* call to function */
1057}1054}
1058 1055
1059static void gen_bounds_epilog(void)1056static void gen_bounds_epilog(TCCState* S)
1060{1057{
1061 addr_t saved_ind;1058 addr_t saved_ind;
1062 addr_t *bounds_ptr;1059 addr_t *bounds_ptr;
1063 Sym *sym_data;1060 Sym *sym_data;
1064 int offset_modified = func_bound_offset != lbounds_section->data_offset;1061 int offset_modified = S->func_bound_offset != lbounds_section->data_offset;
1065 1062
1066 if (!offset_modified && !func_bound_add_epilog)1063 if (!offset_modified && !S->func_bound_add_epilog)
1067 return;1064 return;
1068 1065
1069 /* add end of table info */1066 /* add end of table info */
1070 bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));1067 bounds_ptr = section_ptr_add(S, lbounds_section, sizeof(addr_t));
1071 *bounds_ptr = 0;1068 *bounds_ptr = 0;
1072 1069
1073 sym_data = get_sym_ref(&char_pointer_type, lbounds_section,1070 sym_data = get_sym_ref(S, &S->tccgen_char_pointer_type, lbounds_section,
1074 func_bound_offset, lbounds_section->data_offset);1071 S->func_bound_offset, lbounds_section->data_offset);
1075 1072
1076 /* generate bound local allocation */1073 /* generate bound local allocation */
1077 if (offset_modified) {1074 if (offset_modified) {
1078 saved_ind = ind;1075 saved_ind = S->tccgen_ind;
1079 ind = func_bound_ind;1076 S->tccgen_ind = S->func_bound_ind;
1080 greloc(cur_text_section, sym_data, ind + 1, R_386_32);1077 greloc(S, cur_text_section, sym_data, S->tccgen_ind + 1, R_386_32);
1081 ind = ind + 5;1078 S->tccgen_ind = S->tccgen_ind + 5;
1082 gen_static_call(TOK___bound_local_new);1079 gen_static_call(S, TOK___bound_local_new);
1083 ind = saved_ind;1080 S->tccgen_ind = saved_ind;
1084 }1081 }
1085 1082
1086 /* generate bound check local freeing */1083 /* generate bound check local freeing */
1087 o(0x5250); /* save returned value, if any */1084 o(S, 0x5250); /* save returned value, if any */
1088 greloc(cur_text_section, sym_data, ind + 1, R_386_32);1085 greloc(S, cur_text_section, sym_data, S->tccgen_ind + 1, R_386_32);
1089 oad(0xb8, 0); /* mov %eax, xxx */1086 oad(S, 0xb8, 0); /* mov %eax, xxx */
1090 gen_static_call(TOK___bound_local_delete);1087 gen_static_call(S, TOK___bound_local_delete);
1091 o(0x585a); /* restore returned value, if any */1088 o(S, 0x585a); /* restore returned value, if any */
1092}1089}
1093#endif1090#endif
1094 1091
1095/* Save the stack pointer onto the stack */1092/* Save the stack pointer onto the stack */
1096ST_FUNC void gen_vla_sp_save(int addr) {1093ST_FUNC void gen_vla_sp_save(TCCState* S, int addr) {
1097 /* mov %esp,addr(%ebp)*/1094 /* mov %esp,addr(%ebp)*/
1098 o(0x89);1095 o(S, 0x89);
1099 gen_modrm(TREG_ESP, VT_LOCAL, NULL, addr);1096 gen_modrm(S, TREG_ESP, VT_LOCAL, NULL, addr);
1100}1097}
1101 1098
1102/* Restore the SP from a location on the stack */1099/* Restore the SP from a location on the stack */
1103ST_FUNC void gen_vla_sp_restore(int addr) {1100ST_FUNC void gen_vla_sp_restore(TCCState* S, int addr) {
1104 o(0x8b);1101 o(S, 0x8b);
1105 gen_modrm(TREG_ESP, VT_LOCAL, NULL, addr);1102 gen_modrm(S, TREG_ESP, VT_LOCAL, NULL, addr);
1106}1103}
1107 1104
1108/* Subtract from the stack pointer, and push the resulting value onto the stack */1105/* Subtract from the stack pointer, and push the resulting value onto the stack */
1109ST_FUNC void gen_vla_alloc(CType *type, int align) {1106ST_FUNC void gen_vla_alloc(TCCState* S, CType *type, int align) {
1110 int use_call = 0;1107 int use_call = 0;
1111 1108
1112#if defined(CONFIG_TCC_BCHECK)1109#if defined(CONFIG_TCC_BCHECK)
1113 use_call = tcc_state->do_bounds_check;1110 use_call = S->do_bounds_check;
1114#endif1111#endif
1115#ifdef TCC_TARGET_PE /* alloca does more than just adjust %rsp on Windows */1112#ifdef TCC_TARGET_PE /* alloca does more than just adjust %rsp on Windows */
1116 use_call = 1;1113 use_call = 1;
1117#endif1114#endif
1118 if (use_call)1115 if (use_call)
1119 {1116 {
1120 vpush_helper_func(TOK_alloca);1117 vpush_helper_func(S, TOK_alloca);
1121 vswap(); /* Move alloca ref past allocation size */1118 vswap(S); /* Move alloca ref past allocation size */
1122 gfunc_call(1);1119 gfunc_call(S, 1);
1123 }1120 }
1124 else {1121 else {
1125 int r;1122 int r;
1126 r = gv(RC_INT); /* allocation size */1123 r = gv(S, RC_INT); /* allocation size */
1127 /* sub r,%rsp */1124 /* sub r,%rsp */
1128 o(0x2b);1125 o(S, 0x2b);
1129 o(0xe0 | r);1126 o(S, 0xe0 | r);
1130 /* We align to 16 bytes rather than align */1127 /* We align to 16 bytes rather than align */
1131 /* and ~15, %esp */1128 /* and ~15, %esp */
1132 o(0xf0e483);1129 o(S, 0xf0e483);
1133 vpop();1130 vpop(S);
1134 }1131 }
1135}1132}
1136 1133
i386-link.c+34−34
@@ -91,15 +91,15 @@ int gotplt_entry_type (int reloc_type) · 90 unmodified lines
91 return -1;91 return -1;
92}92}
93 93
94ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)94ST_FUNC unsigned create_plt_entry(TCCState *S, unsigned got_offset, struct sym_attr *attr)
95{95{
96 Section *plt = s1->plt;96 Section *plt = S->plt;
97 uint8_t *p;97 uint8_t *p;
98 int modrm;98 int modrm;
99 unsigned plt_offset, relofs;99 unsigned plt_offset, relofs;
100 100
101 /* on i386 if we build a DLL, we add a %ebx offset */101 /* on i386 if we build a DLL, we add a %ebx offset */
102 if (s1->output_type == TCC_OUTPUT_DLL)102 if (S->output_type == TCC_OUTPUT_DLL)
103 modrm = 0xa3;103 modrm = 0xa3;
104 else104 else
105 modrm = 0x25;105 modrm = 0x25;
@@ -108,7 +108,7 @@ ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_ · 2 unmodified lines
108 (GOT + PTR_SIZE) and jumps to ld.so resolution routine108 (GOT + PTR_SIZE) and jumps to ld.so resolution routine
109 (GOT + 2 * PTR_SIZE) */109 (GOT + 2 * PTR_SIZE) */
110 if (plt->data_offset == 0) {110 if (plt->data_offset == 0) {
111 p = section_ptr_add(plt, 16);111 p = section_ptr_add(S, plt, 16);
112 p[0] = 0xff; /* pushl got + PTR_SIZE */112 p[0] = 0xff; /* pushl got + PTR_SIZE */
113 p[1] = modrm + 0x10;113 p[1] = modrm + 0x10;
114 write32le(p + 2, PTR_SIZE);114 write32le(p + 2, PTR_SIZE);
@@ -121,10 +121,10 @@ ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_ · 6 unmodified lines
121 /* The PLT slot refers to the relocation entry it needs via offset.121 /* The PLT slot refers to the relocation entry it needs via offset.
122 The reloc entry is created below, so its offset is the current122 The reloc entry is created below, so its offset is the current
123 data_offset */123 data_offset */
124 relofs = s1->plt->reloc ? s1->plt->reloc->data_offset : 0;124 relofs = S->plt->reloc ? S->plt->reloc->data_offset : 0;
125 125
126 /* Jump to GOT entry where ld.so initially put the address of ip + 4 */126 /* Jump to GOT entry where ld.so initially put the address of ip + 4 */
127 p = section_ptr_add(plt, 16);127 p = section_ptr_add(S, plt, 16);
128 p[0] = 0xff; /* jmp *(got + x) */128 p[0] = 0xff; /* jmp *(got + x) */
129 p[1] = modrm;129 p[1] = modrm;
130 write32le(p + 2, got_offset);130 write32le(p + 2, got_offset);
@@ -137,31 +137,31 @@ ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_ · 6 unmodified lines
137 137
138/* relocate the PLT: compute addresses and offsets in the PLT now that final138/* relocate the PLT: compute addresses and offsets in the PLT now that final
139 address for PLT and GOT are known (see fill_program_header) */139 address for PLT and GOT are known (see fill_program_header) */
140ST_FUNC void relocate_plt(TCCState *s1)140ST_FUNC void relocate_plt(TCCState *S)
141{141{
142 uint8_t *p, *p_end;142 uint8_t *p, *p_end;
143 143
144 if (!s1->plt)144 if (!S->plt)
145 return;145 return;
146 146
147 p = s1->plt->data;147 p = S->plt->data;
148 p_end = p + s1->plt->data_offset;148 p_end = p + S->plt->data_offset;
149 149
150 if (s1->output_type != TCC_OUTPUT_DLL && p < p_end) {150 if (S->output_type != TCC_OUTPUT_DLL && p < p_end) {
151 add32le(p + 2, s1->got->sh_addr);151 add32le(p + 2, S->got->sh_addr);
152 add32le(p + 8, s1->got->sh_addr);152 add32le(p + 8, S->got->sh_addr);
153 p += 16;153 p += 16;
154 while (p < p_end) {154 while (p < p_end) {
155 add32le(p + 2, s1->got->sh_addr);155 add32le(p + 2, S->got->sh_addr);
156 p += 16;156 p += 16;
157 }157 }
158 }158 }
159 159
160 if (s1->plt->reloc) {160 if (S->plt->reloc) {
161 ElfW_Rel *rel;161 ElfW_Rel *rel;
162 int x = s1->plt->sh_addr + 16 + 6;162 int x = S->plt->sh_addr + 16 + 6;
163 p = s1->got->data;163 p = S->got->data;
164 for_each_elem(s1->plt->reloc, 0, rel, ElfW_Rel) {164 for_each_elem(S->plt->reloc, 0, rel, ElfW_Rel) {
165 write32le(p + rel->r_offset, x);165 write32le(p + rel->r_offset, x);
166 x += 16;166 x += 16;
167 }167 }
@@ -169,7 +169,7 @@ ST_FUNC void relocate_plt(TCCState *s1) · 1 unmodified line
169}169}
170#endif170#endif
171 171
172void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)172void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
173{173{
174 int sym_index, esym_index;174 int sym_index, esym_index;
175 175
@@ -177,8 +177,8 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 1 unmodified line
177 177
178 switch (type) {178 switch (type) {
179 case R_386_32:179 case R_386_32:
180 if (s1->output_type == TCC_OUTPUT_DLL) {180 if (S->output_type == TCC_OUTPUT_DLL) {
181 esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;181 esym_index = get_sym_attr(S, sym_index, 0)->dyn_index;
182 qrel->r_offset = rel->r_offset;182 qrel->r_offset = rel->r_offset;
183 if (esym_index) {183 if (esym_index) {
184 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32);184 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32);
@@ -192,9 +192,9 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 7 unmodified lines
192 add32le(ptr, val);192 add32le(ptr, val);
193 return;193 return;
194 case R_386_PC32:194 case R_386_PC32:
195 if (s1->output_type == TCC_OUTPUT_DLL) {195 if (S->output_type == TCC_OUTPUT_DLL) {
196 /* DLL relocation */196 /* DLL relocation */
197 esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;197 esym_index = get_sym_attr(S, sym_index, 0)->dyn_index;
198 if (esym_index) {198 if (esym_index) {
199 qrel->r_offset = rel->r_offset;199 qrel->r_offset = rel->r_offset;
200 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32);200 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32);
@@ -212,31 +212,31 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 11 unmodified lines
212 write32le(ptr, val);212 write32le(ptr, val);
213 return;213 return;
214 case R_386_GOTPC:214 case R_386_GOTPC:
215 add32le(ptr, s1->got->sh_addr - addr);215 add32le(ptr, S->got->sh_addr - addr);
216 return;216 return;
217 case R_386_GOTOFF:217 case R_386_GOTOFF:
218 add32le(ptr, val - s1->got->sh_addr);218 add32le(ptr, val - S->got->sh_addr);
219 return;219 return;
220 case R_386_GOT32:220 case R_386_GOT32:
221 case R_386_GOT32X:221 case R_386_GOT32X:
222 /* we load the got offset */222 /* we load the got offset */
223 add32le(ptr, get_sym_attr(s1, sym_index, 0)->got_offset);223 add32le(ptr, get_sym_attr(S, sym_index, 0)->got_offset);
224 return;224 return;
225 case R_386_16:225 case R_386_16:
226 if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) {226 if (S->output_format != TCC_OUTPUT_FORMAT_BINARY) {
227 output_file:227 output_file:
228 tcc_error("can only produce 16-bit binary files");228 tcc_error(S, "can only produce 16-bit binary files");
229 }229 }
230 write16le(ptr, read16le(ptr) + val);230 write16le(ptr, read16le(ptr) + val);
231 return;231 return;
232 case R_386_PC16:232 case R_386_PC16:
233 if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY)233 if (S->output_format != TCC_OUTPUT_FORMAT_BINARY)
234 goto output_file;234 goto output_file;
235 write16le(ptr, read16le(ptr) + val - addr);235 write16le(ptr, read16le(ptr) + val - addr);
236 return;236 return;
237 case R_386_RELATIVE:237 case R_386_RELATIVE:
238#ifdef TCC_TARGET_PE238#ifdef TCC_TARGET_PE
239 add32le(ptr, val - s1->pe_imagebase);239 add32le(ptr, val - S->pe_imagebase);
240#endif240#endif
241 /* do nothing */241 /* do nothing */
242 return;242 return;
@@ -267,12 +267,12 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 24 unmodified lines
267 memcpy(ptr-3, replace, sizeof(replace));267 memcpy(ptr-3, replace, sizeof(replace));
268 rel[1].r_info = ELFW(R_INFO)(0, R_386_NONE);268 rel[1].r_info = ELFW(R_INFO)(0, R_386_NONE);
269 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];269 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
270 sec = s1->sections[sym->st_shndx];270 sec = S->sections[sym->st_shndx];
271 x = sym->st_value - sec->sh_addr - sec->data_offset;271 x = sym->st_value - sec->sh_addr - sec->data_offset;
272 add32le(ptr + 5, -x);272 add32le(ptr + 5, -x);
273 }273 }
274 else274 else
275 tcc_error("unexpected R_386_TLS_GD pattern");275 tcc_error(S, "unexpected R_386_TLS_GD pattern");
276 }276 }
277 return;277 return;
278 case R_386_TLS_LDM:278 case R_386_TLS_LDM:
@@ -295,7 +295,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 16 unmodified lines
295 rel[1].r_info = ELFW(R_INFO)(0, R_386_NONE);295 rel[1].r_info = ELFW(R_INFO)(0, R_386_NONE);
296 }296 }
297 else297 else
298 tcc_error("unexpected R_386_TLS_LDM pattern");298 tcc_error(S, "unexpected R_386_TLS_LDM pattern");
299 }299 }
300 return;300 return;
301 case R_386_TLS_LDO_32:301 case R_386_TLS_LDO_32:
@@ -306,7 +306,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 4 unmodified lines
306 int32_t x;306 int32_t x;
307 307
308 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];308 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
309 sec = s1->sections[sym->st_shndx];309 sec = S->sections[sym->st_shndx];
310 x = val - sec->sh_addr - sec->data_offset;310 x = val - sec->sh_addr - sec->data_offset;
311 add32le(ptr, x);311 add32le(ptr, x);
312 }312 }
libtcc.c+470−393
@@ -65,7 +65,6 @@ · 64 unmodified lines
65/* global variables */65/* global variables */
66 66
67/* XXX: get rid of this ASAP (or maybe not) */67/* XXX: get rid of this ASAP (or maybe not) */
68ST_DATA struct TCCState *tcc_state;
69TCC_SEM(static tcc_compile_sem);68TCC_SEM(static tcc_compile_sem);
70 69
71#ifdef MEM_DEBUG70#ifdef MEM_DEBUG
@@ -111,11 +110,11 @@ static inline char *config_tccdir_w32(char *path) · 39 unmodified lines
111#endif110#endif
112 111
113#ifdef TCC_TARGET_PE112#ifdef TCC_TARGET_PE
114static void tcc_add_systemdir(TCCState *s)113static void tcc_add_systemdir(TCCState *S)
115{114{
116 char buf[1000];115 char buf[1000];
117 GetSystemDirectory(buf, sizeof buf);116 GetSystemDirectory(buf, sizeof buf);
118 tcc_add_library_path(s, normalize_slashes(buf));117 tcc_add_library_path(S, normalize_slashes(buf));
119}118}
120#endif119#endif
121#endif120#endif
@@ -160,19 +159,19 @@ ST_FUNC void post_sem(TCCSem *p) · 38 unmodified lines
160#endif159#endif
161#endif160#endif
162 161
163PUB_FUNC void tcc_enter_state(TCCState *s1)162PUB_FUNC void tcc_enter_state(TCCState *S)
164{163{
165 if (s1->error_set_jmp_enabled)164 if (S->error_set_jmp_enabled)
166 return;165 return;
167 WAIT_SEM(&tcc_compile_sem);166 WAIT_SEM(&tcc_compile_sem);
168 tcc_state = s1;167 /*S = S;*/
169}168}
170 169
171PUB_FUNC void tcc_exit_state(TCCState *s1)170PUB_FUNC void tcc_exit_state(TCCState *S)
172{171{
173 if (s1->error_set_jmp_enabled)172 if (S->error_set_jmp_enabled)
174 return;173 return;
175 tcc_state = NULL;174 S = NULL;
176 POST_SEM(&tcc_compile_sem);175 POST_SEM(&tcc_compile_sem);
177}176}
178 177
@@ -234,10 +233,10 @@ PUB_FUNC char *tcc_fileextension (const char *name) · 55 unmodified lines
234 return e ? e : strchr(b, 0);233 return e ? e : strchr(b, 0);
235}234}
236 235
237ST_FUNC char *tcc_load_text(int fd)236ST_FUNC char *tcc_load_text(TCCState* S, int fd)
238{237{
239 int len = lseek(fd, 0, SEEK_END);238 int len = lseek(fd, 0, SEEK_END);
240 char *buf = load_data(fd, 0, len + 1);239 char *buf = load_data(S, fd, 0, len + 1);
241 buf[len] = 0;240 buf[len] = 0;
242 return buf;241 return buf;
243}242}
@@ -249,44 +248,69 @@ ST_FUNC char *tcc_load_text(int fd) · 5 unmodified lines
249#undef malloc248#undef malloc
250#undef realloc249#undef realloc
251 250
251PUB_FUNC void tcc_free_base(void *ptr)
252{
253 free(ptr);
254}
255
256PUB_FUNC void *tcc_malloc_base(unsigned long size)
257{
258 void *ptr;
259 ptr = malloc(size);
260 if (!ptr && size) {
261 printf("memory full (malloc)\n");
262 exit(1);
263 }
264 return ptr;
265}
266
267PUB_FUNC void *tcc_mallocz_base(unsigned long size)
268{
269 void *ptr;
270 ptr = tcc_malloc_base(size);
271 if (size)
272 memset(ptr, 0, size);
273 return ptr;
274}
275
252#ifndef MEM_DEBUG276#ifndef MEM_DEBUG
253 277
254PUB_FUNC void tcc_free(void *ptr)278PUB_FUNC void tcc_free(TCCState* S, void *ptr)
255{279{
256 free(ptr);280 free(ptr);
257}281}
258 282
259PUB_FUNC void *tcc_malloc(unsigned long size)283PUB_FUNC void *tcc_malloc(TCCState* S, unsigned long size)
260{284{
261 void *ptr;285 void *ptr;
262 ptr = malloc(size);286 ptr = malloc(size);
263 if (!ptr && size)287 if (!ptr && size)
264 _tcc_error("memory full (malloc)");288 _tcc_error(S, "memory full (malloc)");
265 return ptr;289 return ptr;
266}290}
267 291
268PUB_FUNC void *tcc_mallocz(unsigned long size)292PUB_FUNC void *tcc_mallocz(TCCState* S, unsigned long size)
269{293{
270 void *ptr;294 void *ptr;
271 ptr = tcc_malloc(size);295 ptr = tcc_malloc(S, size);
272 if (size)296 if (size)
273 memset(ptr, 0, size);297 memset(ptr, 0, size);
274 return ptr;298 return ptr;
275}299}
276 300
277PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size)301PUB_FUNC void *tcc_realloc(TCCState* S, void *ptr, unsigned long size)
278{302{
279 void *ptr1;303 void *ptr1;
280 ptr1 = realloc(ptr, size);304 ptr1 = realloc(ptr, size);
281 if (!ptr1 && size)305 if (!ptr1 && size)
282 _tcc_error("memory full (realloc)");306 _tcc_error(S, "memory full (realloc)");
283 return ptr1;307 return ptr1;
284}308}
285 309
286PUB_FUNC char *tcc_strdup(const char *str)310PUB_FUNC char *tcc_strdup(TCCState* S, const char *str)
287{311{
288 char *ptr;312 char *ptr;
289 ptr = tcc_malloc(strlen(str) + 1);313 ptr = tcc_malloc(S, strlen(str) + 1);
290 strcpy(ptr, str);314 strcpy(ptr, str);
291 return ptr;315 return ptr;
292}316}
@@ -337,14 +361,14 @@ static mem_debug_header_t *malloc_check(void *ptr, const char *msg) · 44 unmodified lines
337 return header;361 return header;
338}362}
339 363
340PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line)364PUB_FUNC void *tcc_malloc_debug(TCCState* S, unsigned long size, const char *file, int line)
341{365{
342 int ofs;366 int ofs;
343 mem_debug_header_t *header;367 mem_debug_header_t *header;
344 368
345 header = malloc(sizeof(mem_debug_header_t) + size);369 header = malloc(sizeof(mem_debug_header_t) + size);
346 if (!header)370 if (!header)
347 _tcc_error("memory full (malloc)");371 _tcc_error(S, "memory full (malloc)");
348 372
349 header->magic1 = MEM_DEBUG_MAGIC1;373 header->magic1 = MEM_DEBUG_MAGIC1;
350 header->magic2 = MEM_DEBUG_MAGIC2;374 header->magic2 = MEM_DEBUG_MAGIC2;
@@ -368,7 +392,7 @@ PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line) · 17 unmodified lines
368 return MEM_USER_PTR(header);392 return MEM_USER_PTR(header);
369}393}
370 394
371PUB_FUNC void tcc_free_debug(void *ptr)395PUB_FUNC void tcc_free_debug(TCCState* S, void *ptr)
372{396{
373 mem_debug_header_t *header;397 mem_debug_header_t *header;
374 if (!ptr)398 if (!ptr)
@@ -385,26 +409,26 @@ PUB_FUNC void tcc_free_debug(void *ptr) · 10 unmodified lines
385 free(header);409 free(header);
386}410}
387 411
388PUB_FUNC void *tcc_mallocz_debug(unsigned long size, const char *file, int line)412PUB_FUNC void *tcc_mallocz_debug(TCCState* S, unsigned long size, const char *file, int line)
389{413{
390 void *ptr;414 void *ptr;
391 ptr = tcc_malloc_debug(size,file,line);415 ptr = tcc_malloc_debug(S, size,file,line);
392 memset(ptr, 0, size);416 memset(ptr, 0, size);
393 return ptr;417 return ptr;
394}418}
395 419
396PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file, int line)420PUB_FUNC void *tcc_realloc_debug(TCCState* S, void *ptr, unsigned long size, const char *file, int line)
397{421{
398 mem_debug_header_t *header;422 mem_debug_header_t *header;
399 int mem_debug_chain_update = 0;423 int mem_debug_chain_update = 0;
400 if (!ptr)424 if (!ptr)
401 return tcc_malloc_debug(size, file, line);425 return tcc_malloc_debug(S, size, file, line);
402 header = malloc_check(ptr, "tcc_realloc");426 header = malloc_check(ptr, "tcc_realloc");
403 mem_cur_size -= header->size;427 mem_cur_size -= header->size;
404 mem_debug_chain_update = (header == mem_debug_chain);428 mem_debug_chain_update = (header == mem_debug_chain);
405 header = realloc(header, sizeof(mem_debug_header_t) + size);429 header = realloc(header, sizeof(mem_debug_header_t) + size);
406 if (!header)430 if (!header)
407 _tcc_error("memory full (realloc)");431 _tcc_error(S, "memory full (realloc)");
408 header->size = size;432 header->size = size;
409 write32le(MEM_DEBUG_CHECK3(header), MEM_DEBUG_MAGIC3);433 write32le(MEM_DEBUG_CHECK3(header), MEM_DEBUG_MAGIC3);
410 if (header->next)434 if (header->next)
@@ -419,10 +443,10 @@ PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file · 8 unmodified lines
419 return MEM_USER_PTR(header);443 return MEM_USER_PTR(header);
420}444}
421 445
422PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line)446PUB_FUNC char *tcc_strdup_debug(TCCState* S, const char *str, const char *file, int line)
423{447{
424 char *ptr;448 char *ptr;
425 ptr = tcc_malloc_debug(strlen(str) + 1, file, line);449 ptr = tcc_malloc_debug(S, strlen(str) + 1, file, line);
426 strcpy(ptr, str);450 strcpy(ptr, str);
427 return ptr;451 return ptr;
428}452}
@@ -449,10 +473,66 @@ PUB_FUNC void tcc_memcheck(void) · 20 unmodified lines
449#define malloc(s) use_tcc_malloc(s)473#define malloc(s) use_tcc_malloc(s)
450#define realloc(p, s) use_tcc_realloc(p, s)474#define realloc(p, s) use_tcc_realloc(p, s)
451 475
476/********************************************************/
477/* virtual io */
478
479LIBTCCAPI void tcc_set_vio_module(TCCState *S, vio_module_t *vio_module){
480 S->vio_module = vio_module;
481 vio_module->S = S;
482}
483
484void vio_initialize(vio_fd *fd) {
485 fd->fd = -1;
486 fd->vio_udata = NULL;
487 fd->vio_module = NULL;
488}
489
490int vio_open(struct TCCState *S, vio_fd *fd, const char *fn, int oflag) {
491 int rc;
492 vio_initialize(fd);
493 fd->vio_module = S->vio_module;
494 if(S->vio_module && (S->vio_module->call_vio_open_flags & CALL_VIO_OPEN_FIRST)) {
495 rc = S->vio_module->vio_open(fd, fn, oflag);
496 if(rc >= 0) return rc;
497 }
498
499 fd->fd = open(fn, oflag);
500
501 if(fd->fd < 0 && S->vio_module && (S->vio_module->call_vio_open_flags & CALL_VIO_OPEN_LAST)) {
502 rc = S->vio_module->vio_open(fd, fn, oflag);
503 if(rc >= 0) return rc;
504 }
505 //printf("vio_open = %d %s\n", fd->fd, fn);
506 return fd->fd;
507}
508
509off_t vio_lseek(vio_fd fd, off_t offset, int whence) {
510 if(fd.vio_udata) {
511 return fd.vio_module->vio_lseek(fd, offset, whence);
512 }
513 return lseek(fd.fd, offset, whence);
514}
515
516size_t vio_read(vio_fd fd, void *buf, size_t bytes) {
517 if(fd.vio_udata) {
518 return fd.vio_module->vio_read(fd, buf, bytes);
519 }
520 return read(fd.fd, buf, bytes);
521}
522
523int vio_close(vio_fd *fd) {
524 int rc = 0;
525 if(fd->vio_udata){
526 fd->vio_module->vio_close(fd);
527 } else rc = close(fd->fd);
528 vio_initialize(fd);
529 return rc;
530}
531
452/********************************************************/532/********************************************************/
453/* dynarrays */533/* dynarrays */
454 534
455ST_FUNC void dynarray_add(void *ptab, int *nb_ptr, void *data)535ST_FUNC void dynarray_add(TCCState* S, void *ptab, int *nb_ptr, void *data)
456{536{
457 int nb, nb_alloc;537 int nb, nb_alloc;
458 void **pp;538 void **pp;
@@ -465,54 +545,54 @@ ST_FUNC void dynarray_add(void *ptab, int *nb_ptr, void *data) · 6 unmodified lines
465 nb_alloc = 1;545 nb_alloc = 1;
466 else546 else
467 nb_alloc = nb * 2;547 nb_alloc = nb * 2;
468 pp = tcc_realloc(pp, nb_alloc * sizeof(void *));548 pp = tcc_realloc(S, pp, nb_alloc * sizeof(void *));
469 *(void***)ptab = pp;549 *(void***)ptab = pp;
470 }550 }
471 pp[nb++] = data;551 pp[nb++] = data;
472 *nb_ptr = nb;552 *nb_ptr = nb;
473}553}
474 554
475ST_FUNC void dynarray_reset(void *pp, int *n)555ST_FUNC void dynarray_reset(TCCState* S, void *pp, int *n)
476{556{
477 void **p;557 void **p;
478 for (p = *(void***)pp; *n; ++p, --*n)558 for (p = *(void***)pp; *n; ++p, --*n)
479 if (*p)559 if (*p)
480 tcc_free(*p);560 tcc_free(S, *p);
481 tcc_free(*(void**)pp);561 tcc_free(S, *(void**)pp);
482 *(void**)pp = NULL;562 *(void**)pp = NULL;
483}563}
484 564
485static void tcc_split_path(TCCState *s, void *p_ary, int *p_nb_ary, const char *in)565static void tcc_split_path(TCCState *S, void *p_ary, int *p_nb_ary, const char *in)
486{566{
487 const char *p;567 const char *p;
488 do {568 do {
489 int c;569 int c;
490 CString str;570 CString str;
491 571
492 cstr_new(&str);572 cstr_new(S, &str);
493 for (p = in; c = *p, c != '\0' && c != PATHSEP[0]; ++p) {573 for (p = in; c = *p, c != '\0' && c != PATHSEP[0]; ++p) {
494 if (c == '{' && p[1] && p[2] == '}') {574 if (c == '{' && p[1] && p[2] == '}') {
495 c = p[1], p += 2;575 c = p[1], p += 2;
496 if (c == 'B')576 if (c == 'B')
497 cstr_cat(&str, s->tcc_lib_path, -1);577 cstr_cat(S, &str, S->tcc_lib_path, -1);
498 if (c == 'f' && file) {578 if (c == 'f' && S->tccpp_file) {
499 /* substitute current file's dir */579 /* substitute current file's dir */
500 const char *f = file->true_filename;580 const char *f = S->tccpp_file->true_filename;
501 const char *b = tcc_basename(f);581 const char *b = tcc_basename(f);
502 if (b > f)582 if (b > f)
503 cstr_cat(&str, f, b - f - 1);583 cstr_cat(S, &str, f, b - f - 1);
504 else584 else
505 cstr_cat(&str, ".", 1);585 cstr_cat(S, &str, ".", 1);
506 }586 }
507 } else {587 } else {
508 cstr_ccat(&str, c);588 cstr_ccat(S, &str, c);
509 }589 }
510 }590 }
511 if (str.size) {591 if (str.size) {
512 cstr_ccat(&str, '\0');592 cstr_ccat(S, &str, '\0');
513 dynarray_add(p_ary, p_nb_ary, tcc_strdup(str.data));593 dynarray_add(S, p_ary, p_nb_ary, tcc_strdup(S, str.data));
514 }594 }
515 cstr_free(&str);595 cstr_free(S, &str);
516 in = p+1;596 in = p+1;
517 } while (*p);597 } while (*p);
518}598}
@@ -528,27 +608,26 @@ static void tcc_split_path(TCCState *s, void *p_ary, int *p_nb_ary, const char * · 9 unmodified lines
528/* error1() modes */608/* error1() modes */
529enum { ERROR_WARN, ERROR_NOABORT, ERROR_ERROR };609enum { ERROR_WARN, ERROR_NOABORT, ERROR_ERROR };
530 610
531static void error1(int mode, const char *fmt, va_list ap)611static void error1(TCCState* S, int mode, const char *fmt, va_list ap)
532{612{
533 BufferedFile **pf, *f;613 BufferedFile **pf, *f;
534 TCCState *s1 = tcc_state;
535 CString cs;614 CString cs;
536 615
537 cstr_new(&cs);616 cstr_new(S, &cs);
538 617
539 if (s1 == NULL)618 if (S == NULL)
540 /* can happen only if called from tcc_malloc(): 'out of memory' */619 /* can happen only if called from tcc_malloc(): 'out of memory' */
541 goto no_file;620 goto no_file;
542 621
543 tcc_exit_state(s1);622 tcc_exit_state(S);
544 623
545 if (mode == ERROR_WARN) {624 if (mode == ERROR_WARN) {
546 if (s1->warn_error)625 if (S->warn_error)
547 mode = ERROR_ERROR;626 mode = ERROR_ERROR;
548 if (s1->warn_num) {627 if (S->warn_num) {
549 /* handle tcc_warning_c(warn_option)(fmt, ...) */628 /* handle tcc_warning_c(warn_option)(fmt, ...) */
550 int wopt = *(&s1->warn_none + s1->warn_num);629 int wopt = *(&S->warn_none + S->warn_num);
551 s1->warn_num = 0;630 S->warn_num = 0;
552 if (0 == (wopt & WARN_ON))631 if (0 == (wopt & WARN_ON))
553 return;632 return;
554 if (wopt & WARN_ERR)633 if (wopt & WARN_ERR)
@@ -556,102 +635,102 @@ static void error1(int mode, const char *fmt, va_list ap) · 1 unmodified line
556 if (wopt & WARN_NOE)635 if (wopt & WARN_NOE)
557 mode = ERROR_WARN;636 mode = ERROR_WARN;
558 }637 }
559 if (s1->warn_none)638 if (S->warn_none)
560 return;639 return;
561 }640 }
562 641
563 f = NULL;642 f = NULL;
564 if (s1->error_set_jmp_enabled) { /* we're called while parsing a file */643 if (S->error_set_jmp_enabled) { /* we're called while parsing a file */
565 /* use upper file if inline ":asm:" or token ":paste:" */644 /* use upper file if inline ":asm:" or token ":paste:" */
566 for (f = file; f && f->filename[0] == ':'; f = f->prev)645 for (f = S->tccpp_file; f && f->filename[0] == ':'; f = f->prev)
567 ;646 ;
568 }647 }
569 if (f) {648 if (f) {
570 for(pf = s1->include_stack; pf < s1->include_stack_ptr; pf++)649 for(pf = S->include_stack; pf < S->include_stack_ptr; pf++)
571 cstr_printf(&cs, "In file included from %s:%d:\n",650 cstr_printf(S, &cs, "In file included from %s:%d:\n",
572 (*pf)->filename, (*pf)->line_num);651 (*pf)->filename, (*pf)->line_num);
573 cstr_printf(&cs, "%s:%d: ",652 cstr_printf(S, &cs, "%s:%d: ",
574 f->filename, f->line_num - !!(tok_flags & TOK_FLAG_BOL));653 f->filename, (*pf)->line_num - !!(S->tccpp_tok_flags & TOK_FLAG_BOL));
575 } else if (s1->current_filename) {654 } else if (S->current_filename) {
576 cstr_printf(&cs, "%s: ", s1->current_filename);655 cstr_printf(S, &cs, "%s: ", S->current_filename);
577 }656 }
578 657
579no_file:658no_file:
580 if (0 == cs.size)659 if (0 == cs.size)
581 cstr_printf(&cs, "tcc: ");660 cstr_printf(S, &cs, "tcc: ");
582 cstr_printf(&cs, mode == ERROR_WARN ? "warning: " : "error: ");661 cstr_printf(S, &cs, mode == ERROR_WARN ? "warning: " : "error: ");
583 cstr_vprintf(&cs, fmt, ap);662 cstr_vprintf(S, &cs, fmt, ap);
584 if (!s1 || !s1->error_func) {663 if (!S || !S->error_func) {
585 /* default case: stderr */664 /* default case: stderr */
586 if (s1 && s1->output_type == TCC_OUTPUT_PREPROCESS && s1->ppfp == stdout)665 if (S && S->output_type == TCC_OUTPUT_PREPROCESS && S->ppfp == stdout)
587 printf("\n"); /* print a newline during tcc -E */666 printf("\n"); /* print a newline during tcc -E */
588 fflush(stdout); /* flush -v output */667 fflush(stdout); /* flush -v output */
589 fprintf(stderr, "%s\n", (char*)cs.data);668 fprintf(stderr, "%s\n", (char*)cs.data);
590 fflush(stderr); /* print error/warning now (win32) */669 fflush(stderr); /* print error/warning now (win32) */
591 } else {670 } else {
592 s1->error_func(s1->error_opaque, (char*)cs.data);671 S->error_func(S->error_opaque, (char*)cs.data);
593 }672 }
594 cstr_free(&cs);673 cstr_free(S, &cs);
595 if (s1) {674 if (S) {
596 if (mode != ERROR_WARN)675 if (mode != ERROR_WARN)
597 s1->nb_errors++;676 S->nb_errors++;
598 if (mode != ERROR_ERROR)677 if (mode != ERROR_ERROR)
599 return;678 return;
600 if (s1->error_set_jmp_enabled)679 if (S->error_set_jmp_enabled)
601 longjmp(s1->error_jmp_buf, 1);680 longjmp(S->error_jmp_buf, 1);
602 }681 }
603 exit(1);682 exit(1);
604}683}
605 684
606LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque, TCCErrorFunc error_func)685LIBTCCAPI void tcc_set_error_func(TCCState *S, void *error_opaque, TCCErrorFunc error_func)
607{686{
608 s->error_opaque = error_opaque;687 S->error_opaque = error_opaque;
609 s->error_func = error_func;688 S->error_func = error_func;
610}689}
611 690
612LIBTCCAPI TCCErrorFunc tcc_get_error_func(TCCState *s)691LIBTCCAPI TCCErrorFunc tcc_get_error_func(TCCState *S)
613{692{
614 return s->error_func;693 return S->error_func;
615}694}
616 695
617LIBTCCAPI void *tcc_get_error_opaque(TCCState *s)696LIBTCCAPI void *tcc_get_error_opaque(TCCState *S)
618{697{
619 return s->error_opaque;698 return S->error_opaque;
620}699}
621 700
622/* error without aborting current compilation */701/* error without aborting current compilation */
623PUB_FUNC void _tcc_error_noabort(const char *fmt, ...)702PUB_FUNC void _tcc_error_noabort(TCCState* S, const char *fmt, ...)
624{703{
625 va_list ap;704 va_list ap;
626 va_start(ap, fmt);705 va_start(ap, fmt);
627 error1(ERROR_NOABORT, fmt, ap);706 error1(S, ERROR_NOABORT, fmt, ap);
628 va_end(ap);707 va_end(ap);
629}708}
630 709
631PUB_FUNC void _tcc_error(const char *fmt, ...)710PUB_FUNC void _tcc_error(TCCState* S, const char *fmt, ...)
632{711{
633 va_list ap;712 va_list ap;
634 va_start(ap, fmt);713 va_start(ap, fmt);
635 for (;;) error1(ERROR_ERROR, fmt, ap);714 for (;;) error1(S, ERROR_ERROR, fmt, ap);
636}715}
637 716
638PUB_FUNC void _tcc_warning(const char *fmt, ...)717PUB_FUNC void _tcc_warning(TCCState* S, const char *fmt, ...)
639{718{
640 va_list ap;719 va_list ap;
641 va_start(ap, fmt);720 va_start(ap, fmt);
642 error1(ERROR_WARN, fmt, ap);721 error1(S, ERROR_WARN, fmt, ap);
643 va_end(ap);722 va_end(ap);
644}723}
645 724
646/********************************************************/725/********************************************************/
647/* I/O layer */726/* I/O layer */
648 727
649ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen)728ST_FUNC void tcc_open_bf(TCCState *S, const char *filename, int initlen)
650{729{
651 BufferedFile *bf;730 BufferedFile *bf;
652 int buflen = initlen ? initlen : IO_BUF_SIZE;731 int buflen = initlen ? initlen : IO_BUF_SIZE;
653 732
654 bf = tcc_mallocz(sizeof(BufferedFile) + buflen);733 bf = tcc_mallocz(S, sizeof(BufferedFile) + buflen);
655 bf->buf_ptr = bf->buffer;734 bf->buf_ptr = bf->buffer;
656 bf->buf_end = bf->buffer + initlen;735 bf->buf_end = bf->buffer + initlen;
657 bf->buf_end[0] = CH_EOB; /* put eob symbol */736 bf->buf_end[0] = CH_EOB; /* put eob symbol */
@@ -661,52 +740,51 @@ ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen) · 3 unmodified lines
661#endif740#endif
662 bf->true_filename = bf->filename;741 bf->true_filename = bf->filename;
663 bf->line_num = 1;742 bf->line_num = 1;
664 bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;743 bf->ifdef_stack_ptr = S->ifdef_stack_ptr;
665 bf->fd = -1;744 bf->fd = -1;
666 bf->prev = file;745 bf->prev = S->tccpp_file;
667 file = bf;746 S->tccpp_file = bf;
668 tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;747 S->tccpp_tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
669}748}
670 749
671ST_FUNC void tcc_close(void)750ST_FUNC void tcc_close(TCCState* S)
672{751{
673 TCCState *s1 = tcc_state;752 BufferedFile *bf = S->tccpp_file;
674 BufferedFile *bf = file;
675 if (bf->fd > 0) {753 if (bf->fd > 0) {
676 close(bf->fd);754 close(bf->fd);
677 total_lines += bf->line_num;755 total_lines += bf->line_num;
678 }756 }
679 if (bf->true_filename != bf->filename)757 if (bf->true_filename != bf->filename)
680 tcc_free(bf->true_filename);758 tcc_free(S, bf->true_filename);
681 file = bf->prev;759 S->tccpp_file = bf->prev;
682 tcc_free(bf);760 tcc_free(S, bf);
683}761}
684 762
685static int _tcc_open(TCCState *s1, const char *filename)763static int _tcc_open(TCCState *S, const char *filename)
686{764{
687 int fd;765 int fd;
688 if (strcmp(filename, "-") == 0)766 if (strcmp(filename, "-") == 0)
689 fd = 0, filename = "<stdin>";767 fd = 0, filename = "<stdin>";
690 else768 else
691 fd = open(filename, O_RDONLY | O_BINARY);769 fd = open(filename, O_RDONLY | O_BINARY);
692 if ((s1->verbose == 2 && fd >= 0) || s1->verbose == 3)770 if ((S->verbose == 2 && fd >= 0) || S->verbose == 3)
693 printf("%s %*s%s\n", fd < 0 ? "nf":"->",771 printf("%s %*s%s\n", fd < 0 ? "nf":"->",
694 (int)(s1->include_stack_ptr - s1->include_stack), "", filename);772 (int)(S->include_stack_ptr - S->include_stack), "", filename);
695 return fd;773 return fd;
696}774}
697 775
698ST_FUNC int tcc_open(TCCState *s1, const char *filename)776ST_FUNC int tcc_open(TCCState *S, const char *filename)
699{777{
700 int fd = _tcc_open(s1, filename);778 int fd = _tcc_open(S, filename);
701 if (fd < 0)779 if (fd < 0)
702 return -1;780 return -1;
703 tcc_open_bf(s1, filename, 0);781 tcc_open_bf(S, filename, 0);
704 file->fd = fd;782 S->tccpp_file->fd = fd;
705 return 0;783 return 0;
706}784}
707 785
708/* compile the file opened in 'file'. Return non zero if errors. */786/* compile the file opened in 'file'. Return non zero if errors. */
709static int tcc_compile(TCCState *s1, int filetype, const char *str, int fd)787static int tcc_compile(TCCState *S, int filetype, const char *str, int fd)
710{788{
711 /* Here we enter the code section where we use the global variables for789 /* Here we enter the code section where we use the global variables for
712 parsing and code generation (tccpp.c, tccgen.c, <target>-gen.c).790 parsing and code generation (tccpp.c, tccgen.c, <target>-gen.c).
@@ -715,62 +793,62 @@ static int tcc_compile(TCCState *s1, int filetype, const char *str, int fd) · 2 unmodified lines
715 Alternatively we could use thread local storage for those global793 Alternatively we could use thread local storage for those global
716 variables, which may or may not have advantages */794 variables, which may or may not have advantages */
717 795
718 tcc_enter_state(s1);796 tcc_enter_state(S);
719 s1->error_set_jmp_enabled = 1;797 S->error_set_jmp_enabled = 1;
720 798
721 if (setjmp(s1->error_jmp_buf) == 0) {799 if (setjmp(S->error_jmp_buf) == 0) {
722 s1->nb_errors = 0;800 S->nb_errors = 0;
723 801
724 if (fd == -1) {802 if (fd == -1) {
725 int len = strlen(str);803 int len = strlen(str);
726 tcc_open_bf(s1, "<string>", len);804 tcc_open_bf(S, "<string>", len);
727 memcpy(file->buffer, str, len);805 memcpy(S->tccpp_file->buffer, str, len);
728 } else {806 } else {
729 tcc_open_bf(s1, str, 0);807 tcc_open_bf(S, str, 0);
730 file->fd = fd;808 S->tccpp_file->fd = fd;
731 }809 }
732 810
733 tccelf_begin_file(s1);811 tccelf_begin_file(S);
734 preprocess_start(s1, filetype);812 preprocess_start(S, filetype);
735 tccgen_init(s1);813 tccgen_init(S);
736 if (s1->output_type == TCC_OUTPUT_PREPROCESS) {814 if (S->output_type == TCC_OUTPUT_PREPROCESS) {
737 tcc_preprocess(s1);815 tcc_preprocess(S);
738 } else if (filetype & (AFF_TYPE_ASM | AFF_TYPE_ASMPP)) {816 } else if (filetype & (AFF_TYPE_ASM | AFF_TYPE_ASMPP)) {
739 tcc_assemble(s1, !!(filetype & AFF_TYPE_ASMPP));817 tcc_assemble(S, !!(filetype & AFF_TYPE_ASMPP));
740 } else {818 } else {
741 tccgen_compile(s1);819 tccgen_compile(S);
742 }820 }
743 }821 }
744 tccgen_finish(s1);822 tccgen_finish(S);
745 preprocess_end(s1);823 preprocess_end(S);
746 824
747 s1->error_set_jmp_enabled = 0;825 S->error_set_jmp_enabled = 0;
748 tcc_exit_state(s1);826 tcc_exit_state(S);
749 827
750 tccelf_end_file(s1);828 tccelf_end_file(S);
751 return s1->nb_errors != 0 ? -1 : 0;829 return S->nb_errors != 0 ? -1 : 0;
752}830}
753 831
754LIBTCCAPI int tcc_compile_string(TCCState *s, const char *str)832LIBTCCAPI int tcc_compile_string(TCCState *S, const char *str)
755{833{
756 return tcc_compile(s, s->filetype, str, -1);834 return tcc_compile(S, S->filetype, str, -1);
757}835}
758 836
759/* define a preprocessor symbol. value can be NULL, sym can be "sym=val" */837/* define a preprocessor symbol. value can be NULL, sym can be "sym=val" */
760LIBTCCAPI void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)838LIBTCCAPI void tcc_define_symbol(TCCState *S, const char *sym, const char *value)
761{839{
762 const char *eq;840 const char *eq;
763 if (NULL == (eq = strchr(sym, '=')))841 if (NULL == (eq = strchr(sym, '=')))
764 eq = strchr(sym, 0);842 eq = strchr(sym, 0);
765 if (NULL == value)843 if (NULL == value)
766 value = *eq ? eq + 1 : "1";844 value = *eq ? eq + 1 : "1";
767 cstr_printf(&s1->cmdline_defs, "#define %.*s %s\n", (int)(eq-sym), sym, value);845 cstr_printf(S, &S->cmdline_defs, "#define %.*s %s\n", (int)(eq-sym), sym, value);
768}846}
769 847
770/* undefine a preprocessor symbol */848/* undefine a preprocessor symbol */
771LIBTCCAPI void tcc_undefine_symbol(TCCState *s1, const char *sym)849LIBTCCAPI void tcc_undefine_symbol(TCCState *S, const char *sym)
772{850{
773 cstr_printf(&s1->cmdline_defs, "#undef %s\n", sym);851 cstr_printf(S, &S->cmdline_defs, "#undef %s\n", sym);
774}852}
775 853
776 854
@@ -778,7 +856,7 @@ LIBTCCAPI TCCState *tcc_new(void) · 1 unmodified line
778{856{
779 TCCState *s;857 TCCState *s;
780 858
781 s = tcc_mallocz(sizeof(TCCState));859 s = tcc_mallocz_base(sizeof(TCCState));
782 if (!s)860 if (!s)
783 return NULL;861 return NULL;
784#ifdef MEM_DEBUG862#ifdef MEM_DEBUG
@@ -820,153 +898,153 @@ LIBTCCAPI TCCState *tcc_new(void) · 35 unmodified lines
820 return s;898 return s;
821}899}
822 900
823LIBTCCAPI void tcc_delete(TCCState *s1)901LIBTCCAPI void tcc_delete(TCCState *S)
824{902{
825 /* free sections */903 /* free sections */
826 tccelf_delete(s1);904 tccelf_delete(S);
827 905
828 /* free library paths */906 /* free library paths */
829 dynarray_reset(&s1->library_paths, &s1->nb_library_paths);907 dynarray_reset(S, &S->library_paths, &S->nb_library_paths);
830 dynarray_reset(&s1->crt_paths, &s1->nb_crt_paths);908 dynarray_reset(S, &S->crt_paths, &S->nb_crt_paths);
831 909
832 /* free include paths */910 /* free include paths */
833 dynarray_reset(&s1->include_paths, &s1->nb_include_paths);911 dynarray_reset(S, &S->include_paths, &S->nb_include_paths);
834 dynarray_reset(&s1->sysinclude_paths, &s1->nb_sysinclude_paths);912 dynarray_reset(S, &S->sysinclude_paths, &S->nb_sysinclude_paths);
835 913
836 tcc_free(s1->tcc_lib_path);914 tcc_free(S, S->tcc_lib_path);
837 tcc_free(s1->soname);915 tcc_free(S, S->soname);
838 tcc_free(s1->rpath);916 tcc_free(S, S->rpath);
839 tcc_free(s1->init_symbol);917 tcc_free(S, S->init_symbol);
840 tcc_free(s1->fini_symbol);918 tcc_free(S, S->fini_symbol);
841 tcc_free(s1->outfile);919 tcc_free(S, S->outfile);
842 tcc_free(s1->deps_outfile);920 tcc_free(S, S->deps_outfile);
843 dynarray_reset(&s1->files, &s1->nb_files);921 dynarray_reset(S, &S->files, &S->nb_files);
844 dynarray_reset(&s1->target_deps, &s1->nb_target_deps);922 dynarray_reset(S, &S->target_deps, &S->nb_target_deps);
845 dynarray_reset(&s1->pragma_libs, &s1->nb_pragma_libs);923 dynarray_reset(S, &S->pragma_libs, &S->nb_pragma_libs);
846 dynarray_reset(&s1->argv, &s1->argc);924 dynarray_reset(S, &S->argv, &S->argc);
847 cstr_free(&s1->cmdline_defs);925 cstr_free(S, &S->cmdline_defs);
848 cstr_free(&s1->cmdline_incl);926 cstr_free(S, &S->cmdline_incl);
849#ifdef TCC_IS_NATIVE927#ifdef TCC_IS_NATIVE
850 /* free runtime memory */928 /* free runtime memory */
851 tcc_run_free(s1);929 tcc_run_free(S);
852#endif930#endif
853 931
854 tcc_free(s1);932 tcc_free_base(S);
855#ifdef MEM_DEBUG933#ifdef MEM_DEBUG
856 if (0 == --nb_states)934 if (0 == --nb_states)
857 tcc_memcheck();935 tcc_memcheck();
858#endif936#endif
859}937}
860 938
861LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)939LIBTCCAPI int tcc_set_output_type(TCCState *S, int output_type)
862{940{
863 s->output_type = output_type;941 S->output_type = output_type;
864 942
865 if (!s->nostdinc) {943 if (!S->nostdinc) {
866 /* default include paths */944 /* default include paths */
867 /* -isystem paths have already been handled */945 /* -isystem paths have already been handled */
868 tcc_add_sysinclude_path(s, CONFIG_TCC_SYSINCLUDEPATHS);946 tcc_add_sysinclude_path(S, CONFIG_TCC_SYSINCLUDEPATHS);
869 }947 }
870#ifdef CONFIG_TCC_BCHECK948#ifdef CONFIG_TCC_BCHECK
871 if (s->do_bounds_check) {949 if (S->do_bounds_check) {
872 /* if bound checking, then add corresponding sections */950 /* if bound checking, then add corresponding sections */
873 tccelf_bounds_new(s);951 tccelf_bounds_new(S);
874 }952 }
875#endif953#endif
876 if (s->do_debug) {954 if (S->do_debug) {
877 /* add debug sections */955 /* add debug sections */
878 tccelf_stab_new(s);956 tccelf_stab_new(S);
879 }957 }
880 if (output_type == TCC_OUTPUT_OBJ) {958 if (output_type == TCC_OUTPUT_OBJ) {
881 /* always elf for objects */959 /* always elf for objects */
882 s->output_format = TCC_OUTPUT_FORMAT_ELF;960 S->output_format = TCC_OUTPUT_FORMAT_ELF;
883 return 0;961 return 0;
884 }962 }
885 963
886 tcc_add_library_path(s, CONFIG_TCC_LIBPATHS);964 tcc_add_library_path(S, CONFIG_TCC_LIBPATHS);
887 965
888#ifdef TCC_TARGET_PE966#ifdef TCC_TARGET_PE
889# ifdef _WIN32967# ifdef _WIN32
890 /* allow linking with system dll's directly */968 /* allow linking with system dll's directly */
891 tcc_add_systemdir(s);969 tcc_add_systemdir(S);
892# endif970# endif
893 /* target PE has its own startup code in libtcc1.a */971 /* target PE has its own startup code in libtcc1.a */
894 return 0;972 return 0;
895 973
896#elif defined TCC_TARGET_MACHO974#elif defined TCC_TARGET_MACHO
897# ifdef TCC_IS_NATIVE975# ifdef TCC_IS_NATIVE
898 tcc_add_macos_sdkpath(s);976 tcc_add_macos_sdkpath(S);
899# endif977# endif
900 /* Mach-O with LC_MAIN doesn't need any crt startup code. */978 /* Mach-O with LC_MAIN doesn't need any crt startup code. */
901 return 0;979 return 0;
902 980
903#else981#else
904 /* paths for crt objects */982 /* paths for crt objects */
905 tcc_split_path(s, &s->crt_paths, &s->nb_crt_paths, CONFIG_TCC_CRTPREFIX);983 tcc_split_path(S, &S->crt_paths, &S->nb_crt_paths, CONFIG_TCC_CRTPREFIX);
906 /* add libc crt1/crti objects */984 /* add libc crt1/crti objects */
907 if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) &&985 if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) &&
908 !s->nostdlib) {986 !S->nostdlib) {
909#if TARGETOS_OpenBSD987#if TARGETOS_OpenBSD
910 if (output_type != TCC_OUTPUT_DLL)988 if (output_type != TCC_OUTPUT_DLL)
911 tcc_add_crt(s, "crt0.o");989 tcc_add_crt(S, "crt0.o");
912 if (output_type == TCC_OUTPUT_DLL)990 if (output_type == TCC_OUTPUT_DLL)
913 tcc_add_crt(s, "crtbeginS.o");991 tcc_add_crt(S, "crtbeginS.o");
914 else992 else
915 tcc_add_crt(s, "crtbegin.o");993 tcc_add_crt(S, "crtbegin.o");
916#elif TARGETOS_FreeBSD994#elif TARGETOS_FreeBSD
917 if (output_type != TCC_OUTPUT_DLL)995 if (output_type != TCC_OUTPUT_DLL)
918 tcc_add_crt(s, "crt1.o");996 tcc_add_crt(S, "crt1.o");
919 tcc_add_crt(s, "crti.o");997 tcc_add_crt(S, "crti.o");
920 if (s->static_link)998 if (S->static_link)
921 tcc_add_crt(s, "crtbeginT.o");999 tcc_add_crt(S, "crtbeginT.o");
922 else if (output_type == TCC_OUTPUT_DLL)1000 else if (output_type == TCC_OUTPUT_DLL)
923 tcc_add_crt(s, "crtbeginS.o");1001 tcc_add_crt(S, "crtbeginS.o");
924 else1002 else
925 tcc_add_crt(s, "crtbegin.o");1003 tcc_add_crt(S, "crtbegin.o");
926#elif TARGETOS_NetBSD1004#elif TARGETOS_NetBSD
927 if (output_type != TCC_OUTPUT_DLL)1005 if (output_type != TCC_OUTPUT_DLL)
928 tcc_add_crt(s, "crt0.o");1006 tcc_add_crt(S, "crt0.o");
929 tcc_add_crt(s, "crti.o");1007 tcc_add_crt(S, "crti.o");
930 if (s->static_link)1008 if (S->static_link)
931 tcc_add_crt(s, "crtbeginT.o");1009 tcc_add_crt(S, "crtbeginT.o");
932 else if (output_type == TCC_OUTPUT_DLL)1010 else if (output_type == TCC_OUTPUT_DLL)
933 tcc_add_crt(s, "crtbeginS.o");1011 tcc_add_crt(S, "crtbeginS.o");
934 else1012 else
935 tcc_add_crt(s, "crtbegin.o");1013 tcc_add_crt(S, "crtbegin.o");
936#else1014#else
937 if (output_type != TCC_OUTPUT_DLL)1015 if (output_type != TCC_OUTPUT_DLL)
938 tcc_add_crt(s, "crt1.o");1016 tcc_add_crt(S, "crt1.o");
939 tcc_add_crt(s, "crti.o");1017 tcc_add_crt(S, "crti.o");
940#endif1018#endif
941 }1019 }
942 return 0;1020 return 0;
943#endif1021#endif
944}1022}
945 1023
946LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname)1024LIBTCCAPI int tcc_add_include_path(TCCState *S, const char *pathname)
947{1025{
948 tcc_split_path(s, &s->include_paths, &s->nb_include_paths, pathname);1026 tcc_split_path(S, &S->include_paths, &S->nb_include_paths, pathname);
949 return 0;1027 return 0;
950}1028}
951 1029
952LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname)1030LIBTCCAPI int tcc_add_sysinclude_path(TCCState *S, const char *pathname)
953{1031{
954 tcc_split_path(s, &s->sysinclude_paths, &s->nb_sysinclude_paths, pathname);1032 tcc_split_path(S, &S->sysinclude_paths, &S->nb_sysinclude_paths, pathname);
955 return 0;1033 return 0;
956}1034}
957 1035
958ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllname)1036ST_FUNC DLLReference *tcc_add_dllref(TCCState *S, const char *dllname)
959{1037{
960 DLLReference *ref = tcc_mallocz(sizeof(DLLReference) + strlen(dllname));1038 DLLReference *ref = tcc_mallocz(S, sizeof(DLLReference) + strlen(dllname));
961 strcpy(ref->name, dllname);1039 strcpy(ref->name, dllname);
962 dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, ref);1040 dynarray_add(S, &S->loaded_dlls, &S->nb_loaded_dlls, ref);
963 return ref;1041 return ref;
964}1042}
965 1043
966/* OpenBSD: choose latest from libxxx.so.x.y versions */1044/* OpenBSD: choose latest from libxxx.so.x.y versions */
967#if defined TARGETOS_OpenBSD && !defined _WIN321045#if defined TARGETOS_OpenBSD && !defined _WIN32
968#include <glob.h>1046#include <glob.h>
969static int tcc_glob_so(TCCState *s1, const char *pattern, char *buf, int size)1047static int tcc_glob_so(TCCState *S, const char *pattern, char *buf, int size)
970{1048{
971 const char *star;1049 const char *star;
972 glob_t g;1050 glob_t g;
@@ -988,25 +1066,25 @@ static int tcc_glob_so(TCCState *s1, const char *pattern, char *buf, int size) · 15 unmodified lines
988}1066}
989#endif1067#endif
990 1068
991ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)1069ST_FUNC int tcc_add_file_internal(TCCState *S, const char *filename, int flags)
992{1070{
993 int fd, ret = -1;1071 int fd, ret = -1;
994 1072
995#if defined TARGETOS_OpenBSD && !defined _WIN321073#if defined TARGETOS_OpenBSD && !defined _WIN32
996 char buf[1024];1074 char buf[1024];
997 if (tcc_glob_so(s1, filename, buf, sizeof buf) >= 0)1075 if (tcc_glob_so(S, filename, buf, sizeof buf) >= 0)
998 filename = buf;1076 filename = buf;
999#endif1077#endif
1000 1078
1001 /* open the file */1079 /* open the file */
1002 fd = _tcc_open(s1, filename);1080 fd = _tcc_open(S, filename);
1003 if (fd < 0) {1081 if (fd < 0) {
1004 if (flags & AFF_PRINT_ERROR)1082 if (flags & AFF_PRINT_ERROR)
1005 tcc_error_noabort("file '%s' not found", filename);1083 tcc_error_noabort(S, "file '%s' not found", filename);
1006 return ret;1084 return ret;
1007 }1085 }
1008 1086
1009 s1->current_filename = filename;1087 S->current_filename = filename;
1010 if (flags & AFF_TYPE_BIN) {1088 if (flags & AFF_TYPE_BIN) {
1011 ElfW(Ehdr) ehdr;1089 ElfW(Ehdr) ehdr;
1012 int obj_type;1090 int obj_type;
@@ -1017,22 +1095,22 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 4 unmodified lines
1017 switch (obj_type) {1095 switch (obj_type) {
1018 1096
1019 case AFF_BINTYPE_REL:1097 case AFF_BINTYPE_REL:
1020 ret = tcc_load_object_file(s1, fd, 0);1098 ret = tcc_load_object_file(S, fd, 0);
1021 break;1099 break;
1022 1100
1023 case AFF_BINTYPE_AR:1101 case AFF_BINTYPE_AR:
1024 ret = tcc_load_archive(s1, fd, !(flags & AFF_WHOLE_ARCHIVE));1102 ret = tcc_load_archive(S, fd, !(flags & AFF_WHOLE_ARCHIVE));
1025 break;1103 break;
1026 1104
1027#ifdef TCC_TARGET_PE1105#ifdef TCC_TARGET_PE
1028 default:1106 default:
1029 ret = pe_load_file(s1, fd, filename);1107 ret = pe_load_file(S, fd, filename);
1030 goto check_success;1108 goto check_success;
1031 1109
1032#elif defined TCC_TARGET_MACHO1110#elif defined TCC_TARGET_MACHO
1033 case AFF_BINTYPE_DYN:1111 case AFF_BINTYPE_DYN:
1034 case_dyn_or_tbd:1112 case_dyn_or_tbd:
1035 if (s1->output_type == TCC_OUTPUT_MEMORY) {1113 if (S->output_type == TCC_OUTPUT_MEMORY) {
1036#ifdef TCC_IS_NATIVE1114#ifdef TCC_IS_NATIVE
1037 void* dl;1115 void* dl;
1038 const char* soname = filename;1116 const char* soname = filename;
@@ -1040,14 +1118,14 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 1 unmodified line
1040 soname = macho_tbd_soname(filename);1118 soname = macho_tbd_soname(filename);
1041 dl = dlopen(soname, RTLD_GLOBAL | RTLD_LAZY);1119 dl = dlopen(soname, RTLD_GLOBAL | RTLD_LAZY);
1042 if (dl)1120 if (dl)
1043 tcc_add_dllref(s1, soname)->handle = dl, ret = 0;1121 tcc_add_dllref(S, soname)->handle = dl, ret = 0;
1044 if (filename != soname)1122 if (filename != soname)
1045 tcc_free((void *)soname);1123 tcc_free(S, (void *)soname);
1046#endif1124#endif
1047 } else if (obj_type == AFF_BINTYPE_DYN) {1125 } else if (obj_type == AFF_BINTYPE_DYN) {
1048 ret = macho_load_dll(s1, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);1126 ret = macho_load_dll(S, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);
1049 } else {1127 } else {
1050 ret = macho_load_tbd(s1, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);1128 ret = macho_load_tbd(S, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);
1051 }1129 }
1052 break;1130 break;
1053 default:1131 default:
@@ -1064,47 +1142,47 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 10 unmodified lines
1064 1142
1065#else /* unix */1143#else /* unix */
1066 case AFF_BINTYPE_DYN:1144 case AFF_BINTYPE_DYN:
1067 if (s1->output_type == TCC_OUTPUT_MEMORY) {1145 if (S->output_type == TCC_OUTPUT_MEMORY) {
1068#ifdef TCC_IS_NATIVE1146#ifdef TCC_IS_NATIVE
1069 void* dl = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY);1147 void* dl = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY);
1070 if (dl)1148 if (dl)
1071 tcc_add_dllref(s1, filename)->handle = dl, ret = 0;1149 tcc_add_dllref(S, filename)->handle = dl, ret = 0;
1072#endif1150#endif
1073 } else1151 } else
1074 ret = tcc_load_dll(s1, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);1152 ret = tcc_load_dll(S, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);
1075 break;1153 break;
1076 1154
1077 default:1155 default:
1078 /* as GNU ld, consider it is an ld script if not recognized */1156 /* as GNU ld, consider it is an ld script if not recognized */
1079 ret = tcc_load_ldscript(s1, fd);1157 ret = tcc_load_ldscript(S, fd);
1080 goto check_success;1158 goto check_success;
1081 1159
1082#endif /* pe / macos / unix */1160#endif /* pe / macos / unix */
1083 1161
1084check_success:1162check_success:
1085 if (ret < 0)1163 if (ret < 0)
1086 tcc_error_noabort("%s: unrecognized file type", filename);1164 tcc_error_noabort(S, "%s: unrecognized file type", filename);
1087 break;1165 break;
1088 1166
1089#ifdef TCC_TARGET_COFF1167#ifdef TCC_TARGET_COFF
1090 case AFF_BINTYPE_C67:1168 case AFF_BINTYPE_C67:
1091 ret = tcc_load_coff(s1, fd);1169 ret = tcc_load_coff(S, fd);
1092 break;1170 break;
1093#endif1171#endif
1094 }1172 }
1095 close(fd);1173 close(fd);
1096 } else {1174 } else {
1097 /* update target deps */1175 /* update target deps */
1098 dynarray_add(&s1->target_deps, &s1->nb_target_deps, tcc_strdup(filename));1176 dynarray_add(S, &S->target_deps, &S->nb_target_deps, tcc_strdup(S, filename));
1099 ret = tcc_compile(s1, flags, filename, fd);1177 ret = tcc_compile(S, flags, filename, fd);
1100 }1178 }
1101 s1->current_filename = NULL;1179 S->current_filename = NULL;
1102 return ret;1180 return ret;
1103}1181}
1104 1182
1105LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename)1183LIBTCCAPI int tcc_add_file(TCCState *S, const char *filename)
1106{1184{
1107 int filetype = s->filetype;1185 int filetype = S->filetype;
1108 if (0 == (filetype & AFF_TYPE_MASK)) {1186 if (0 == (filetype & AFF_TYPE_MASK)) {
1109 /* use a file extension to detect a filetype */1187 /* use a file extension to detect a filetype */
1110 const char *ext = tcc_fileextension(filename);1188 const char *ext = tcc_fileextension(filename);
@@ -1124,16 +1202,16 @@ LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename) · 13 unmodified lines
1124 filetype = AFF_TYPE_C;1202 filetype = AFF_TYPE_C;
1125 }1203 }
1126 }1204 }
1127 return tcc_add_file_internal(s, filename, filetype | AFF_PRINT_ERROR);1205 return tcc_add_file_internal(S, filename, filetype | AFF_PRINT_ERROR);
1128}1206}
1129 1207
1130LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname)1208LIBTCCAPI int tcc_add_library_path(TCCState *S, const char *pathname)
1131{1209{
1132 tcc_split_path(s, &s->library_paths, &s->nb_library_paths, pathname);1210 tcc_split_path(S, &S->library_paths, &S->nb_library_paths, pathname);
1133 return 0;1211 return 0;
1134}1212}
1135 1213
1136static int tcc_add_library_internal(TCCState *s, const char *fmt,1214static int tcc_add_library_internal(TCCState *S, const char *fmt,
1137 const char *filename, int flags, char **paths, int nb_paths)1215 const char *filename, int flags, char **paths, int nb_paths)
1138{1216{
1139 char buf[1024];1217 char buf[1024];
@@ -1141,7 +1219,7 @@ static int tcc_add_library_internal(TCCState *s, const char *fmt, · 1 unmodified line
1141 1219
1142 for(i = 0; i < nb_paths; i++) {1220 for(i = 0; i < nb_paths; i++) {
1143 snprintf(buf, sizeof(buf), fmt, paths[i], filename);1221 snprintf(buf, sizeof(buf), fmt, paths[i], filename);
1144 if (tcc_add_file_internal(s, buf, flags | AFF_TYPE_BIN) == 0)1222 if (tcc_add_file_internal(S, buf, flags | AFF_TYPE_BIN) == 0)
1145 return 0;1223 return 0;
1146 }1224 }
1147 return -1;1225 return -1;
@@ -1150,87 +1228,87 @@ static int tcc_add_library_internal(TCCState *s, const char *fmt, · 2 unmodified lines
1150#ifndef TCC_TARGET_MACHO1228#ifndef TCC_TARGET_MACHO
1151/* find and load a dll. Return non zero if not found */1229/* find and load a dll. Return non zero if not found */
1152/* XXX: add '-rpath' option support ? */1230/* XXX: add '-rpath' option support ? */
1153ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags)1231ST_FUNC int tcc_add_dll(TCCState *S, const char *filename, int flags)
1154{1232{
1155 return tcc_add_library_internal(s, "%s/%s", filename, flags,1233 return tcc_add_library_internal(S, "%s/%s", filename, flags,
1156 s->library_paths, s->nb_library_paths);1234 S->library_paths, S->nb_library_paths);
1157}1235}
1158#endif1236#endif
1159 1237
1160#if !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO1238#if !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO
1161ST_FUNC int tcc_add_crt(TCCState *s1, const char *filename)1239ST_FUNC int tcc_add_crt(TCCState *S, const char *filename)
1162{1240{
1163 if (-1 == tcc_add_library_internal(s1, "%s/%s",1241 if (-1 == tcc_add_library_internal(S, "%s/%s",
1164 filename, 0, s1->crt_paths, s1->nb_crt_paths))1242 filename, 0, S->crt_paths, S->nb_crt_paths))
1165 tcc_error_noabort("file '%s' not found", filename);1243 tcc_error_noabort(S, "file '%s' not found", filename);
1166 return 0;1244 return 0;
1167}1245}
1168#endif1246#endif
1169 1247
1170/* the library name is the same as the argument of the '-l' option */1248/* the library name is the same as the argument of the '-l' option */
1171LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname)1249LIBTCCAPI int tcc_add_library(TCCState *S, const char *libraryname)
1172{1250{
1173#if defined TCC_TARGET_PE1251#if defined TCC_TARGET_PE
1174 static const char * const libs[] = { "%s/%s.def", "%s/lib%s.def", "%s/%s.dll", "%s/lib%s.dll", "%s/lib%s.a", NULL };1252 static const char * const libs[] = { "%s/%s.def", "%s/lib%s.def", "%s/%s.dll", "%s/lib%s.dll", "%s/lib%s.a", NULL };
1175 const char * const *pp = s->static_link ? libs + 4 : libs;1253 const char * const *pp = S->static_link ? libs + 4 : libs;
1176#elif defined TCC_TARGET_MACHO1254#elif defined TCC_TARGET_MACHO
1177 static const char * const libs[] = { "%s/lib%s.dylib", "%s/lib%s.tbd", "%s/lib%s.a", NULL };1255 static const char * const libs[] = { "%s/lib%s.dylib", "%s/lib%s.tbd", "%s/lib%s.a", NULL };
1178 const char * const *pp = s->static_link ? libs + 2 : libs;1256 const char * const *pp = S->static_link ? libs + 2 : libs;
1179#elif defined TARGETOS_OpenBSD1257#elif defined TARGETOS_OpenBSD
1180 static const char * const libs[] = { "%s/lib%s.so.*", "%s/lib%s.a", NULL };1258 static const char * const libs[] = { "%s/lib%s.so.*", "%s/lib%s.a", NULL };
1181 const char * const *pp = s->static_link ? libs + 1 : libs;1259 const char * const *pp = S->static_link ? libs + 1 : libs;
1182#else1260#else
1183 static const char * const libs[] = { "%s/lib%s.so", "%s/lib%s.a", NULL };1261 static const char * const libs[] = { "%s/lib%s.so", "%s/lib%s.a", NULL };
1184 const char * const *pp = s->static_link ? libs + 1 : libs;1262 const char * const *pp = S->static_link ? libs + 1 : libs;
1185#endif1263#endif
1186 int flags = s->filetype & AFF_WHOLE_ARCHIVE;1264 int flags = S->filetype & AFF_WHOLE_ARCHIVE;
1187 while (*pp) {1265 while (*pp) {
1188 if (0 == tcc_add_library_internal(s, *pp,1266 if (0 == tcc_add_library_internal(S, *pp,
1189 libraryname, flags, s->library_paths, s->nb_library_paths))1267 libraryname, flags, S->library_paths, S->nb_library_paths))
1190 return 0;1268 return 0;
1191 ++pp;1269 ++pp;
1192 }1270 }
1193 return -1;1271 return -1;
1194}1272}
1195 1273
1196PUB_FUNC int tcc_add_library_err(TCCState *s1, const char *libname)1274PUB_FUNC int tcc_add_library_err(TCCState *S, const char *libname)
1197{1275{
1198 int ret = tcc_add_library(s1, libname);1276 int ret = tcc_add_library(S, libname);
1199 if (ret < 0)1277 if (ret < 0)
1200 tcc_error_noabort("library '%s' not found", libname);1278 tcc_error_noabort(S, "library '%s' not found", libname);
1201 return ret;1279 return ret;
1202}1280}
1203 1281
1204/* handle #pragma comment(lib,) */1282/* handle #pragma comment(lib,) */
1205ST_FUNC void tcc_add_pragma_libs(TCCState *s1)1283ST_FUNC void tcc_add_pragma_libs(TCCState *S)
1206{1284{
1207 int i;1285 int i;
1208 for (i = 0; i < s1->nb_pragma_libs; i++)1286 for (i = 0; i < S->nb_pragma_libs; i++)
1209 tcc_add_library_err(s1, s1->pragma_libs[i]);1287 tcc_add_library_err(S, S->pragma_libs[i]);
1210}1288}
1211 1289
1212LIBTCCAPI int tcc_add_symbol(TCCState *s1, const char *name, const void *val)1290LIBTCCAPI int tcc_add_symbol(TCCState *S, const char *name, const void *val)
1213{1291{
1214#ifdef TCC_TARGET_PE1292#ifdef TCC_TARGET_PE
1215 /* On x86_64 'val' might not be reachable with a 32bit offset.1293 /* On x86_64 'val' might not be reachable with a 32bit offset.
1216 So it is handled here as if it were in a DLL. */1294 So it is handled here as if it were in a DLL. */
1217 pe_putimport(s1, 0, name, (uintptr_t)val);1295 pe_putimport(S, 0, name, (uintptr_t)val);
1218#else1296#else
1219 char buf[256];1297 char buf[256];
1220 if (s1->leading_underscore) {1298 if (S->leading_underscore) {
1221 buf[0] = '_';1299 buf[0] = '_';
1222 pstrcpy(buf + 1, sizeof(buf) - 1, name);1300 pstrcpy(buf + 1, sizeof(buf) - 1, name);
1223 name = buf;1301 name = buf;
1224 }1302 }
1225 set_global_sym(s1, name, NULL, (addr_t)(uintptr_t)val); /* NULL: SHN_ABS */1303 set_global_sym(S, name, NULL, (addr_t)(uintptr_t)val); /* NULL: SHN_ABS */
1226#endif1304#endif
1227 return 0;1305 return 0;
1228}1306}
1229 1307
1230LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path)1308LIBTCCAPI void tcc_set_lib_path(TCCState *S, const char *path)
1231{1309{
1232 tcc_free(s->tcc_lib_path);1310 tcc_free(S, S->tcc_lib_path);
1233 s->tcc_lib_path = tcc_strdup(path);1311 S->tcc_lib_path = tcc_strdup(S, path);
1234}1312}
1235 1313
1236/********************************************************/1314/********************************************************/
@@ -1310,7 +1388,7 @@ static const char *skip_linker_arg(const char **str) · 73 unmodified lines
1310 return s2;1388 return s2;
1311}1389}
1312 1390
1313static void copy_linker_arg(char **pp, const char *s, int sep)1391static void copy_linker_arg(TCCState* S, char **pp, const char *s, int sep)
1314{1392{
1315 const char *q = s;1393 const char *q = s;
1316 char *p = *pp;1394 char *p = *pp;
@@ -1318,13 +1396,12 @@ static void copy_linker_arg(char **pp, const char *s, int sep) · 1 unmodified line
1318 if (p && sep)1396 if (p && sep)
1319 p[l = strlen(p)] = sep, ++l;1397 p[l = strlen(p)] = sep, ++l;
1320 skip_linker_arg(&q);1398 skip_linker_arg(&q);
1321 pstrncpy(l + (*pp = tcc_realloc(p, q - s + l + 1)), s, q - s);1399 pstrncpy(l + (*pp = tcc_realloc(S, p, q - s + l + 1)), s, q - s);
1322}1400}
1323 1401
1324/* set linker options */1402/* set linker options */
1325static int tcc_set_linker(TCCState *s, const char *option)1403static int tcc_set_linker(TCCState *S, const char *option)
1326{1404{
1327 TCCState *s1 = s;
1328 while (*option) {1405 while (*option) {
1329 1406
1330 const char *p = NULL;1407 const char *p = NULL;
@@ -1333,18 +1410,18 @@ static int tcc_set_linker(TCCState *s, const char *option) · 2 unmodified lines
1333 int ret;1410 int ret;
1334 1411
1335 if (link_option(option, "Bsymbolic", &p)) {1412 if (link_option(option, "Bsymbolic", &p)) {
1336 s->symbolic = 1;1413 S->symbolic = 1;
1337 } else if (link_option(option, "nostdlib", &p)) {1414 } else if (link_option(option, "nostdlib", &p)) {
1338 s->nostdlib = 1;1415 S->nostdlib = 1;
1339 } else if (link_option(option, "fini=", &p)) {1416 } else if (link_option(option, "fini=", &p)) {
1340 copy_linker_arg(&s->fini_symbol, p, 0);1417 copy_linker_arg(S, &S->fini_symbol, p, 0);
1341 ignoring = 1;1418 ignoring = 1;
1342 } else if (link_option(option, "image-base=", &p)1419 } else if (link_option(option, "image-base=", &p)
1343 || link_option(option, "Ttext=", &p)) {1420 || link_option(option, "Ttext=", &p)) {
1344 s->text_addr = strtoull(p, &end, 16);1421 S->text_addr = strtoull(p, &end, 16);
1345 s->has_text_addr = 1;1422 S->has_text_addr = 1;
1346 } else if (link_option(option, "init=", &p)) {1423 } else if (link_option(option, "init=", &p)) {
1347 copy_linker_arg(&s->init_symbol, p, 0);1424 copy_linker_arg(S, &S->init_symbol, p, 0);
1348 ignoring = 1;1425 ignoring = 1;
1349 } else if (link_option(option, "oformat=", &p)) {1426 } else if (link_option(option, "oformat=", &p)) {
1350#if defined(TCC_TARGET_PE)1427#if defined(TCC_TARGET_PE)
@@ -1354,12 +1431,12 @@ static int tcc_set_linker(TCCState *s, const char *option) · 3 unmodified lines
1354#else1431#else
1355 if (strstart("elf32-", &p)) {1432 if (strstart("elf32-", &p)) {
1356#endif1433#endif
1357 s->output_format = TCC_OUTPUT_FORMAT_ELF;1434 S->output_format = TCC_OUTPUT_FORMAT_ELF;
1358 } else if (!strcmp(p, "binary")) {1435 } else if (!strcmp(p, "binary")) {
1359 s->output_format = TCC_OUTPUT_FORMAT_BINARY;1436 S->output_format = TCC_OUTPUT_FORMAT_BINARY;
1360#ifdef TCC_TARGET_COFF1437#ifdef TCC_TARGET_COFF
1361 } else if (!strcmp(p, "coff")) {1438 } else if (!strcmp(p, "coff")) {
1362 s->output_format = TCC_OUTPUT_FORMAT_COFF;1439 S->output_format = TCC_OUTPUT_FORMAT_COFF;
1363#endif1440#endif
1364 } else1441 } else
1365 goto err;1442 goto err;
@@ -1369,64 +1446,64 @@ static int tcc_set_linker(TCCState *s, const char *option) · 3 unmodified lines
1369 } else if (link_option(option, "O", &p)) {1446 } else if (link_option(option, "O", &p)) {
1370 ignoring = 1;1447 ignoring = 1;
1371 } else if (link_option(option, "export-all-symbols", &p)) {1448 } else if (link_option(option, "export-all-symbols", &p)) {
1372 s->rdynamic = 1;1449 S->rdynamic = 1;
1373 } else if (link_option(option, "export-dynamic", &p)) {1450 } else if (link_option(option, "export-dynamic", &p)) {
1374 s->rdynamic = 1;1451 S->rdynamic = 1;
1375 } else if (link_option(option, "rpath=", &p)) {1452 } else if (link_option(option, "rpath=", &p)) {
1376 copy_linker_arg(&s->rpath, p, ':');1453 copy_linker_arg(S, &S->rpath, p, ':');
1377 } else if (link_option(option, "enable-new-dtags", &p)) {1454 } else if (link_option(option, "enable-new-dtags", &p)) {
1378 s->enable_new_dtags = 1;1455 S->enable_new_dtags = 1;
1379 } else if (link_option(option, "section-alignment=", &p)) {1456 } else if (link_option(option, "section-alignment=", &p)) {
1380 s->section_align = strtoul(p, &end, 16);1457 S->section_align = strtoul(p, &end, 16);
1381 } else if (link_option(option, "soname=", &p)) {1458 } else if (link_option(option, "soname=", &p)) {
1382 copy_linker_arg(&s->soname, p, 0);1459 copy_linker_arg(S, &S->soname, p, 0);
1383#ifdef TCC_TARGET_PE1460#ifdef TCC_TARGET_PE
1384 } else if (link_option(option, "large-address-aware", &p)) {1461 } else if (link_option(option, "large-address-aware", &p)) {
1385 s->pe_characteristics |= 0x20;1462 S->pe_characteristics |= 0x20;
1386 } else if (link_option(option, "file-alignment=", &p)) {1463 } else if (link_option(option, "file-alignment=", &p)) {
1387 s->pe_file_align = strtoul(p, &end, 16);1464 S->pe_file_align = strtoul(p, &end, 16);
1388 } else if (link_option(option, "stack=", &p)) {1465 } else if (link_option(option, "stack=", &p)) {
1389 s->pe_stack_size = strtoul(p, &end, 10);1466 S->pe_stack_size = strtoul(p, &end, 10);
1390 } else if (link_option(option, "subsystem=", &p)) {1467 } else if (link_option(option, "subsystem=", &p)) {
1391#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)1468#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1392 if (!strcmp(p, "native")) {1469 if (!strcmp(p, "native")) {
1393 s->pe_subsystem = 1;1470 S->pe_subsystem = 1;
1394 } else if (!strcmp(p, "console")) {1471 } else if (!strcmp(p, "console")) {
1395 s->pe_subsystem = 3;1472 S->pe_subsystem = 3;
1396 } else if (!strcmp(p, "gui") || !strcmp(p, "windows")) {1473 } else if (!strcmp(p, "gui") || !strcmp(p, "windows")) {
1397 s->pe_subsystem = 2;1474 S->pe_subsystem = 2;
1398 } else if (!strcmp(p, "posix")) {1475 } else if (!strcmp(p, "posix")) {
1399 s->pe_subsystem = 7;1476 S->pe_subsystem = 7;
1400 } else if (!strcmp(p, "efiapp")) {1477 } else if (!strcmp(p, "efiapp")) {
1401 s->pe_subsystem = 10;1478 S->pe_subsystem = 10;
1402 } else if (!strcmp(p, "efiboot")) {1479 } else if (!strcmp(p, "efiboot")) {
1403 s->pe_subsystem = 11;1480 S->pe_subsystem = 11;
1404 } else if (!strcmp(p, "efiruntime")) {1481 } else if (!strcmp(p, "efiruntime")) {
1405 s->pe_subsystem = 12;1482 S->pe_subsystem = 12;
1406 } else if (!strcmp(p, "efirom")) {1483 } else if (!strcmp(p, "efirom")) {
1407 s->pe_subsystem = 13;1484 S->pe_subsystem = 13;
1408#elif defined(TCC_TARGET_ARM)1485#elif defined(TCC_TARGET_ARM)
1409 if (!strcmp(p, "wince")) {1486 if (!strcmp(p, "wince")) {
1410 s->pe_subsystem = 9;1487 S->pe_subsystem = 9;
1411#endif1488#endif
1412 } else1489 } else
1413 goto err;1490 goto err;
1414#endif1491#endif
1415 } else if (ret = link_option(option, "?whole-archive", &p), ret) {1492 } else if (ret = link_option(option, "?whole-archive", &p), ret) {
1416 if (ret > 0)1493 if (ret > 0)
1417 s->filetype |= AFF_WHOLE_ARCHIVE;1494 S->filetype |= AFF_WHOLE_ARCHIVE;
1418 else1495 else
1419 s->filetype &= ~AFF_WHOLE_ARCHIVE;1496 S->filetype &= ~AFF_WHOLE_ARCHIVE;
1420 } else if (link_option(option, "z=", &p)) {1497 } else if (link_option(option, "z=", &p)) {
1421 ignoring = 1;1498 ignoring = 1;
1422 } else if (p) {1499 } else if (p) {
1423 return 0;1500 return 0;
1424 } else {1501 } else {
1425 err:1502 err:
1426 tcc_error("unsupported linker option '%s'", option);1503 tcc_error(S, "unsupported linker option '%s'", option);
1427 }1504 }
1428 if (ignoring)1505 if (ignoring)
1429 tcc_warning_c(warn_unsupported)("unsupported linker option '%s'", option);1506 tcc_warning_c(warn_unsupported)(S, "unsupported linker option '%s'", option);
1430 option = skip_linker_arg(&p);1507 option = skip_linker_arg(&p);
1431 }1508 }
1432 return 1;1509 return 1;
@@ -1604,7 +1681,7 @@ static const FlagDef options_m[] = { · 171 unmodified lines
1604 { 0, 0, NULL }1681 { 0, 0, NULL }
1605};1682};
1606 1683
1607static int set_flag(TCCState *s, const FlagDef *flags, const char *name)1684static int set_flag(TCCState *S, const FlagDef *flags, const char *name)
1608{1685{
1609 int value, mask, ret;1686 int value, mask, ret;
1610 const FlagDef *p;1687 const FlagDef *p;
@@ -1626,7 +1703,7 @@ static int set_flag(TCCState *s, const FlagDef *flags, const char *name) · 15 unmodified lines
1626 continue;1703 continue;
1627 }1704 }
1628 1705
1629 f = (unsigned char *)s + p->offset;1706 f = (unsigned char *)S + p->offset;
1630 *f = (*f & mask) | (value ^ !!(p->flags & FD_INVERT));1707 *f = (*f & mask) | (value ^ !!(p->flags & FD_INVERT));
1631 1708
1632 if (ret) {1709 if (ret) {
@@ -1638,15 +1715,15 @@ static int set_flag(TCCState *s, const FlagDef *flags, const char *name) · 5 unmodified lines
1638 return ret;1715 return ret;
1639}1716}
1640 1717
1641static void args_parser_add_file(TCCState *s, const char* filename, int filetype)1718static void args_parser_add_file(TCCState *S, const char* filename, int filetype)
1642{1719{
1643 struct filespec *f = tcc_malloc(sizeof *f + strlen(filename));1720 struct filespec *f = tcc_malloc(S, sizeof *f + strlen(filename));
1644 f->type = filetype;1721 f->type = filetype;
1645 strcpy(f->name, filename);1722 strcpy(f->name, filename);
1646 dynarray_add(&s->files, &s->nb_files, f);1723 dynarray_add(S, &S->files, &S->nb_files, f);
1647}1724}
1648 1725
1649static int args_parser_make_argv(const char *r, int *argc, char ***argv)1726static int args_parser_make_argv(TCCState* S, const char *r, int *argc, char ***argv)
1650{1727{
1651 int ret = 0, q, c;1728 int ret = 0, q, c;
1652 CString str;1729 CString str;
@@ -1656,7 +1733,7 @@ static int args_parser_make_argv(const char *r, int *argc, char ***argv) · 3 unmodified lines
1656 if (c == 0)1733 if (c == 0)
1657 break;1734 break;
1658 q = 0;1735 q = 0;
1659 cstr_new(&str);1736 cstr_new(S, &str);
1660 while (c = (unsigned char)*r, c) {1737 while (c = (unsigned char)*r, c) {
1661 ++r;1738 ++r;
1662 if (c == '\\' && (*r == '"' || *r == '\\')) {1739 if (c == '\\' && (*r == '"' || *r == '\\')) {
@@ -1667,22 +1744,21 @@ static int args_parser_make_argv(const char *r, int *argc, char ***argv) · 4 unmodified lines
1667 } else if (q == 0 && c <= ' ') {1744 } else if (q == 0 && c <= ' ') {
1668 break;1745 break;
1669 }1746 }
1670 cstr_ccat(&str, c);1747 cstr_ccat(S, &str, c);
1671 }1748 }
1672 cstr_ccat(&str, 0);1749 cstr_ccat(S, &str, 0);
1673 //printf("<%s>\n", str.data), fflush(stdout);1750 //printf("<%s>\n", str.data), fflush(stdout);
1674 dynarray_add(argv, argc, tcc_strdup(str.data));1751 dynarray_add(S, argv, argc, tcc_strdup(S, str.data));
1675 cstr_free(&str);1752 cstr_free(S, &str);
1676 ++ret;1753 ++ret;
1677 }1754 }
1678 return ret;1755 return ret;
1679}1756}
1680 1757
1681/* read list file */1758/* read list file */
1682static void args_parser_listfile(TCCState *s,1759static void args_parser_listfile(TCCState *S,
1683 const char *filename, int optind, int *pargc, char ***pargv)1760 const char *filename, int optind, int *pargc, char ***pargv)
1684{1761{
1685 TCCState *s1 = s;
1686 int fd, i;1762 int fd, i;
1687 char *p;1763 char *p;
1688 int argc = 0;1764 int argc = 0;
@@ -1690,23 +1766,22 @@ static void args_parser_listfile(TCCState *s, · 1 unmodified line
1690 1766
1691 fd = open(filename, O_RDONLY | O_BINARY);1767 fd = open(filename, O_RDONLY | O_BINARY);
1692 if (fd < 0)1768 if (fd < 0)
1693 tcc_error("listfile '%s' not found", filename);1769 tcc_error(S, "listfile '%s' not found", filename);
1694 1770
1695 p = tcc_load_text(fd);1771 p = tcc_load_text(S, fd);
1696 for (i = 0; i < *pargc; ++i)1772 for (i = 0; i < *pargc; ++i)
1697 if (i == optind)1773 if (i == optind)
1698 args_parser_make_argv(p, &argc, &argv);1774 args_parser_make_argv(S, p, &argc, &argv);
1699 else1775 else
1700 dynarray_add(&argv, &argc, tcc_strdup((*pargv)[i]));1776 dynarray_add(S, &argv, &argc, tcc_strdup(S, (*pargv)[i]));
1701 1777
1702 tcc_free(p);1778 tcc_free(S, p);
1703 dynarray_reset(&s->argv, &s->argc);1779 dynarray_reset(S, &S->argv, &S->argc);
1704 *pargc = s->argc = argc, *pargv = s->argv = argv;1780 *pargc = S->argc = argc, *pargv = S->argv = argv;
1705}1781}
1706 1782
1707PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind)1783PUB_FUNC int tcc_parse_args(TCCState *S, int *pargc, char ***pargv, int optind)
1708{1784{
1709 TCCState *s1 = s;
1710 const TCCOption *popt;1785 const TCCOption *popt;
1711 const char *optarg, *r;1786 const char *optarg, *r;
1712 const char *run = NULL;1787 const char *run = NULL;
@@ -1716,26 +1791,26 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind) · 3 unmodified lines
1716 char **argv = *pargv;1791 char **argv = *pargv;
1717 int argc = *pargc;1792 int argc = *pargc;
1718 1793
1719 cstr_new(&linker_arg);1794 cstr_new(S, &linker_arg);
1720 1795
1721 while (optind < argc) {1796 while (optind < argc) {
1722 r = argv[optind];1797 r = argv[optind];
1723 if (r[0] == '@' && r[1] != '\0') {1798 if (r[0] == '@' && r[1] != '\0') {
1724 args_parser_listfile(s, r + 1, optind, &argc, &argv);1799 args_parser_listfile(S, r + 1, optind, &argc, &argv);
1725 continue;1800 continue;
1726 }1801 }
1727 optind++;1802 optind++;
1728 if (tool) {1803 if (tool) {
1729 if (r[0] == '-' && r[1] == 'v' && r[2] == 0)1804 if (r[0] == '-' && r[1] == 'v' && r[2] == 0)
1730 ++s->verbose;1805 ++S->verbose;
1731 continue;1806 continue;
1732 }1807 }
1733reparse:1808reparse:
1734 if (r[0] != '-' || r[1] == '\0') {1809 if (r[0] != '-' || r[1] == '\0') {
1735 if (r[0] != '@') /* allow "tcc file(s) -run @ args ..." */1810 if (r[0] != '@') /* allow "tcc file(s) -run @ args ..." */
1736 args_parser_add_file(s, r, s->filetype);1811 args_parser_add_file(S, r, S->filetype);
1737 if (run) {1812 if (run) {
1738 tcc_set_options(s, run);1813 tcc_set_options(S, run);
1739 arg_start = optind - 1;1814 arg_start = optind - 1;
1740 break;1815 break;
1741 }1816 }
@@ -1747,7 +1822,7 @@ reparse: · 5 unmodified lines
1747 const char *p1 = popt->name;1822 const char *p1 = popt->name;
1748 const char *r1 = r + 1;1823 const char *r1 = r + 1;
1749 if (p1 == NULL)1824 if (p1 == NULL)
1750 tcc_error("invalid option -- '%s'", r);1825 tcc_error(S, "invalid option -- '%s'", r);
1751 if (!strstart(p1, &r1))1826 if (!strstart(p1, &r1))
1752 continue;1827 continue;
1753 optarg = r1;1828 optarg = r1;
@@ -1755,7 +1830,7 @@ reparse: · 1 unmodified line
1755 if (*r1 == '\0' && !(popt->flags & TCC_OPTION_NOSEP)) {1830 if (*r1 == '\0' && !(popt->flags & TCC_OPTION_NOSEP)) {
1756 if (optind >= argc)1831 if (optind >= argc)
1757 arg_err:1832 arg_err:
1758 tcc_error("argument to '%s' is missing", r);1833 tcc_error(S, "argument to '%s' is missing", r);
1759 optarg = argv[optind++];1834 optarg = argv[optind++];
1760 }1835 }
1761 } else if (*r1 != '\0')1836 } else if (*r1 != '\0')
@@ -1771,132 +1846,132 @@ reparse: · 9 unmodified lines
1771 x = OPT_HELP2;1846 x = OPT_HELP2;
1772 goto extra_action;1847 goto extra_action;
1773 case TCC_OPTION_I:1848 case TCC_OPTION_I:
1774 tcc_add_include_path(s, optarg);1849 tcc_add_include_path(S, optarg);
1775 break;1850 break;
1776 case TCC_OPTION_D:1851 case TCC_OPTION_D:
1777 tcc_define_symbol(s, optarg, NULL);1852 tcc_define_symbol(S, optarg, NULL);
1778 break;1853 break;
1779 case TCC_OPTION_U:1854 case TCC_OPTION_U:
1780 tcc_undefine_symbol(s, optarg);1855 tcc_undefine_symbol(S, optarg);
1781 break;1856 break;
1782 case TCC_OPTION_L:1857 case TCC_OPTION_L:
1783 tcc_add_library_path(s, optarg);1858 tcc_add_library_path(S, optarg);
1784 break;1859 break;
1785 case TCC_OPTION_B:1860 case TCC_OPTION_B:
1786 /* set tcc utilities path (mainly for tcc development) */1861 /* set tcc utilities path (mainly for tcc development) */
1787 tcc_set_lib_path(s, optarg);1862 tcc_set_lib_path(S, optarg);
1788 break;1863 break;
1789 case TCC_OPTION_l:1864 case TCC_OPTION_l:
1790 args_parser_add_file(s, optarg, AFF_TYPE_LIB | (s->filetype & ~AFF_TYPE_MASK));1865 args_parser_add_file(S, optarg, AFF_TYPE_LIB | (S->filetype & ~AFF_TYPE_MASK));
1791 s->nb_libraries++;1866 S->nb_libraries++;
1792 break;1867 break;
1793 case TCC_OPTION_pthread:1868 case TCC_OPTION_pthread:
1794 s->option_pthread = 1;1869 S->option_pthread = 1;
1795 break;1870 break;
1796 case TCC_OPTION_bench:1871 case TCC_OPTION_bench:
1797 s->do_bench = 1;1872 S->do_bench = 1;
1798 break;1873 break;
1799#ifdef CONFIG_TCC_BACKTRACE1874#ifdef CONFIG_TCC_BACKTRACE
1800 case TCC_OPTION_bt:1875 case TCC_OPTION_bt:
1801 s->rt_num_callers = atoi(optarg);1876 S->rt_num_callers = atoi(optarg);
1802 s->do_backtrace = 1;1877 S->do_backtrace = 1;
1803 s->do_debug = 1;1878 S->do_debug = 1;
1804 break;1879 break;
1805#endif1880#endif
1806#ifdef CONFIG_TCC_BCHECK1881#ifdef CONFIG_TCC_BCHECK
1807 case TCC_OPTION_b:1882 case TCC_OPTION_b:
1808 s->do_bounds_check = 1;1883 S->do_bounds_check = 1;
1809 s->do_backtrace = 1;1884 S->do_backtrace = 1;
1810 s->do_debug = 1;1885 S->do_debug = 1;
1811 break;1886 break;
1812#endif1887#endif
1813 case TCC_OPTION_g:1888 case TCC_OPTION_g:
1814 s->do_debug = 1;1889 S->do_debug = 1;
1815 break;1890 break;
1816 case TCC_OPTION_c:1891 case TCC_OPTION_c:
1817 x = TCC_OUTPUT_OBJ;1892 x = TCC_OUTPUT_OBJ;
1818 set_output_type:1893 set_output_type:
1819 if (s->output_type)1894 if (S->output_type)
1820 tcc_warning("-%s: overriding compiler action already specified", popt->name);1895 tcc_warning(S, "-%s: overriding compiler action already specified", popt->name);
1821 s->output_type = x;1896 S->output_type = x;
1822 break;1897 break;
1823 case TCC_OPTION_d:1898 case TCC_OPTION_d:
1824 if (*optarg == 'D')1899 if (*optarg == 'D')
1825 s->dflag = 3;1900 S->dflag = TCC_OPTION_d_D;
1826 else if (*optarg == 'M')1901 else if (*optarg == 'M')
1827 s->dflag = 7;1902 S->dflag = TCC_OPTION_d_M;
1828 else if (*optarg == 't')1903 else if (*optarg == 't')
1829 s->dflag = 16;1904 S->dflag = TCC_OPTION_d_t;
1830 else if (isnum(*optarg))1905 else if (isnum(*optarg))
1831 s->g_debug |= atoi(optarg);1906 S->g_debug |= atoi(optarg);
1832 else1907 else
1833 goto unsupported_option;1908 goto unsupported_option;
1834 break;1909 break;
1835 case TCC_OPTION_static:1910 case TCC_OPTION_static:
1836 s->static_link = 1;1911 S->static_link = 1;
1837 break;1912 break;
1838 case TCC_OPTION_std:1913 case TCC_OPTION_std:
1839 if (strcmp(optarg, "=c11") == 0)1914 if (strcmp(optarg, "=c11") == 0)
1840 s->cversion = 201112;1915 S->cversion = 201112;
1841 break;1916 break;
1842 case TCC_OPTION_shared:1917 case TCC_OPTION_shared:
1843 x = TCC_OUTPUT_DLL;1918 x = TCC_OUTPUT_DLL;
1844 goto set_output_type;1919 goto set_output_type;
1845 case TCC_OPTION_soname:1920 case TCC_OPTION_soname:
1846 s->soname = tcc_strdup(optarg);1921 S->soname = tcc_strdup(S, optarg);
1847 break;1922 break;
1848 case TCC_OPTION_o:1923 case TCC_OPTION_o:
1849 if (s->outfile) {1924 if (S->outfile) {
1850 tcc_warning("multiple -o option");1925 tcc_warning(S, "multiple -o option");
1851 tcc_free(s->outfile);1926 tcc_free(S, S->outfile);
1852 }1927 }
1853 s->outfile = tcc_strdup(optarg);1928 S->outfile = tcc_strdup(S, optarg);
1854 break;1929 break;
1855 case TCC_OPTION_r:1930 case TCC_OPTION_r:
1856 /* generate a .o merging several output files */1931 /* generate a .o merging several output files */
1857 s->option_r = 1;1932 S->option_r = 1;
1858 x = TCC_OUTPUT_OBJ;1933 x = TCC_OUTPUT_OBJ;
1859 goto set_output_type;1934 goto set_output_type;
1860 case TCC_OPTION_isystem:1935 case TCC_OPTION_isystem:
1861 tcc_add_sysinclude_path(s, optarg);1936 tcc_add_sysinclude_path(S, optarg);
1862 break;1937 break;
1863 case TCC_OPTION_include:1938 case TCC_OPTION_include:
1864 cstr_printf(&s->cmdline_incl, "#include \"%s\"\n", optarg);1939 cstr_printf(S, &S->cmdline_incl, "#include \"%s\"\n", optarg);
1865 break;1940 break;
1866 case TCC_OPTION_nostdinc:1941 case TCC_OPTION_nostdinc:
1867 s->nostdinc = 1;1942 S->nostdinc = 1;
1868 break;1943 break;
1869 case TCC_OPTION_nostdlib:1944 case TCC_OPTION_nostdlib:
1870 s->nostdlib = 1;1945 S->nostdlib = 1;
1871 break;1946 break;
1872 case TCC_OPTION_run:1947 case TCC_OPTION_run:
1873#ifndef TCC_IS_NATIVE1948#ifndef TCC_IS_NATIVE
1874 tcc_error("-run is not available in a cross compiler");1949 tcc_error(S, "-run is not available in a cross compiler");
1875#endif1950#endif
1876 run = optarg;1951 run = optarg;
1877 x = TCC_OUTPUT_MEMORY;1952 x = TCC_OUTPUT_MEMORY;
1878 goto set_output_type;1953 goto set_output_type;
1879 case TCC_OPTION_v:1954 case TCC_OPTION_v:
1880 do ++s->verbose; while (*optarg++ == 'v');1955 do ++S->verbose; while (*optarg++ == 'v');
1881 ++noaction;1956 ++noaction;
1882 break;1957 break;
1883 case TCC_OPTION_f:1958 case TCC_OPTION_f:
1884 if (set_flag(s, options_f, optarg) < 0)1959 if (set_flag(S, options_f, optarg) < 0)
1885 goto unsupported_option;1960 goto unsupported_option;
1886 break;1961 break;
1887#ifdef TCC_TARGET_ARM1962#ifdef TCC_TARGET_ARM
1888 case TCC_OPTION_mfloat_abi:1963 case TCC_OPTION_mfloat_abi:
1889 /* tcc doesn't support soft float yet */1964 /* tcc doesn't support soft float yet */
1890 if (!strcmp(optarg, "softfp")) {1965 if (!strcmp(optarg, "softfp")) {
1891 s->float_abi = ARM_SOFTFP_FLOAT;1966 S->float_abi = ARM_SOFTFP_FLOAT;
1892 } else if (!strcmp(optarg, "hard"))1967 } else if (!strcmp(optarg, "hard"))
1893 s->float_abi = ARM_HARD_FLOAT;1968 S->float_abi = ARM_HARD_FLOAT;
1894 else1969 else
1895 tcc_error("unsupported float abi '%s'", optarg);1970 tcc_error(S, "unsupported float abi '%s'", optarg);
1896 break;1971 break;
1897#endif1972#endif
1898 case TCC_OPTION_m:1973 case TCC_OPTION_m:
1899 if (set_flag(s, options_m, optarg) < 0) {1974 if (set_flag(S, options_m, optarg) < 0) {
1900 if (x = atoi(optarg), x != 32 && x != 64)1975 if (x = atoi(optarg), x != 32 && x != 64)
1901 goto unsupported_option;1976 goto unsupported_option;
1902 if (PTR_SIZE != x/8)1977 if (PTR_SIZE != x/8)
@@ -1905,22 +1980,22 @@ reparse: · 2 unmodified lines
1905 }1980 }
1906 break;1981 break;
1907 case TCC_OPTION_W:1982 case TCC_OPTION_W:
1908 s->warn_none = 0;1983 S->warn_none = 0;
1909 if (optarg[0] && set_flag(s, options_W, optarg) < 0)1984 if (optarg[0] && set_flag(S, options_W, optarg) < 0)
1910 goto unsupported_option;1985 goto unsupported_option;
1911 break;1986 break;
1912 case TCC_OPTION_w:1987 case TCC_OPTION_w:
1913 s->warn_none = 1;1988 S->warn_none = 1;
1914 break;1989 break;
1915 case TCC_OPTION_rdynamic:1990 case TCC_OPTION_rdynamic:
1916 s->rdynamic = 1;1991 S->rdynamic = 1;
1917 break;1992 break;
1918 case TCC_OPTION_Wl:1993 case TCC_OPTION_Wl:
1919 if (linker_arg.size)1994 if (linker_arg.size)
1920 --linker_arg.size, cstr_ccat(&linker_arg, ',');1995 --linker_arg.size, cstr_ccat(S, &linker_arg, ',');
1921 cstr_cat(&linker_arg, optarg, 0);1996 cstr_cat(S, &linker_arg, optarg, 0);
1922 if (tcc_set_linker(s, linker_arg.data))1997 if (tcc_set_linker(S, linker_arg.data))
1923 cstr_free(&linker_arg);1998 cstr_free(S, &linker_arg);
1924 break;1999 break;
1925 case TCC_OPTION_Wp:2000 case TCC_OPTION_Wp:
1926 r = optarg;2001 r = optarg;
@@ -1929,25 +2004,25 @@ reparse: · 2 unmodified lines
1929 x = TCC_OUTPUT_PREPROCESS;2004 x = TCC_OUTPUT_PREPROCESS;
1930 goto set_output_type;2005 goto set_output_type;
1931 case TCC_OPTION_P:2006 case TCC_OPTION_P:
1932 s->Pflag = atoi(optarg) + 1;2007 S->Pflag = atoi(optarg) + 1;
1933 break;2008 break;
1934 case TCC_OPTION_M:2009 case TCC_OPTION_M:
1935 s->include_sys_deps = 1;2010 S->include_sys_deps = 1;
1936 // fall through2011 // fall through
1937 case TCC_OPTION_MM:2012 case TCC_OPTION_MM:
1938 s->just_deps = 1;2013 S->just_deps = 1;
1939 if(!s->deps_outfile)2014 if(!S->deps_outfile)
1940 s->deps_outfile = tcc_strdup("-");2015 S->deps_outfile = tcc_strdup(S, "-");
1941 // fall through2016 // fall through
1942 case TCC_OPTION_MMD:2017 case TCC_OPTION_MMD:
1943 s->gen_deps = 1;2018 S->gen_deps = 1;
1944 break;2019 break;
1945 case TCC_OPTION_MD:2020 case TCC_OPTION_MD:
1946 s->gen_deps = 1;2021 S->gen_deps = 1;
1947 s->include_sys_deps = 1;2022 S->include_sys_deps = 1;
1948 break;2023 break;
1949 case TCC_OPTION_MF:2024 case TCC_OPTION_MF:
1950 s->deps_outfile = tcc_strdup(optarg);2025 S->deps_outfile = tcc_strdup(S, optarg);
1951 break;2026 break;
1952 case TCC_OPTION_dumpversion:2027 case TCC_OPTION_dumpversion:
1953 printf ("%s\n", TCC_VERSION);2028 printf ("%s\n", TCC_VERSION);
@@ -1964,11 +2039,11 @@ reparse: · 10 unmodified lines
1964 else if (*optarg == 'n')2039 else if (*optarg == 'n')
1965 x = AFF_TYPE_NONE;2040 x = AFF_TYPE_NONE;
1966 else2041 else
1967 tcc_warning("unsupported language '%s'", optarg);2042 tcc_warning(S, "unsupported language '%s'", optarg);
1968 s->filetype = x | (s->filetype & ~AFF_TYPE_MASK);2043 S->filetype = x | (S->filetype & ~AFF_TYPE_MASK);
1969 break;2044 break;
1970 case TCC_OPTION_O:2045 case TCC_OPTION_O:
1971 s->optimize = atoi(optarg);2046 S->optimize = atoi(optarg);
1972 break;2047 break;
1973 case TCC_OPTION_print_search_dirs:2048 case TCC_OPTION_print_search_dirs:
1974 x = OPT_PRINT_DIRS;2049 x = OPT_PRINT_DIRS;
@@ -1981,12 +2056,12 @@ reparse: · 6 unmodified lines
1981 extra_action:2056 extra_action:
1982 arg_start = optind - 1;2057 arg_start = optind - 1;
1983 if (arg_start != noaction)2058 if (arg_start != noaction)
1984 tcc_error("cannot parse %s here", r);2059 tcc_error(S, "cannot parse %s here", r);
1985 tool = x;2060 tool = x;
1986 break;2061 break;
1987 default:2062 default:
1988unsupported_option:2063unsupported_option:
1989 tcc_warning_c(warn_unsupported)("unsupported option '%s'", r);2064 tcc_warning_c(warn_unsupported)(S, "unsupported option '%s'", r);
1990 break;2065 break;
1991 }2066 }
1992 }2067 }
@@ -2000,23 +2075,23 @@ unsupported_option: · 7 unmodified lines
2000 return tool;2075 return tool;
2001 if (optind != noaction)2076 if (optind != noaction)
2002 return 0;2077 return 0;
2003 if (s->verbose == 2)2078 if (S->verbose == 2)
2004 return OPT_PRINT_DIRS;2079 return OPT_PRINT_DIRS;
2005 if (s->verbose)2080 if (S->verbose)
2006 return OPT_V;2081 return OPT_V;
2007 return OPT_HELP;2082 return OPT_HELP;
2008}2083}
2009 2084
2010LIBTCCAPI void tcc_set_options(TCCState *s, const char *r)2085LIBTCCAPI void tcc_set_options(TCCState *S, const char *r)
2011{2086{
2012 char **argv = NULL;2087 char **argv = NULL;
2013 int argc = 0;2088 int argc = 0;
2014 args_parser_make_argv(r, &argc, &argv);2089 args_parser_make_argv(S, r, &argc, &argv);
2015 tcc_parse_args(s, &argc, &argv, 0);2090 tcc_parse_args(S, &argc, &argv, 0);
2016 dynarray_reset(&argv, &argc);2091 dynarray_reset(S, &argv, &argc);
2017}2092}
2018 2093
2019PUB_FUNC void tcc_print_stats(TCCState *s1, unsigned total_time)2094PUB_FUNC void tcc_print_stats(TCCState *S, unsigned total_time)
2020{2095{
2021 if (total_time < 1)2096 if (total_time < 1)
2022 total_time = 1;2097 total_time = 1;
@@ -2029,12 +2104,14 @@ PUB_FUNC void tcc_print_stats(TCCState *s1, unsigned total_time) · 6 unmodified lines
2029 (unsigned)total_lines*1000/total_time,2104 (unsigned)total_lines*1000/total_time,
2030 (double)total_bytes/1000/total_time);2105 (double)total_bytes/1000/total_time);
2031 fprintf(stderr, "* text %d, data.rw %d, data.ro %d, bss %d bytes\n",2106 fprintf(stderr, "* text %d, data.rw %d, data.ro %d, bss %d bytes\n",
2032 s1->total_output[0],2107 S->total_output[0],
2033 s1->total_output[1],2108 S->total_output[1],
2034 s1->total_output[2],2109 S->total_output[2],
2035 s1->total_output[3]2110 S->total_output[3]
2036 );2111 );
2037#ifdef MEM_DEBUG2112#ifdef MEM_DEBUG
2038 fprintf(stderr, "* %d bytes memory used\n", mem_max_size);2113 fprintf(stderr, "* %d bytes memory used\n", mem_max_size);
2039#endif2114#endif
2040}2115}
2116
2117#include "tccqsort.c"
libtcc.h+72−21
@@ -15,56 +15,95 @@ typedef struct TCCState TCCState; · 14 unmodified lines
15 15
16typedef void (*TCCErrorFunc)(void *opaque, const char *msg);16typedef void (*TCCErrorFunc)(void *opaque, const char *msg);
17 17
18#ifndef _OFF_T_DEFINED
19#define _OFF_T_DEFINED
20#ifndef _OFF_T_
21#define _OFF_T_
22 typedef long _off_t;
23#ifndef _SIZE_T_
24#define _SIZE_T_
25 typedef unsigned long size_t;
26#endif
27#if !defined(NO_OLDNAMES) || defined(_POSIX)
28 typedef long off_t;
29#endif
30#endif
31#endif
32
33struct vio_module_t;
34
35typedef struct vio_fd {
36 int fd;
37 void *vio_udata;
38 struct vio_module_t *vio_module;
39} vio_fd;
40
41#define CALL_VIO_OPEN_FIRST 0x01
42#define CALL_VIO_OPEN_LAST 0x02
43
44typedef struct vio_module_t {
45 void *user_data;
46 struct TCCState *S;
47 int call_vio_open_flags; /*CALL_VIO_OPEN_FIRST, CALL_VIO_OPEN_LAST, one or both */
48 int (*vio_open)(vio_fd *fd, const char *fn, int oflag) ;
49 off_t (*vio_lseek)(vio_fd fd, off_t offset, int whence);
50 size_t (*vio_read)(vio_fd fd, void *buf, size_t bytes);
51 int (*vio_close)(vio_fd *fd);
52} vio_module_t;
53
18/* create a new TCC compilation context */54/* create a new TCC compilation context */
19LIBTCCAPI TCCState *tcc_new(void);55LIBTCCAPI TCCState *tcc_new(void);
20 56
21/* free a TCC compilation context */57/* free a TCC compilation context */
22LIBTCCAPI void tcc_delete(TCCState *s);58LIBTCCAPI void tcc_delete(TCCState *S);
23 59
24/* set CONFIG_TCCDIR at runtime */60/* set CONFIG_TCCDIR at runtime */
25LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path);61LIBTCCAPI void tcc_set_lib_path(TCCState *S, const char *path);
26 62
27/* set error/warning display callback */63/* set error/warning display callback */
28LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque, TCCErrorFunc error_func);64LIBTCCAPI void tcc_set_error_func(TCCState *S, void *error_opaque, TCCErrorFunc error_func);
29 65
30/* return error/warning callback */66/* return error/warning callback */
31LIBTCCAPI TCCErrorFunc tcc_get_error_func(TCCState *s);67LIBTCCAPI TCCErrorFunc tcc_get_error_func(TCCState *S);
32 68
33/* return error/warning callback opaque pointer */69/* return error/warning callback opaque pointer */
34LIBTCCAPI void *tcc_get_error_opaque(TCCState *s);70LIBTCCAPI void *tcc_get_error_opaque(TCCState *S);
35 71
36/* set options as from command line (multiple supported) */72/* set options as from command line (multiple supported) */
37LIBTCCAPI void tcc_set_options(TCCState *s, const char *str);73LIBTCCAPI void tcc_set_options(TCCState *S, const char *str);
74
75/* set virtual io module */
76LIBTCCAPI void tcc_set_vio_module(TCCState *S, vio_module_t *vio_module);
38 77
39/*****************************/78/*****************************/
40/* preprocessor */79/* preprocessor */
41 80
42/* add include path */81/* add include path */
43LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname);82LIBTCCAPI int tcc_add_include_path(TCCState *S, const char *pathname);
44 83
45/* add in system include path */84/* add in system include path */
46LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname);85LIBTCCAPI int tcc_add_sysinclude_path(TCCState *S, const char *pathname);
47 86
48/* define preprocessor symbol 'sym'. value can be NULL, sym can be "sym=val" */87/* define preprocessor symbol 'sym'. value can be NULL, sym can be "sym=val" */
49LIBTCCAPI void tcc_define_symbol(TCCState *s, const char *sym, const char *value);88LIBTCCAPI void tcc_define_symbol(TCCState *S, const char *sym, const char *value);
50 89
51/* undefine preprocess symbol 'sym' */90/* undefine preprocess symbol 'sym' */
52LIBTCCAPI void tcc_undefine_symbol(TCCState *s, const char *sym);91LIBTCCAPI void tcc_undefine_symbol(TCCState *S, const char *sym);
53 92
54/*****************************/93/*****************************/
55/* compiling */94/* compiling */
56 95
57/* add a file (C file, dll, object, library, ld script). Return -1 if error. */96/* add a file (C file, dll, object, library, ld script). Return -1 if error. */
58LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename);97LIBTCCAPI int tcc_add_file(TCCState *S, const char *filename);
59 98
60/* compile a string containing a C source. Return -1 if error. */99/* compile a string containing a C source. Return -1 if error. */
61LIBTCCAPI int tcc_compile_string(TCCState *s, const char *buf);100LIBTCCAPI int tcc_compile_string(TCCState *S, const char *buf);
62 101
63/*****************************/102/*****************************/
64/* linking commands */103/* linking commands */
65 104
66/* set output type. MUST BE CALLED before any compilation */105/* set output type. MUST BE CALLED before any compilation */
67LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type);106LIBTCCAPI int tcc_set_output_type(TCCState *S, int output_type);
68#define TCC_OUTPUT_MEMORY 1 /* output will be run in memory (default) */107#define TCC_OUTPUT_MEMORY 1 /* output will be run in memory (default) */
69#define TCC_OUTPUT_EXE 2 /* executable file */108#define TCC_OUTPUT_EXE 2 /* executable file */
70#define TCC_OUTPUT_DLL 3 /* dynamic library */109#define TCC_OUTPUT_DLL 3 /* dynamic library */
@@ -72,24 +111,24 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type); · 1 unmodified line
72#define TCC_OUTPUT_PREPROCESS 5 /* only preprocess (used internally) */111#define TCC_OUTPUT_PREPROCESS 5 /* only preprocess (used internally) */
73 112
74/* equivalent to -Lpath option */113/* equivalent to -Lpath option */
75LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname);114LIBTCCAPI int tcc_add_library_path(TCCState *S, const char *pathname);
76 115
77/* the library name is the same as the argument of the '-l' option */116/* the library name is the same as the argument of the '-l' option */
78LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname);117LIBTCCAPI int tcc_add_library(TCCState *S, const char *libraryname);
79 118
80/* add a symbol to the compiled program */119/* add a symbol to the compiled program */
81LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val);120LIBTCCAPI int tcc_add_symbol(TCCState *S, const char *name, const void *val);
82 121
83/* output an executable, library or object file. DO NOT call122/* output an executable, library or object file. DO NOT call
84 tcc_relocate() before. */123 tcc_relocate() before. */
85LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename);124LIBTCCAPI int tcc_output_file(TCCState *S, const char *filename);
86 125
87/* link and run main() function and return its value. DO NOT call126/* link and run main() function and return its value. DO NOT call
88 tcc_relocate() before. */127 tcc_relocate() before. */
89LIBTCCAPI int tcc_run(TCCState *s, int argc, char **argv);128LIBTCCAPI int tcc_run(TCCState *S, int argc, char **argv);
90 129
91/* do all relocations (needed before using tcc_get_symbol()) */130/* do all relocations (needed before using tcc_get_symbol()) */
92LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr);131LIBTCCAPI int tcc_relocate(TCCState *S, void *ptr);
93/* possible values for 'ptr':132/* possible values for 'ptr':
94 - TCC_RELOCATE_AUTO : Allocate and manage memory internally133 - TCC_RELOCATE_AUTO : Allocate and manage memory internally
95 - NULL : return required memory size for the step below134 - NULL : return required memory size for the step below
@@ -98,12 +137,24 @@ LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr); · 2 unmodified lines
98#define TCC_RELOCATE_AUTO (void*)1137#define TCC_RELOCATE_AUTO (void*)1
99 138
100/* return symbol value or NULL if not found */139/* return symbol value or NULL if not found */
101LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name);140LIBTCCAPI void *tcc_get_symbol(TCCState *S, const char *name);
102 141
103/* return symbol value or NULL if not found */142/* return symbol value or NULL if not found */
104LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,143LIBTCCAPI void tcc_list_symbols(TCCState *S, void *ctx,
105 void (*symbol_cb)(void *ctx, const char *name, const void *val));144 void (*symbol_cb)(void *ctx, const char *name, const void *val));
106 145
146typedef int (*tcc_cmpfun)(const void *, const void *, void *);
147LIBTCCAPI void tcc_qsort_s(void *base, size_t nel, size_t width, tcc_cmpfun cmp, void *ctx);
148
149enum { /*need better names for some of then*/
150 TCC_OPTION_d_BI = 1,
151 TCC_OPTION_d_D = 3,
152 TCC_OPTION_d_4 = 4,
153 TCC_OPTION_d_M = 7,
154 TCC_OPTION_d_t = 16,
155 TCC_OPTION_d_32 = 32,
156};
157
107#ifdef __cplusplus158#ifdef __cplusplus
108}159}
109#endif160#endif
riscv64-asm.c+187−187
@@ -9,9 +9,9 @@ · 8 unmodified lines
9#define CONFIG_TCC_ASM9#define CONFIG_TCC_ASM
10#define NB_ASM_REGS 3210#define NB_ASM_REGS 32
11 11
12ST_FUNC void g(int c);12ST_FUNC void g(TCCState* S, int c);
13ST_FUNC void gen_le16(int c);13ST_FUNC void gen_le16(TCCState* S, int c);
14ST_FUNC void gen_le32(int c);14ST_FUNC void gen_le32(TCCState* S, int c);
15 15
16/*************************************************************/16/*************************************************************/
17#else17#else
@@ -20,85 +20,85 @@ ST_FUNC void gen_le32(int c); · 2 unmodified lines
20#include "tcc.h"20#include "tcc.h"
21 21
22/* XXX: make it faster ? */22/* XXX: make it faster ? */
23ST_FUNC void g(int c)23ST_FUNC void g(TCCState* S, int c)
24{24{
25 int ind1;25 int ind1;
26 if (nocode_wanted)26 if (S->tccgen_nocode_wanted)
27 return;27 return;
28 ind1 = ind + 1;28 ind1 = S->tccgen_ind + 1;
29 if (ind1 > cur_text_section->data_allocated)29 if (ind1 > cur_text_section->data_allocated)
30 section_realloc(cur_text_section, ind1);30 section_realloc(S, cur_text_section, ind1);
31 cur_text_section->data[ind] = c;31 cur_text_section->data[S->tccgen_ind] = c;
32 ind = ind1;32 S->tccgen_ind = ind1;
33}33}
34 34
35ST_FUNC void gen_le16 (int i)35ST_FUNC void gen_le16 (TCCState* S, int i)
36{36{
37 g(i);37 g(S, i);
38 g(i>>8);38 g(S, i>>8);
39}39}
40 40
41ST_FUNC void gen_le32 (int i)41ST_FUNC void gen_le32 (TCCState* S, int i)
42{42{
43 int ind1;43 int ind1;
44 if (nocode_wanted)44 if (S->tccgen_nocode_wanted)
45 return;45 return;
46 ind1 = ind + 4;46 ind1 = S->tccgen_ind + 4;
47 if (ind1 > cur_text_section->data_allocated)47 if (ind1 > cur_text_section->data_allocated)
48 section_realloc(cur_text_section, ind1);48 section_realloc(S, cur_text_section, ind1);
49 cur_text_section->data[ind++] = i & 0xFF;49 cur_text_section->data[S->tccgen_ind++] = i & 0xFF;
50 cur_text_section->data[ind++] = (i >> 8) & 0xFF;50 cur_text_section->data[S->tccgen_ind++] = (i >> 8) & 0xFF;
51 cur_text_section->data[ind++] = (i >> 16) & 0xFF;51 cur_text_section->data[S->tccgen_ind++] = (i >> 16) & 0xFF;
52 cur_text_section->data[ind++] = (i >> 24) & 0xFF;52 cur_text_section->data[S->tccgen_ind++] = (i >> 24) & 0xFF;
53}53}
54 54
55ST_FUNC void gen_expr32(ExprValue *pe)55ST_FUNC void gen_expr32(TCCState* S, ExprValue *pe)
56{56{
57 gen_le32(pe->v);57 gen_le32(S, pe->v);
58}58}
59 59
60static void asm_emit_opcode(uint32_t opcode) {60static void asm_emit_opcode(TCCState* S, uint32_t opcode) {
61 gen_le32(opcode);61 gen_le32(S, opcode);
62}62}
63 63
64static void asm_nullary_opcode(TCCState *s1, int token)64static void asm_nullary_opcode(TCCState *S, int token)
65{65{
66 switch (token) {66 switch (token) {
67 // Sync instructions67 // Sync instructions
68 68
69 case TOK_ASM_fence: // I69 case TOK_ASM_fence: // I
70 asm_emit_opcode((0x3 << 2) | 3 | (0 << 12));70 asm_emit_opcode(S, (0x3 << 2) | 3 | (0 << 12));
71 return;71 return;
72 case TOK_ASM_fence_i: // I72 case TOK_ASM_fence_i: // I
73 asm_emit_opcode((0x3 << 2) | 3| (1 << 12));73 asm_emit_opcode(S, (0x3 << 2) | 3| (1 << 12));
74 return;74 return;
75 75
76 // System calls76 // System calls
77 77
78 case TOK_ASM_scall: // I (pseudo)78 case TOK_ASM_scall: // I (pseudo)
79 asm_emit_opcode((0x1C << 2) | 3 | (0 << 12));79 asm_emit_opcode(S, (0x1C << 2) | 3 | (0 << 12));
80 return;80 return;
81 case TOK_ASM_sbreak: // I (pseudo)81 case TOK_ASM_sbreak: // I (pseudo)
82 asm_emit_opcode((0x1C << 2) | 3 | (0 << 12) | (1 << 20));82 asm_emit_opcode(S, (0x1C << 2) | 3 | (0 << 12) | (1 << 20));
83 return;83 return;
84 84
85 // Privileged Instructions85 // Privileged Instructions
86 86
87 case TOK_ASM_ecall:87 case TOK_ASM_ecall:
88 asm_emit_opcode((0x1C << 2) | 3 | (0 << 20));88 asm_emit_opcode(S, (0x1C << 2) | 3 | (0 << 20));
89 return;89 return;
90 case TOK_ASM_ebreak:90 case TOK_ASM_ebreak:
91 asm_emit_opcode((0x1C << 2) | 3 | (1 << 20));91 asm_emit_opcode(S, (0x1C << 2) | 3 | (1 << 20));
92 return;92 return;
93 93
94 // Other94 // Other
95 95
96 case TOK_ASM_wfi:96 case TOK_ASM_wfi:
97 asm_emit_opcode((0x1C << 2) | 3 | (0x105 << 20));97 asm_emit_opcode(S, (0x1C << 2) | 3 | (0x105 << 20));
98 return;98 return;
99 99
100 default:100 default:
101 expect("nullary instruction");101 expect(S, "nullary instruction");
102 }102 }
103}103}
104 104
@@ -121,30 +121,30 @@ typedef struct Operand { · 16 unmodified lines
121} Operand;121} Operand;
122 122
123/* Parse a text containing operand and store the result in OP */123/* Parse a text containing operand and store the result in OP */
124static void parse_operand(TCCState *s1, Operand *op)124static void parse_operand(TCCState *S, Operand *op)
125{125{
126 ExprValue e;126 ExprValue e;
127 int8_t reg;127 int8_t reg;
128 128
129 op->type = 0;129 op->type = 0;
130 130
131 if ((reg = asm_parse_regvar(tok)) != -1) {131 if ((reg = asm_parse_regvar(S, S->tccpp_tok)) != -1) {
132 next(); // skip register name132 next(S); // skip register name
133 op->type = OP_REG;133 op->type = OP_REG;
134 op->reg = (uint8_t) reg;134 op->reg = (uint8_t) reg;
135 return;135 return;
136 } else if (tok == '$') {136 } else if (S->tccpp_tok == '$') {
137 /* constant value */137 /* constant value */
138 next(); // skip '#' or '$'138 next(S); // skip '#' or '$'
139 }139 }
140 asm_expr(s1, &e);140 asm_expr(S, &e);
141 op->type = OP_IM32;141 op->type = OP_IM32;
142 op->e = e;142 op->e = e;
143 if (!op->e.sym) {143 if (!op->e.sym) {
144 if ((int) op->e.v >= -2048 && (int) op->e.v < 2048)144 if ((int) op->e.v >= -2048 && (int) op->e.v < 2048)
145 op->type = OP_IM12S;145 op->type = OP_IM12S;
146 } else146 } else
147 expect("operand");147 expect(S, "operand");
148}148}
149 149
150#define ENCODE_RS1(register_index) ((register_index) << 15)150#define ENCODE_RS1(register_index) ((register_index) << 15)
@@ -152,96 +152,96 @@ static void parse_operand(TCCState *s1, Operand *op) · 1 unmodified line
152#define ENCODE_RD(register_index) ((register_index) << 7)152#define ENCODE_RD(register_index) ((register_index) << 7)
153 153
154// Note: Those all map to CSR--so they are pseudo-instructions.154// Note: Those all map to CSR--so they are pseudo-instructions.
155static void asm_unary_opcode(TCCState *s1, int token)155static void asm_unary_opcode(TCCState *S, int token)
156{156{
157 uint32_t opcode = (0x1C << 2) | 3 | (2 << 12);157 uint32_t opcode = (0x1C << 2) | 3 | (2 << 12);
158 Operand op;158 Operand op;
159 parse_operand(s1, &op);159 parse_operand(S, &op);
160 if (op.type != OP_REG) {160 if (op.type != OP_REG) {
161 expect("register");161 expect(S, "register");
162 return;162 return;
163 }163 }
164 opcode |= ENCODE_RD(op.reg);164 opcode |= ENCODE_RD(op.reg);
165 165
166 switch (token) {166 switch (token) {
167 case TOK_ASM_rdcycle:167 case TOK_ASM_rdcycle:
168 asm_emit_opcode(opcode | (0xC00 << 20));168 asm_emit_opcode(S, opcode | (0xC00 << 20));
169 return;169 return;
170 case TOK_ASM_rdcycleh:170 case TOK_ASM_rdcycleh:
171 asm_emit_opcode(opcode | (0xC80 << 20));171 asm_emit_opcode(S, opcode | (0xC80 << 20));
172 return;172 return;
173 case TOK_ASM_rdtime:173 case TOK_ASM_rdtime:
174 asm_emit_opcode(opcode | (0xC01 << 20) | ENCODE_RD(op.reg));174 asm_emit_opcode(S, opcode | (0xC01 << 20) | ENCODE_RD(op.reg));
175 return;175 return;
176 case TOK_ASM_rdtimeh:176 case TOK_ASM_rdtimeh:
177 asm_emit_opcode(opcode | (0xC81 << 20) | ENCODE_RD(op.reg));177 asm_emit_opcode(S, opcode | (0xC81 << 20) | ENCODE_RD(op.reg));
178 return;178 return;
179 case TOK_ASM_rdinstret:179 case TOK_ASM_rdinstret:
180 asm_emit_opcode(opcode | (0xC02 << 20) | ENCODE_RD(op.reg));180 asm_emit_opcode(S, opcode | (0xC02 << 20) | ENCODE_RD(op.reg));
181 return;181 return;
182 case TOK_ASM_rdinstreth:182 case TOK_ASM_rdinstreth:
183 asm_emit_opcode(opcode | (0xC82 << 20) | ENCODE_RD(op.reg));183 asm_emit_opcode(S, opcode | (0xC82 << 20) | ENCODE_RD(op.reg));
184 return;184 return;
185 default:185 default:
186 expect("unary instruction");186 expect(S, "unary instruction");
187 }187 }
188}188}
189 189
190static void asm_emit_u(int token, uint32_t opcode, const Operand* rd, const Operand* rs2)190static void asm_emit_u(TCCState *S, int token, uint32_t opcode, const Operand* rd, const Operand* rs2)
191{191{
192 if (rd->type != OP_REG) {192 if (rd->type != OP_REG) {
193 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));193 tcc_error(S, "'%s': Expected destination operand that is a register", get_tok_str(S, token, NULL));
194 return;194 return;
195 }195 }
196 if (rs2->type != OP_IM12S && rs2->type != OP_IM32) {196 if (rs2->type != OP_IM12S && rs2->type != OP_IM32) {
197 tcc_error("'%s': Expected second source operand that is an immediate value", get_tok_str(token, NULL));197 tcc_error(S, "'%s': Expected second source operand that is an immediate value", get_tok_str(S, token, NULL));
198 return;198 return;
199 } else if (rs2->e.v >= 0x100000) {199 } else if (rs2->e.v >= 0x100000) {
200 tcc_error("'%s': Expected second source operand that is an immediate value between 0 and 0xfffff", get_tok_str(token, NULL));200 tcc_error(S, "'%s': Expected second source operand that is an immediate value between 0 and 0xfffff", get_tok_str(S, token, NULL));
201 return;201 return;
202 }202 }
203 /* U-type instruction:203 /* U-type instruction:
204 31...12 imm[31:12]204 31...12 imm[31:12]
205 11...7 rd205 11...7 rd
206 6...0 opcode */206 6...0 opcode */
207 gen_le32(opcode | ENCODE_RD(rd->reg) | (rs2->e.v << 12));207 gen_le32(S, opcode | ENCODE_RD(rd->reg) | (rs2->e.v << 12));
208}208}
209 209
210static void asm_binary_opcode(TCCState* s1, int token)210static void asm_binary_opcode(TCCState* S, int token)
211{211{
212 Operand ops[2];212 Operand ops[2];
213 parse_operand(s1, &ops[0]);213 parse_operand(S, &ops[0]);
214 if (tok == ',')214 if (S->tccpp_tok == ',')
215 next();215 next(S);
216 else216 else
217 expect("','");217 expect(S, "','");
218 parse_operand(s1, &ops[1]);218 parse_operand(S, &ops[1]);
219 219
220 switch (token) {220 switch (token) {
221 case TOK_ASM_lui:221 case TOK_ASM_lui:
222 asm_emit_u(token, (0xD << 2) | 3, &ops[0], &ops[1]);222 asm_emit_u(S, token, (0xD << 2) | 3, &ops[0], &ops[1]);
223 return;223 return;
224 case TOK_ASM_auipc:224 case TOK_ASM_auipc:
225 asm_emit_u(token, (0x05 << 2) | 3, &ops[0], &ops[1]);225 asm_emit_u(S, token, (0x05 << 2) | 3, &ops[0], &ops[1]);
226 return;226 return;
227 default:227 default:
228 expect("binary instruction");228 expect(S, "binary instruction");
229 }229 }
230}230}
231 231
232/* caller: Add funct3, funct7 into opcode */232/* caller: Add funct3, funct7 into opcode */
233static void asm_emit_r(int token, uint32_t opcode, const Operand* rd, const Operand* rs1, const Operand* rs2)233static void asm_emit_r(TCCState* S, int token, uint32_t opcode, const Operand* rd, const Operand* rs1, const Operand* rs2)
234{234{
235 if (rd->type != OP_REG) {235 if (rd->type != OP_REG) {
236 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));236 tcc_error(S, "'%s': Expected destination operand that is a register", get_tok_str(S, token, NULL));
237 return;237 return;
238 }238 }
239 if (rs1->type != OP_REG) {239 if (rs1->type != OP_REG) {
240 tcc_error("'%s': Expected first source operand that is a register", get_tok_str(token, NULL));240 tcc_error(S, "'%s': Expected first source operand that is a register", get_tok_str(S, token, NULL));
241 return;241 return;
242 }242 }
243 if (rs2->type != OP_REG) {243 if (rs2->type != OP_REG) {
244 tcc_error("'%s': Expected second source operand that is a register or immediate", get_tok_str(token, NULL));244 tcc_error(S, "'%s': Expected second source operand that is a register or immediate", get_tok_str(S, token, NULL));
245 return;245 return;
246 }246 }
247 /* R-type instruction:247 /* R-type instruction:
@@ -251,22 +251,22 @@ static void asm_emit_r(int token, uint32_t opcode, const Operand* rd, const Oper · 3 unmodified lines
251 14...12 funct3251 14...12 funct3
252 11...7 rd252 11...7 rd
253 6...0 opcode */253 6...0 opcode */
254 gen_le32(opcode | ENCODE_RD(rd->reg) | ENCODE_RS1(rs1->reg) | ENCODE_RS2(rs2->reg));254 gen_le32(S, opcode | ENCODE_RD(rd->reg) | ENCODE_RS1(rs1->reg) | ENCODE_RS2(rs2->reg));
255}255}
256 256
257/* caller: Add funct3 into opcode */257/* caller: Add funct3 into opcode */
258static void asm_emit_i(int token, uint32_t opcode, const Operand* rd, const Operand* rs1, const Operand* rs2)258static void asm_emit_i(TCCState* S, int token, uint32_t opcode, const Operand* rd, const Operand* rs1, const Operand* rs2)
259{259{
260 if (rd->type != OP_REG) {260 if (rd->type != OP_REG) {
261 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));261 tcc_error(S, "'%s': Expected destination operand that is a register", get_tok_str(S, token, NULL));
262 return;262 return;
263 }263 }
264 if (rs1->type != OP_REG) {264 if (rs1->type != OP_REG) {
265 tcc_error("'%s': Expected first source operand that is a register", get_tok_str(token, NULL));265 tcc_error(S, "'%s': Expected first source operand that is a register", get_tok_str(S, token, NULL));
266 return;266 return;
267 }267 }
268 if (rs2->type != OP_IM12S) {268 if (rs2->type != OP_IM12S) {
269 tcc_error("'%s': Expected second source operand that is an immediate value between 0 and 4095", get_tok_str(token, NULL));269 tcc_error(S, "'%s': Expected second source operand that is an immediate value between 0 and 4095", get_tok_str(S, token, NULL));
270 return;270 return;
271 }271 }
272 /* I-type instruction:272 /* I-type instruction:
@@ -276,156 +276,156 @@ static void asm_emit_i(int token, uint32_t opcode, const Operand* rd, const Oper · 3 unmodified lines
276 11...7 rd276 11...7 rd
277 6...0 opcode */277 6...0 opcode */
278 278
279 gen_le32(opcode | ENCODE_RD(rd->reg) | ENCODE_RS1(rs1->reg) | (rs2->e.v << 20));279 gen_le32(S, opcode | ENCODE_RD(rd->reg) | ENCODE_RS1(rs1->reg) | (rs2->e.v << 20));
280}280}
281 281
282static void asm_shift_opcode(TCCState *s1, int token)282static void asm_shift_opcode(TCCState *S, int token)
283{283{
284 Operand ops[3];284 Operand ops[3];
285 parse_operand(s1, &ops[0]);285 parse_operand(S, &ops[0]);
286 if (tok == ',')286 if (S->tccpp_tok == ',')
287 next();287 next(S);
288 else288 else
289 expect("','");289 expect(S, "','");
290 parse_operand(s1, &ops[1]);290 parse_operand(S, &ops[1]);
291 if (tok == ',')291 if (S->tccpp_tok == ',')
292 next();292 next(S);
293 else293 else
294 expect("','");294 expect(S, "','");
295 parse_operand(s1, &ops[2]);295 parse_operand(S, &ops[2]);
296 296
297 switch (token) {297 switch (token) {
298 case TOK_ASM_sll:298 case TOK_ASM_sll:
299 asm_emit_r(token, (0xC << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]);299 asm_emit_r(S, token, (0xC << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]);
300 return;300 return;
301 case TOK_ASM_slli:301 case TOK_ASM_slli:
302 asm_emit_i(token, (4 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]);302 asm_emit_i(S, token, (4 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]);
303 return;303 return;
304 case TOK_ASM_srl:304 case TOK_ASM_srl:
305 asm_emit_r(token, (0xC << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]);305 asm_emit_r(S, token, (0xC << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]);
306 return;306 return;
307 case TOK_ASM_srli:307 case TOK_ASM_srli:
308 asm_emit_i(token, (0x4 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);308 asm_emit_i(S, token, (0x4 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);
309 return;309 return;
310 case TOK_ASM_sra:310 case TOK_ASM_sra:
311 asm_emit_r(token, (0xC << 2) | 3 | (5 << 12) | (32 << 25), &ops[0], &ops[1], &ops[2]);311 asm_emit_r(S, token, (0xC << 2) | 3 | (5 << 12) | (32 << 25), &ops[0], &ops[1], &ops[2]);
312 return;312 return;
313 case TOK_ASM_srai:313 case TOK_ASM_srai:
314 asm_emit_i(token, (0x4 << 2) | 3 | (5 << 12) | (16 << 26), &ops[0], &ops[1], &ops[2]);314 asm_emit_i(S, token, (0x4 << 2) | 3 | (5 << 12) | (16 << 26), &ops[0], &ops[1], &ops[2]);
315 return;315 return;
316 case TOK_ASM_sllw:316 case TOK_ASM_sllw:
317 asm_emit_r(token, (0xE << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]);317 asm_emit_r(S, token, (0xE << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]);
318 return;318 return;
319 case TOK_ASM_slliw:319 case TOK_ASM_slliw:
320 asm_emit_i(token, (6 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]);320 asm_emit_i(S, token, (6 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]);
321 return;321 return;
322 case TOK_ASM_srlw:322 case TOK_ASM_srlw:
323 asm_emit_r(token, (0xE << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);323 asm_emit_r(S, token, (0xE << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);
324 return;324 return;
325 case TOK_ASM_srliw:325 case TOK_ASM_srliw:
326 asm_emit_i(token, (0x6 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);326 asm_emit_i(S, token, (0x6 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);
327 return;327 return;
328 case TOK_ASM_sraw:328 case TOK_ASM_sraw:
329 asm_emit_r(token, (0xE << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);329 asm_emit_r(S, token, (0xE << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);
330 return;330 return;
331 case TOK_ASM_sraiw:331 case TOK_ASM_sraiw:
332 asm_emit_i(token, (0x6 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);332 asm_emit_i(S, token, (0x6 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);
333 return;333 return;
334 default:334 default:
335 expect("shift instruction");335 expect(S, "shift instruction");
336 }336 }
337}337}
338 338
339static void asm_data_processing_opcode(TCCState* s1, int token)339static void asm_data_processing_opcode(TCCState* S, int token)
340{340{
341 Operand ops[3];341 Operand ops[3];
342 parse_operand(s1, &ops[0]);342 parse_operand(S, &ops[0]);
343 if (tok == ',')343 if (S->tccpp_tok == ',')
344 next();344 next(S);
345 else345 else
346 expect("','");346 expect(S, "','");
347 parse_operand(s1, &ops[1]);347 parse_operand(S, &ops[1]);
348 if (tok == ',')348 if (S->tccpp_tok == ',')
349 next();349 next(S);
350 else350 else
351 expect("','");351 expect(S, "','");
352 parse_operand(s1, &ops[2]);352 parse_operand(S, &ops[2]);
353 353
354 switch (token) {354 switch (token) {
355 // Arithmetic (RD,RS1,(RS2|IMM)); R-format, I-format or U-format355 // Arithmetic (RD,RS1,(RS2|IMM)); R-format, I-format or U-format
356 356
357 case TOK_ASM_add:357 case TOK_ASM_add:
358 asm_emit_r(token, (0xC << 2) | 3, &ops[0], &ops[1], &ops[2]);358 asm_emit_r(S, token, (0xC << 2) | 3, &ops[0], &ops[1], &ops[2]);
359 return;359 return;
360 case TOK_ASM_addi:360 case TOK_ASM_addi:
361 asm_emit_i(token, (4 << 2) | 3, &ops[0], &ops[1], &ops[2]);361 asm_emit_i(S, token, (4 << 2) | 3, &ops[0], &ops[1], &ops[2]);
362 return;362 return;
363 case TOK_ASM_sub:363 case TOK_ASM_sub:
364 asm_emit_r(token, (0xC << 2) | 3 | (32 << 25), &ops[0], &ops[1], &ops[2]);364 asm_emit_r(S, token, (0xC << 2) | 3 | (32 << 25), &ops[0], &ops[1], &ops[2]);
365 return;365 return;
366 case TOK_ASM_addw:366 case TOK_ASM_addw:
367 asm_emit_r(token, (0xE << 2) | 3 | (0 << 12), &ops[0], &ops[1], &ops[2]);367 asm_emit_r(S, token, (0xE << 2) | 3 | (0 << 12), &ops[0], &ops[1], &ops[2]);
368 return;368 return;
369 case TOK_ASM_addiw: // 64 bit369 case TOK_ASM_addiw: // 64 bit
370 asm_emit_i(token, (0x6 << 2) | 3 | (0 << 12), &ops[0], &ops[1], &ops[2]);370 asm_emit_i(S, token, (0x6 << 2) | 3 | (0 << 12), &ops[0], &ops[1], &ops[2]);
371 return;371 return;
372 case TOK_ASM_subw:372 case TOK_ASM_subw:
373 asm_emit_r(token, (0xE << 2) | 3 | (0 << 12) | (32 << 25), &ops[0], &ops[1], &ops[2]);373 asm_emit_r(S, token, (0xE << 2) | 3 | (0 << 12) | (32 << 25), &ops[0], &ops[1], &ops[2]);
374 return;374 return;
375 375
376 // Logical (RD,RS1,(RS2|IMM)); R-format or I-format376 // Logical (RD,RS1,(RS2|IMM)); R-format or I-format
377 377
378 case TOK_ASM_xor:378 case TOK_ASM_xor:
379 asm_emit_r(token, (0xC << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]);379 asm_emit_r(S, token, (0xC << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]);
380 return;380 return;
381 case TOK_ASM_xori:381 case TOK_ASM_xori:
382 asm_emit_i(token, (0x4 << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]);382 asm_emit_i(S, token, (0x4 << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]);
383 return;383 return;
384 case TOK_ASM_or:384 case TOK_ASM_or:
385 asm_emit_r(token, (0xC << 2) | 3 | (6 << 12), &ops[0], &ops[1], &ops[2]);385 asm_emit_r(S, token, (0xC << 2) | 3 | (6 << 12), &ops[0], &ops[1], &ops[2]);
386 return;386 return;
387 case TOK_ASM_ori:387 case TOK_ASM_ori:
388 asm_emit_i(token, (0x4 << 2) | 3 | (6 << 12), &ops[0], &ops[1], &ops[2]);388 asm_emit_i(S, token, (0x4 << 2) | 3 | (6 << 12), &ops[0], &ops[1], &ops[2]);
389 return;389 return;
390 case TOK_ASM_and:390 case TOK_ASM_and:
391 asm_emit_r(token, (0xC << 2) | 3 | (7 << 12), &ops[0], &ops[1], &ops[2]);391 asm_emit_r(S, token, (0xC << 2) | 3 | (7 << 12), &ops[0], &ops[1], &ops[2]);
392 return;392 return;
393 case TOK_ASM_andi:393 case TOK_ASM_andi:
394 asm_emit_i(token, (0x4 << 2) | 3 | (7 << 12), &ops[0], &ops[1], &ops[2]);394 asm_emit_i(S, token, (0x4 << 2) | 3 | (7 << 12), &ops[0], &ops[1], &ops[2]);
395 return;395 return;
396 396
397 // Compare (RD,RS1,(RS2|IMM)); R-format or I-format397 // Compare (RD,RS1,(RS2|IMM)); R-format or I-format
398 398
399 case TOK_ASM_slt:399 case TOK_ASM_slt:
400 asm_emit_r(token, (0xC << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]);400 asm_emit_r(S, token, (0xC << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]);
401 return;401 return;
402 case TOK_ASM_slti:402 case TOK_ASM_slti:
403 asm_emit_i(token, (0x4 << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]);403 asm_emit_i(S, token, (0x4 << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]);
404 return;404 return;
405 case TOK_ASM_sltu:405 case TOK_ASM_sltu:
406 asm_emit_r(token, (0xC << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]);406 asm_emit_r(S, token, (0xC << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]);
407 return;407 return;
408 case TOK_ASM_sltiu:408 case TOK_ASM_sltiu:
409 asm_emit_i(token, (0x4 << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]);409 asm_emit_i(S, token, (0x4 << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]);
410 return;410 return;
411 default:411 default:
412 expect("known data processing instruction");412 expect(S, "known data processing instruction");
413 }413 }
414}414}
415 415
416/* caller: Add funct3 to opcode */416/* caller: Add funct3 to opcode */
417static void asm_emit_s(int token, uint32_t opcode, const Operand* rs1, const Operand* rs2, const Operand* imm)417static void asm_emit_s(TCCState* S, int token, uint32_t opcode, const Operand* rs1, const Operand* rs2, const Operand* imm)
418{418{
419 if (rs1->type != OP_REG) {419 if (rs1->type != OP_REG) {
420 tcc_error("'%s': Expected first source operand that is a register", get_tok_str(token, NULL));420 tcc_error(S, "'%s': Expected first source operand that is a register", get_tok_str(S, token, NULL));
421 return;421 return;
422 }422 }
423 if (rs2->type != OP_REG) {423 if (rs2->type != OP_REG) {
424 tcc_error("'%s': Expected second source operand that is a register", get_tok_str(token, NULL));424 tcc_error(S, "'%s': Expected second source operand that is a register", get_tok_str(S, token, NULL));
425 return;425 return;
426 }426 }
427 if (imm->type != OP_IM12S) {427 if (imm->type != OP_IM12S) {
428 tcc_error("'%s': Expected third operand that is an immediate value between 0 and 0xfff", get_tok_str(token, NULL));428 tcc_error(S, "'%s': Expected third operand that is an immediate value between 0 and 0xfff", get_tok_str(S, token, NULL));
429 return;429 return;
430 }430 }
431 {431 {
@@ -438,112 +438,112 @@ static void asm_emit_s(int token, uint32_t opcode, const Operand* rs1, const Ope · 6 unmodified lines
438 11...7 imm[4:0]438 11...7 imm[4:0]
439 6...0 opcode439 6...0 opcode
440 opcode always fixed pos. */440 opcode always fixed pos. */
441 gen_le32(opcode | ENCODE_RS1(rs1->reg) | ENCODE_RS2(rs2->reg) | ((v & 0x1F) << 7) | ((v >> 5) << 25));441 gen_le32(S, opcode | ENCODE_RS1(rs1->reg) | ENCODE_RS2(rs2->reg) | ((v & 0x1F) << 7) | ((v >> 5) << 25));
442 }442 }
443}443}
444 444
445static void asm_data_transfer_opcode(TCCState* s1, int token)445static void asm_data_transfer_opcode(TCCState* S, int token)
446{446{
447 Operand ops[3];447 Operand ops[3];
448 parse_operand(s1, &ops[0]);448 parse_operand(S, &ops[0]);
449 if (ops[0].type != OP_REG) {449 if (ops[0].type != OP_REG) {
450 expect("register");450 expect(S, "register");
451 return;451 return;
452 }452 }
453 if (tok == ',')453 if (S->tccpp_tok == ',')
454 next();454 next(S);
455 else455 else
456 expect("','");456 expect(S, "','");
457 parse_operand(s1, &ops[1]);457 parse_operand(S, &ops[1]);
458 if (ops[1].type != OP_REG) {458 if (ops[1].type != OP_REG) {
459 expect("register");459 expect(S, "register");
460 return;460 return;
461 }461 }
462 if (tok == ',')462 if (S->tccpp_tok == ',')
463 next();463 next(S);
464 else464 else
465 expect("','");465 expect(S, "','");
466 parse_operand(s1, &ops[2]);466 parse_operand(S, &ops[2]);
467 467
468 switch (token) {468 switch (token) {
469 // Loads (RD,RS1,I); I-format469 // Loads (RD,RS1,I); I-format
470 470
471 case TOK_ASM_lb:471 case TOK_ASM_lb:
472 asm_emit_i(token, (0x0 << 2) | 3, &ops[0], &ops[1], &ops[2]);472 asm_emit_i(S, token, (0x0 << 2) | 3, &ops[0], &ops[1], &ops[2]);
473 return;473 return;
474 case TOK_ASM_lh:474 case TOK_ASM_lh:
475 asm_emit_i(token, (0x0 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]);475 asm_emit_i(S, token, (0x0 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]);
476 return;476 return;
477 case TOK_ASM_lw:477 case TOK_ASM_lw:
478 asm_emit_i(token, (0x0 << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]);478 asm_emit_i(S, token, (0x0 << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]);
479 return;479 return;
480 case TOK_ASM_lbu:480 case TOK_ASM_lbu:
481 asm_emit_i(token, (0x0 << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]);481 asm_emit_i(S, token, (0x0 << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]);
482 return;482 return;
483 case TOK_ASM_lhu:483 case TOK_ASM_lhu:
484 asm_emit_i(token, (0x0 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);484 asm_emit_i(S, token, (0x0 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);
485 return;485 return;
486 // 64 bit486 // 64 bit
487 case TOK_ASM_ld:487 case TOK_ASM_ld:
488 asm_emit_i(token, (0x0 << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]);488 asm_emit_i(S, token, (0x0 << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]);
489 return;489 return;
490 case TOK_ASM_lwu:490 case TOK_ASM_lwu:
491 asm_emit_i(token, (0x0 << 2) | 3 | (6 << 12), &ops[0], &ops[1], &ops[2]);491 asm_emit_i(S, token, (0x0 << 2) | 3 | (6 << 12), &ops[0], &ops[1], &ops[2]);
492 return;492 return;
493 493
494 // Stores (RS1,RS2,I); S-format494 // Stores (RS1,RS2,I); S-format
495 495
496 case TOK_ASM_sb:496 case TOK_ASM_sb:
497 asm_emit_s(token, (0x8 << 2) | 3 | (0 << 12), &ops[0], &ops[1], &ops[2]);497 asm_emit_s(S, token, (0x8 << 2) | 3 | (0 << 12), &ops[0], &ops[1], &ops[2]);
498 return;498 return;
499 case TOK_ASM_sh:499 case TOK_ASM_sh:
500 asm_emit_s(token, (0x8 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]);500 asm_emit_s(S, token, (0x8 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]);
501 return;501 return;
502 case TOK_ASM_sw:502 case TOK_ASM_sw:
503 asm_emit_s(token, (0x8 << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]);503 asm_emit_s(S, token, (0x8 << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]);
504 return;504 return;
505 case TOK_ASM_sd:505 case TOK_ASM_sd:
506 asm_emit_s(token, (0x8 << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]);506 asm_emit_s(S, token, (0x8 << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]);
507 return;507 return;
508 508
509 default:509 default:
510 expect("known data transfer instruction");510 expect(S, "known data transfer instruction");
511 }511 }
512}512}
513 513
514static void asm_branch_opcode(TCCState* s1, int token)514static void asm_branch_opcode(TCCState* S, int token)
515{515{
516 // Branch (RS1,RS2,IMM); SB-format516 // Branch (RS1,RS2,IMM); SB-format
517 uint32_t opcode = (0x18 << 2) | 3;517 uint32_t opcode = (0x18 << 2) | 3;
518 uint32_t offset = 0;518 uint32_t offset = 0;
519 Operand ops[3];519 Operand ops[3];
520 parse_operand(s1, &ops[0]);520 parse_operand(S, &ops[0]);
521 if (ops[0].type != OP_REG) {521 if (ops[0].type != OP_REG) {
522 expect("register");522 expect(S, "register");
523 return;523 return;
524 }524 }
525 if (tok == ',')525 if (S->tccpp_tok == ',')
526 next();526 next(S);
527 else527 else
528 expect("','");528 expect(S, "','");
529 parse_operand(s1, &ops[1]);529 parse_operand(S, &ops[1]);
530 if (ops[1].type != OP_REG) {530 if (ops[1].type != OP_REG) {
531 expect("register");531 expect(S, "register");
532 return;532 return;
533 }533 }
534 if (tok == ',')534 if (S->tccpp_tok == ',')
535 next();535 next(S);
536 else536 else
537 expect("','");537 expect(S, "','");
538 parse_operand(s1, &ops[2]);538 parse_operand(S, &ops[2]);
539 539
540 if (ops[2].type != OP_IM12S) {540 if (ops[2].type != OP_IM12S) {
541 tcc_error("'%s': Expected third operand that is an immediate value between 0 and 0xfff", get_tok_str(token, NULL));541 tcc_error(S, "'%s': Expected third operand that is an immediate value between 0 and 0xfff", get_tok_str(S, token, NULL));
542 return;542 return;
543 }543 }
544 offset = ops[2].e.v;544 offset = ops[2].e.v;
545 if (offset & 1) {545 if (offset & 1) {
546 tcc_error("'%s': Expected third operand that is an even immediate value", get_tok_str(token, NULL));546 tcc_error(S, "'%s': Expected third operand that is an even immediate value", get_tok_str(S, token, NULL));
547 return;547 return;
548 }548 }
549 549
@@ -567,12 +567,12 @@ static void asm_branch_opcode(TCCState* s1, int token) · 17 unmodified lines
567 opcode |= 7 << 12;567 opcode |= 7 << 12;
568 break;568 break;
569 default:569 default:
570 expect("known branch instruction");570 expect(S, "known branch instruction");
571 }571 }
572 asm_emit_opcode(opcode | ENCODE_RS1(ops[0].reg) | ENCODE_RS2(ops[1].reg) | (((offset >> 1) & 0xF) << 8) | (((offset >> 5) & 0x1f) << 25) | (((offset >> 11) & 1) << 7) | (((offset >> 12) & 1) << 31));572 asm_emit_opcode(S, opcode | ENCODE_RS1(ops[0].reg) | ENCODE_RS2(ops[1].reg) | (((offset >> 1) & 0xF) << 8) | (((offset >> 5) & 0x1f) << 25) | (((offset >> 11) & 1) << 7) | (((offset >> 12) & 1) << 31));
573}573}
574 574
575ST_FUNC void asm_opcode(TCCState *s1, int token)575ST_FUNC void asm_opcode(TCCState *S, int token)
576{576{
577 switch (token) {577 switch (token) {
578 case TOK_ASM_fence:578 case TOK_ASM_fence:
@@ -585,7 +585,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 6 unmodified lines
585 case TOK_ASM_mrth:585 case TOK_ASM_mrth:
586 case TOK_ASM_hrts:586 case TOK_ASM_hrts:
587 case TOK_ASM_wfi:587 case TOK_ASM_wfi:
588 asm_nullary_opcode(s1, token);588 asm_nullary_opcode(S, token);
589 return;589 return;
590 590
591 case TOK_ASM_rdcycle:591 case TOK_ASM_rdcycle:
@@ -594,12 +594,12 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 2 unmodified lines
594 case TOK_ASM_rdtimeh:594 case TOK_ASM_rdtimeh:
595 case TOK_ASM_rdinstret:595 case TOK_ASM_rdinstret:
596 case TOK_ASM_rdinstreth:596 case TOK_ASM_rdinstreth:
597 asm_unary_opcode(s1, token);597 asm_unary_opcode(S, token);
598 return;598 return;
599 599
600 case TOK_ASM_lui:600 case TOK_ASM_lui:
601 case TOK_ASM_auipc:601 case TOK_ASM_auipc:
602 asm_binary_opcode(s1, token);602 asm_binary_opcode(S, token);
603 return;603 return;
604 604
605 case TOK_ASM_sll:605 case TOK_ASM_sll:
@@ -620,7 +620,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 14 unmodified lines
620 case TOK_ASM_srad:620 case TOK_ASM_srad:
621 case TOK_ASM_sraiw:621 case TOK_ASM_sraiw:
622 case TOK_ASM_sraid:622 case TOK_ASM_sraid:
623 asm_shift_opcode(s1, token);623 asm_shift_opcode(S, token);
624 return;624 return;
625 625
626 case TOK_ASM_add:626 case TOK_ASM_add:
@@ -642,7 +642,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 15 unmodified lines
642 case TOK_ASM_slti:642 case TOK_ASM_slti:
643 case TOK_ASM_sltu:643 case TOK_ASM_sltu:
644 case TOK_ASM_sltiu:644 case TOK_ASM_sltiu:
645 asm_data_processing_opcode(s1, token);645 asm_data_processing_opcode(S, token);
646 646
647 case TOK_ASM_lb:647 case TOK_ASM_lb:
648 case TOK_ASM_lh:648 case TOK_ASM_lh:
@@ -655,7 +655,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 6 unmodified lines
655 case TOK_ASM_sh:655 case TOK_ASM_sh:
656 case TOK_ASM_sw:656 case TOK_ASM_sw:
657 case TOK_ASM_sd:657 case TOK_ASM_sd:
658 asm_data_transfer_opcode(s1, token);658 asm_data_transfer_opcode(S, token);
659 return;659 return;
660 660
661 case TOK_ASM_beq:661 case TOK_ASM_beq:
@@ -664,35 +664,35 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 2 unmodified lines
664 case TOK_ASM_bge:664 case TOK_ASM_bge:
665 case TOK_ASM_bltu:665 case TOK_ASM_bltu:
666 case TOK_ASM_bgeu:666 case TOK_ASM_bgeu:
667 asm_branch_opcode(s1, token);667 asm_branch_opcode(S, token);
668 return;668 return;
669 669
670 default:670 default:
671 expect("known instruction");671 expect(S, "known instruction");
672 }672 }
673}673}
674 674
675ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier)675ST_FUNC void subst_asm_operand(TCCState *S, CString *add_str, SValue *sv, int modifier)
676{676{
677 tcc_error("RISCV64 asm not implemented.");677 tcc_error(S, "RISCV64 asm not implemented.");
678}678}
679 679
680/* generate prolog and epilog code for asm statement */680/* generate prolog and epilog code for asm statement */
681ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,681ST_FUNC void asm_gen_code(TCCState *S, ASMOperand *operands, int nb_operands,
682 int nb_outputs, int is_output,682 int nb_outputs, int is_output,
683 uint8_t *clobber_regs,683 uint8_t *clobber_regs,
684 int out_reg)684 int out_reg)
685{685{
686}686}
687 687
688ST_FUNC void asm_compute_constraints(ASMOperand *operands,688ST_FUNC void asm_compute_constraints(TCCState *S, ASMOperand *operands,
689 int nb_operands, int nb_outputs,689 int nb_operands, int nb_outputs,
690 const uint8_t *clobber_regs,690 const uint8_t *clobber_regs,
691 int *pout_reg)691 int *pout_reg)
692{692{
693}693}
694 694
695ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str)695ST_FUNC void asm_clobber(TCCState *S, uint8_t *clobber_regs, const char *str)
696{696{
697 int reg;697 int reg;
698 TokenSym *ts;698 TokenSym *ts;
@@ -701,15 +701,15 @@ ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str) · 2 unmodified lines
701 !strcmp(str, "cc") ||701 !strcmp(str, "cc") ||
702 !strcmp(str, "flags"))702 !strcmp(str, "flags"))
703 return;703 return;
704 ts = tok_alloc(str, strlen(str));704 ts = tok_alloc(S, str, strlen(str));
705 reg = asm_parse_regvar(ts->tok);705 reg = asm_parse_regvar(S, ts->tok);
706 if (reg == -1) {706 if (reg == -1) {
707 tcc_error("invalid clobber register '%s'", str);707 tcc_error(S, "invalid clobber register '%s'", str);
708 }708 }
709 clobber_regs[reg] = 1;709 clobber_regs[reg] = 1;
710}710}
711 711
712ST_FUNC int asm_parse_regvar (int t)712ST_FUNC int asm_parse_regvar (TCCState* S, int t)
713{713{
714 if (t >= TOK_ASM_x0 && t <= TOK_ASM_pc) { /* register name */714 if (t >= TOK_ASM_x0 && t <= TOK_ASM_pc) { /* register name */
715 switch (t) {715 switch (t) {
riscv64-gen.c+451−457
@@ -74,12 +74,6 @@ ST_DATA const int reg_classes[NB_REGS] = { · 73 unmodified lines
74 1 << TREG_SP74 1 << TREG_SP
75};75};
76 76
77#if defined(CONFIG_TCC_BCHECK)
78static addr_t func_bound_offset;
79static unsigned long func_bound_ind;
80ST_DATA int func_bound_add_epilog;
81#endif
82
83static int ireg(int r)77static int ireg(int r)
84{78{
85 if (r == TREG_RA)79 if (r == TREG_RA)
@@ -106,46 +100,46 @@ static int is_freg(int r) · 20 unmodified lines
106 return r >= 8 && r < 16;100 return r >= 8 && r < 16;
107}101}
108 102
109ST_FUNC void o(unsigned int c)103ST_FUNC void o(TCCState* S, unsigned int c)
110{104{
111 int ind1 = ind + 4;105 int ind1 = S->tccgen_ind + 4;
112 if (nocode_wanted)106 if (S->tccgen_nocode_wanted)
113 return;107 return;
114 if (ind1 > cur_text_section->data_allocated)108 if (ind1 > cur_text_section->data_allocated)
115 section_realloc(cur_text_section, ind1);109 section_realloc(S, cur_text_section, ind1);
116 write32le(cur_text_section->data + ind, c);110 write32le(cur_text_section->data + S->tccgen_ind, c);
117 ind = ind1;111 S->tccgen_ind = ind1;
118}112}
119 113
120static void EIu(uint32_t opcode, uint32_t func3,114static void EIu(TCCState* S, uint32_t opcode, uint32_t func3,
121 uint32_t rd, uint32_t rs1, uint32_t imm)115 uint32_t rd, uint32_t rs1, uint32_t imm)
122{116{
123 o(opcode | (func3 << 12) | (rd << 7) | (rs1 << 15) | (imm << 20));117 o(S, opcode | (func3 << 12) | (rd << 7) | (rs1 << 15) | (imm << 20));
124}118}
125 119
126static void ER(uint32_t opcode, uint32_t func3,120static void ER(TCCState* S, uint32_t opcode, uint32_t func3,
127 uint32_t rd, uint32_t rs1, uint32_t rs2, uint32_t func7)121 uint32_t rd, uint32_t rs1, uint32_t rs2, uint32_t func7)
128{122{
129 o(opcode | func3 << 12 | rd << 7 | rs1 << 15 | rs2 << 20 | func7 << 25);123 o(S, opcode | func3 << 12 | rd << 7 | rs1 << 15 | rs2 << 20 | func7 << 25);
130}124}
131 125
132static void EI(uint32_t opcode, uint32_t func3,126static void EI(TCCState* S, uint32_t opcode, uint32_t func3,
133 uint32_t rd, uint32_t rs1, uint32_t imm)127 uint32_t rd, uint32_t rs1, uint32_t imm)
134{128{
135 assert(! ((imm + (1 << 11)) >> 12));129 assert(! ((imm + (1 << 11)) >> 12));
136 EIu(opcode, func3, rd, rs1, imm);130 EIu(S, opcode, func3, rd, rs1, imm);
137}131}
138 132
139static void ES(uint32_t opcode, uint32_t func3,133static void ES(TCCState* S, uint32_t opcode, uint32_t func3,
140 uint32_t rs1, uint32_t rs2, uint32_t imm)134 uint32_t rs1, uint32_t rs2, uint32_t imm)
141{135{
142 assert(! ((imm + (1 << 11)) >> 12));136 assert(! ((imm + (1 << 11)) >> 12));
143 o(opcode | (func3 << 12) | ((imm & 0x1f) << 7) | (rs1 << 15)137 o(S, opcode | (func3 << 12) | ((imm & 0x1f) << 7) | (rs1 << 15)
144 | (rs2 << 20) | ((imm >> 5) << 25));138 | (rs2 << 20) | ((imm >> 5) << 25));
145}139}
146 140
147// Patch all branches in list pointed to by t to branch to a:141// Patch all branches in list pointed to by t to branch to a:
148ST_FUNC void gsym_addr(int t_, int a_)142ST_FUNC void gsym_addr(TCCState* S, int t_, int a_)
149{143{
150 uint32_t t = t_;144 uint32_t t = t_;
151 uint32_t a = a_;145 uint32_t a = a_;
@@ -154,7 +148,7 @@ ST_FUNC void gsym_addr(int t_, int a_) · 2 unmodified lines
154 uint32_t next = read32le(ptr);148 uint32_t next = read32le(ptr);
155 uint32_t r = a - t, imm;149 uint32_t r = a - t, imm;
156 if ((r + (1 << 21)) & ~((1U << 22) - 2))150 if ((r + (1 << 21)) & ~((1U << 22) - 2))
157 tcc_error("out-of-range branch chain");151 tcc_error(S, "out-of-range branch chain");
158 imm = (((r >> 12) & 0xff) << 12)152 imm = (((r >> 12) & 0xff) << 12)
159 | (((r >> 11) & 1) << 20)153 | (((r >> 11) & 1) << 20)
160 | (((r >> 1) & 0x3ff) << 21)154 | (((r >> 1) & 0x3ff) << 21)
@@ -164,7 +158,7 @@ ST_FUNC void gsym_addr(int t_, int a_) · 3 unmodified lines
164 }158 }
165}159}
166 160
167static int load_symofs(int r, SValue *sv, int forstore)161static int load_symofs(TCCState* S, int r, SValue *sv, int forstore)
168{162{
169 int rr, doload = 0;163 int rr, doload = 0;
170 int fc = sv->c.i, v = sv->r & VT_VALMASK;164 int fc = sv->c.i, v = sv->r & VT_VALMASK;
@@ -172,56 +166,56 @@ static int load_symofs(int r, SValue *sv, int forstore) · 1 unmodified line
172 Sym label = {0};166 Sym label = {0};
173 assert(v == VT_CONST);167 assert(v == VT_CONST);
174 if (sv->sym->type.t & VT_STATIC) { // XXX do this per linker relax168 if (sv->sym->type.t & VT_STATIC) { // XXX do this per linker relax
175 greloca(cur_text_section, sv->sym, ind,169 greloca(S, cur_text_section, sv->sym, S->tccgen_ind,
176 R_RISCV_PCREL_HI20, sv->c.i);170 R_RISCV_PCREL_HI20, sv->c.i);
177 sv->c.i = 0;171 sv->c.i = 0;
178 } else {172 } else {
179 if (((unsigned)fc + (1 << 11)) >> 12)173 if (((unsigned)fc + (1 << 11)) >> 12)
180 tcc_error("unimp: large addend for global address (0x%lx)", (long)sv->c.i);174 tcc_error(S, "unimp: large addend for global address (0x%lx)", (long)sv->c.i);
181 greloca(cur_text_section, sv->sym, ind,175 greloca(S, cur_text_section, sv->sym, S->tccgen_ind,
182 R_RISCV_GOT_HI20, 0);176 R_RISCV_GOT_HI20, 0);
183 doload = 1;177 doload = 1;
184 }178 }
185 label.type.t = VT_VOID | VT_STATIC;179 label.type.t = VT_VOID | VT_STATIC;
186 put_extern_sym(&label, cur_text_section, ind, 0);180 put_extern_sym(S, &label, cur_text_section, S->tccgen_ind, 0);
187 rr = is_ireg(r) ? ireg(r) : 5;181 rr = is_ireg(r) ? ireg(r) : 5;
188 o(0x17 | (rr << 7)); // auipc RR, 0 %pcrel_hi(sym)+addend182 o(S, 0x17 | (rr << 7)); // auipc RR, 0 %pcrel_hi(sym)+addend
189 greloca(cur_text_section, &label, ind,183 greloca(S, cur_text_section, &label, S->tccgen_ind,
190 doload || !forstore184 doload || !forstore
191 ? R_RISCV_PCREL_LO12_I : R_RISCV_PCREL_LO12_S, 0);185 ? R_RISCV_PCREL_LO12_I : R_RISCV_PCREL_LO12_S, 0);
192 if (doload) {186 if (doload) {
193 EI(0x03, 3, rr, rr, 0); // ld RR, 0(RR)187 EI(S, 0x03, 3, rr, rr, 0); // ld RR, 0(RR)
194 }188 }
195 } else if (v == VT_LOCAL || v == VT_LLOCAL) {189 } else if (v == VT_LOCAL || v == VT_LLOCAL) {
196 rr = 8; // s0190 rr = 8; // s0
197 if (fc != sv->c.i)191 if (fc != sv->c.i)
198 tcc_error("unimp: store(giant local off) (0x%lx)", (long)sv->c.i);192 tcc_error(S, "unimp: store(giant local off) (0x%lx)", (long)sv->c.i);
199 if (((unsigned)fc + (1 << 11)) >> 12) {193 if (((unsigned)fc + (1 << 11)) >> 12) {
200 rr = is_ireg(r) ? ireg(r) : 5; // t0194 rr = is_ireg(r) ? ireg(r) : 5; // t0
201 o(0x37 | (rr << 7) | ((0x800 + fc) & 0xfffff000)); //lui RR, upper(fc)195 o(S, 0x37 | (rr << 7) | ((0x800 + fc) & 0xfffff000)); //lui RR, upper(fc)
202 ER(0x33, 0, rr, rr, 8, 0); // add RR, RR, s0196 ER(S, 0x33, 0, rr, rr, 8, 0); // add RR, RR, s0
203 sv->c.i = fc << 20 >> 20;197 sv->c.i = fc << 20 >> 20;
204 }198 }
205 } else199 } else
206 tcc_error("uhh");200 tcc_error(S, "uhh");
207 return rr;201 return rr;
208}202}
209 203
210static void load_large_constant(int rr, int fc, uint32_t pi)204static void load_large_constant(TCCState* S, int rr, int fc, uint32_t pi)
211{205{
212 if (fc < 0)206 if (fc < 0)
213 pi++;207 pi++;
214 o(0x37 | (rr << 7) | (((pi + 0x800) & 0xfffff000))); // lui RR, up(up(fc))208 o(S, 0x37 | (rr << 7) | (((pi + 0x800) & 0xfffff000))); // lui RR, up(up(fc))
215 EI(0x13, 0, rr, rr, (int)pi << 20 >> 20); // addi RR, RR, lo(up(fc))209 EI(S, 0x13, 0, rr, rr, (int)pi << 20 >> 20); // addi RR, RR, lo(up(fc))
216 EI(0x13, 1, rr, rr, 12); // slli RR, RR, 12210 EI(S, 0x13, 1, rr, rr, 12); // slli RR, RR, 12
217 EI(0x13, 0, rr, rr, (fc + (1 << 19)) >> 20); // addi RR, RR, up(lo(fc))211 EI(S, 0x13, 0, rr, rr, (fc + (1 << 19)) >> 20); // addi RR, RR, up(lo(fc))
218 EI(0x13, 1, rr, rr, 12); // slli RR, RR, 12212 EI(S, 0x13, 1, rr, rr, 12); // slli RR, RR, 12
219 fc = fc << 12 >> 12;213 fc = fc << 12 >> 12;
220 EI(0x13, 0, rr, rr, fc >> 8); // addi RR, RR, lo1(lo(fc))214 EI(S, 0x13, 0, rr, rr, fc >> 8); // addi RR, RR, lo1(lo(fc))
221 EI(0x13, 1, rr, rr, 8); // slli RR, RR, 8215 EI(S, 0x13, 1, rr, rr, 8); // slli RR, RR, 8
222}216}
223 217
224ST_FUNC void load(int r, SValue *sv)218ST_FUNC void load(TCCState* S, int r, SValue *sv)
225{219{
226 int fr = sv->r;220 int fr = sv->r;
227 int v = fr & VT_VALMASK;221 int v = fr & VT_VALMASK;
@@ -239,49 +233,49 @@ ST_FUNC void load(int r, SValue *sv) · 11 unmodified lines
239 if (size < 4 && !is_float(sv->type.t) && (sv->type.t & VT_UNSIGNED))233 if (size < 4 && !is_float(sv->type.t) && (sv->type.t & VT_UNSIGNED))
240 func3 |= 4;234 func3 |= 4;
241 if (v == VT_LOCAL || (fr & VT_SYM)) {235 if (v == VT_LOCAL || (fr & VT_SYM)) {
242 br = load_symofs(r, sv, 0);236 br = load_symofs(S, r, sv, 0);
243 fc = sv->c.i;237 fc = sv->c.i;
244 } else if (v < VT_CONST) {238 } else if (v < VT_CONST) {
245 br = ireg(v);239 br = ireg(v);
246 /*if (((unsigned)fc + (1 << 11)) >> 12)240 /*if (((unsigned)fc + (1 << 11)) >> 12)
247 tcc_error("unimp: load(large addend) (0x%x)", fc);*/241 tcc_error(S, "unimp: load(large addend) (0x%x)", fc);*/
248 fc = 0; // XXX store ofs in LVAL(reg)242 fc = 0; // XXX store ofs in LVAL(reg)
249 } else if (v == VT_LLOCAL) {243 } else if (v == VT_LLOCAL) {
250 br = load_symofs(r, sv, 0);244 br = load_symofs(S, r, sv, 0);
251 fc = sv->c.i;245 fc = sv->c.i;
252 EI(0x03, 3, rr, br, fc); // ld RR, fc(BR)246 EI(S, 0x03, 3, rr, br, fc); // ld RR, fc(BR)
253 br = rr;247 br = rr;
254 fc = 0;248 fc = 0;
255 } else if (v == VT_CONST) {249 } else if (v == VT_CONST) {
256 int64_t si = sv->c.i;250 int64_t si = sv->c.i;
257 si >>= 32;251 si >>= 32;
258 if (si != 0) {252 if (si != 0) {
259 load_large_constant(rr, fc, si);253 load_large_constant(S, rr, fc, si);
260 fc &= 0xff;254 fc &= 0xff;
261 } else {255 } else {
262 o(0x37 | (rr << 7) | ((0x800 + fc) & 0xfffff000)); //lui RR, upper(fc)256 o(S, 0x37 | (rr << 7) | ((0x800 + fc) & 0xfffff000)); //lui RR, upper(fc)
263 fc = fc << 20 >> 20;257 fc = fc << 20 >> 20;
264 }258 }
265 br = rr;259 br = rr;
266 } else {260 } else {
267 tcc_error("unimp: load(non-local lval)");261 tcc_error(S, "unimp: load(non-local lval)");
268 }262 }
269 EI(opcode, func3, rr, br, fc); // l[bhwd][u] / fl[wd] RR, fc(BR)263 EI(S, opcode, func3, rr, br, fc); // l[bhwd][u] / fl[wd] RR, fc(BR)
270 } else if (v == VT_CONST) {264 } else if (v == VT_CONST) {
271 int rb = 0, do32bit = 8, zext = 0;265 int rb = 0, do32bit = 8, zext = 0;
272 assert((!is_float(sv->type.t) && is_ireg(r)) || bt == VT_LDOUBLE);266 assert((!is_float(sv->type.t) && is_ireg(r)) || bt == VT_LDOUBLE);
273 if (fr & VT_SYM) {267 if (fr & VT_SYM) {
274 rb = load_symofs(r, sv, 0);268 rb = load_symofs(S, r, sv, 0);
275 fc = sv->c.i;269 fc = sv->c.i;
276 do32bit = 0;270 do32bit = 0;
277 }271 }
278 if (is_float(sv->type.t) && bt != VT_LDOUBLE)272 if (is_float(sv->type.t) && bt != VT_LDOUBLE)
279 tcc_error("unimp: load(float)");273 tcc_error(S, "unimp: load(float)");
280 if (fc != sv->c.i) {274 if (fc != sv->c.i) {
281 int64_t si = sv->c.i;275 int64_t si = sv->c.i;
282 si >>= 32;276 si >>= 32;
283 if (si != 0) {277 if (si != 0) {
284 load_large_constant(rr, fc, si);278 load_large_constant(S, rr, fc, si);
285 fc &= 0xff;279 fc &= 0xff;
286 rb = rr;280 rb = rr;
287 do32bit = 0;281 do32bit = 0;
@@ -292,37 +286,37 @@ ST_FUNC void load(int r, SValue *sv) · 4 unmodified lines
292 }286 }
293 }287 }
294 if (((unsigned)fc + (1 << 11)) >> 12)288 if (((unsigned)fc + (1 << 11)) >> 12)
295 o(0x37 | (rr << 7) | ((0x800 + fc) & 0xfffff000)), rb = rr; //lui RR, upper(fc)289 o(S, 0x37 | (rr << 7) | ((0x800 + fc) & 0xfffff000)), rb = rr; //lui RR, upper(fc)
296 if (fc || (rr != rb) || do32bit || (fr & VT_SYM))290 if (fc || (rr != rb) || do32bit || (fr & VT_SYM))
297 EI(0x13 | do32bit, 0, rr, rb, fc << 20 >> 20); // addi[w] R, x0|R, FC291 EI(S, 0x13 | do32bit, 0, rr, rb, fc << 20 >> 20); // addi[w] R, x0|R, FC
298 if (zext) {292 if (zext) {
299 EI(0x13, 1, rr, rr, 32); // slli RR, RR, 32293 EI(S, 0x13, 1, rr, rr, 32); // slli RR, RR, 32
300 EI(0x13, 5, rr, rr, 32); // srli RR, RR, 32294 EI(S, 0x13, 5, rr, rr, 32); // srli RR, RR, 32
301 }295 }
302 } else if (v == VT_LOCAL) {296 } else if (v == VT_LOCAL) {
303 int br = load_symofs(r, sv, 0);297 int br = load_symofs(S, r, sv, 0);
304 assert(is_ireg(r));298 assert(is_ireg(r));
305 fc = sv->c.i;299 fc = sv->c.i;
306 EI(0x13, 0, rr, br, fc); // addi R, s0, FC300 EI(S, 0x13, 0, rr, br, fc); // addi R, s0, FC
307 } else if (v < VT_CONST) { /* reg-reg */301 } else if (v < VT_CONST) { /* reg-reg */
308 //assert(!fc); XXX support offseted regs302 //assert(!fc); XXX support offseted regs
309 if (is_freg(r) && is_freg(v))303 if (is_freg(r) && is_freg(v))
310 ER(0x53, 0, rr, freg(v), freg(v), bt == VT_DOUBLE ? 0x11 : 0x10); //fsgnj.[sd] RR, V, V == fmv.[sd] RR, V304 ER(S, 0x53, 0, rr, freg(v), freg(v), bt == VT_DOUBLE ? 0x11 : 0x10); //fsgnj.[sd] RR, V, V == fmv.[sd] RR, V
311 else if (is_ireg(r) && is_ireg(v))305 else if (is_ireg(r) && is_ireg(v))
312 EI(0x13, 0, rr, ireg(v), 0); // addi RR, V, 0 == mv RR, V306 EI(S, 0x13, 0, rr, ireg(v), 0); // addi RR, V, 0 == mv RR, V
313 else {307 else {
314 int func7 = is_ireg(r) ? 0x70 : 0x78;308 int func7 = is_ireg(r) ? 0x70 : 0x78;
315 size = type_size(&sv->type, &align);309 size = type_size(&sv->type, &align);
316 if (size == 8)310 if (size == 8)
317 func7 |= 1;311 func7 |= 1;
318 assert(size == 4 || size == 8);312 assert(size == 4 || size == 8);
319 o(0x53 | (rr << 7) | ((is_freg(v) ? freg(v) : ireg(v)) << 15)313 o(S, 0x53 | (rr << 7) | ((is_freg(v) ? freg(v) : ireg(v)) << 15)
320 | (func7 << 25)); // fmv.{w.x, x.w, d.x, x.d} RR, VR314 | (func7 << 25)); // fmv.{w.x, x.w, d.x, x.d} RR, VR
321 }315 }
322 } else if (v == VT_CMP) {316 } else if (v == VT_CMP) {
323 int op = vtop->cmp_op;317 int op = S->tccgen_vtop->cmp_op;
324 int a = vtop->cmp_r & 0xff;318 int a = S->tccgen_vtop->cmp_r & 0xff;
325 int b = (vtop->cmp_r >> 8) & 0xff;319 int b = (S->tccgen_vtop->cmp_r >> 8) & 0xff;
326 int inv = 0;320 int inv = 0;
327 switch (op) {321 switch (op) {
328 case TOK_ULT:322 case TOK_ULT:
@@ -341,32 +335,32 @@ ST_FUNC void load(int r, SValue *sv) · 12 unmodified lines
341 int t = a; a = b; b = t;335 int t = a; a = b; b = t;
342 inv ^= 1;336 inv ^= 1;
343 }337 }
344 ER(0x33, (op > TOK_UGT) ? 2 : 3, rr, a, b, 0); // slt[u] d, a, b338 ER(S, 0x33, (op > TOK_UGT) ? 2 : 3, rr, a, b, 0); // slt[u] d, a, b
345 if (inv)339 if (inv)
346 EI(0x13, 4, rr, rr, 1); // xori d, d, 1340 EI(S, 0x13, 4, rr, rr, 1); // xori d, d, 1
347 break;341 break;
348 case TOK_NE:342 case TOK_NE:
349 case TOK_EQ:343 case TOK_EQ:
350 if (rr != a || b)344 if (rr != a || b)
351 ER(0x33, 0, rr, a, b, 0x20); // sub d, a, b345 ER(S, 0x33, 0, rr, a, b, 0x20); // sub d, a, b
352 if (op == TOK_NE)346 if (op == TOK_NE)
353 ER(0x33, 3, rr, 0, rr, 0); // sltu d, x0, d == snez d,d347 ER(S, 0x33, 3, rr, 0, rr, 0); // sltu d, x0, d == snez d,d
354 else348 else
355 EI(0x13, 3, rr, rr, 1); // sltiu d, d, 1 == seqz d,d349 EI(S, 0x13, 3, rr, rr, 1); // sltiu d, d, 1 == seqz d,d
356 break;350 break;
357 }351 }
358 } else if ((v & ~1) == VT_JMP) {352 } else if ((v & ~1) == VT_JMP) {
359 int t = v & 1;353 int t = v & 1;
360 assert(is_ireg(r));354 assert(is_ireg(r));
361 EI(0x13, 0, rr, 0, t); // addi RR, x0, t355 EI(S, 0x13, 0, rr, 0, t); // addi RR, x0, t
362 gjmp_addr(ind + 8);356 gjmp_addr(S, S->tccgen_ind + 8);
363 gsym(fc);357 gsym(S, fc);
364 EI(0x13, 0, rr, 0, t ^ 1); // addi RR, x0, !t358 EI(S, 0x13, 0, rr, 0, t ^ 1); // addi RR, x0, !t
365 } else359 } else
366 tcc_error("unimp: load(non-const)");360 tcc_error(S, "unimp: load(non-const)");
367}361}
368 362
369ST_FUNC void store(int r, SValue *sv)363ST_FUNC void store(TCCState* S, int r, SValue *sv)
370{364{
371 int fr = sv->r & VT_VALMASK;365 int fr = sv->r & VT_VALMASK;
372 int rr = is_ireg(r) ? ireg(r) : freg(r), ptrreg;366 int rr = is_ireg(r) ? ireg(r) : freg(r), ptrreg;
@@ -379,125 +373,125 @@ ST_FUNC void store(int r, SValue *sv) · 6 unmodified lines
379 if (bt == VT_LDOUBLE)373 if (bt == VT_LDOUBLE)
380 size = align = 8;374 size = align = 8;
381 if (bt == VT_STRUCT)375 if (bt == VT_STRUCT)
382 tcc_error("unimp: store(struct)");376 tcc_error(S, "unimp: store(struct)");
383 if (size > 8)377 if (size > 8)
384 tcc_error("unimp: large sized store");378 tcc_error(S, "unimp: large sized store");
385 assert(sv->r & VT_LVAL);379 assert(sv->r & VT_LVAL);
386 if (fr == VT_LOCAL || (sv->r & VT_SYM)) {380 if (fr == VT_LOCAL || (sv->r & VT_SYM)) {
387 ptrreg = load_symofs(-1, sv, 1);381 ptrreg = load_symofs(S, -1, sv, 1);
388 fc = sv->c.i;382 fc = sv->c.i;
389 } else if (fr < VT_CONST) {383 } else if (fr < VT_CONST) {
390 ptrreg = ireg(fr);384 ptrreg = ireg(fr);
391 /*if (((unsigned)fc + (1 << 11)) >> 12)385 /*if (((unsigned)fc + (1 << 11)) >> 12)
392 tcc_error("unimp: store(large addend) (0x%x)", fc);*/386 tcc_error(S, "unimp: store(large addend) (0x%x)", fc);*/
393 fc = 0; // XXX support offsets regs387 fc = 0; // XXX support offsets regs
394 } else if (fr == VT_CONST) {388 } else if (fr == VT_CONST) {
395 int64_t si = sv->c.i;389 int64_t si = sv->c.i;
396 ptrreg = 8; // s0390 ptrreg = 8; // s0
397 si >>= 32;391 si >>= 32;
398 if (si != 0) {392 if (si != 0) {
399 load_large_constant(ptrreg, fc, si);393 load_large_constant(S, ptrreg, fc, si);
400 fc &= 0xff;394 fc &= 0xff;
401 } else {395 } else {
402 o(0x37 | (ptrreg << 7) | ((0x800 + fc) & 0xfffff000)); //lui RR, upper(fc)396 o(S, 0x37 | (ptrreg << 7) | ((0x800 + fc) & 0xfffff000)); //lui RR, upper(fc)
403 fc = fc << 20 >> 20;397 fc = fc << 20 >> 20;
404 }398 }
405 } else399 } else
406 tcc_error("implement me: %s(!local)", __FUNCTION__);400 tcc_error(S, "implement me: %s(!local)", __FUNCTION__);
407 ES(is_freg(r) ? 0x27 : 0x23, // fs... | s...401 ES(S, is_freg(r) ? 0x27 : 0x23, // fs... | s...
408 size == 1 ? 0 : size == 2 ? 1 : size == 4 ? 2 : 3, // ... [wd] | [bhwd]402 size == 1 ? 0 : size == 2 ? 1 : size == 4 ? 2 : 3, // ... [wd] | [bhwd]
409 ptrreg, rr, fc); // RR, fc(base)403 ptrreg, rr, fc); // RR, fc(base)
410}404}
411 405
412static void gcall_or_jmp(int docall)406static void gcall_or_jmp(TCCState* S, int docall)
413{407{
414 int tr = docall ? 1 : 5; // ra or t0408 int tr = docall ? 1 : 5; // ra or t0
415 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&409 if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
416 ((vtop->r & VT_SYM) && vtop->c.i == (int)vtop->c.i)) {410 ((S->tccgen_vtop->r & VT_SYM) && S->tccgen_vtop->c.i == (int)S->tccgen_vtop->c.i)) {
417 /* constant symbolic case -> simple relocation */411 /* constant symbolic case -> simple relocation */
418 greloca(cur_text_section, vtop->sym, ind,412 greloca(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind,
419 R_RISCV_CALL_PLT, (int)vtop->c.i);413 R_RISCV_CALL_PLT, (int)S->tccgen_vtop->c.i);
420 o(0x17 | (tr << 7)); // auipc TR, 0 %call(func)414 o(S, 0x17 | (tr << 7)); // auipc TR, 0 %call(func)
421 EI(0x67, 0, tr, tr, 0);// jalr TR, r(TR)415 EI(S, 0x67, 0, tr, tr, 0);// jalr TR, r(TR)
422 } else if (vtop->r < VT_CONST) {416 } else if (S->tccgen_vtop->r < VT_CONST) {
423 int r = ireg(vtop->r);417 int r = ireg(S->tccgen_vtop->r);
424 EI(0x67, 0, tr, r, 0); // jalr TR, 0(R)418 EI(S, 0x67, 0, tr, r, 0); // jalr TR, 0(R)
425 } else {419 } else {
426 int r = TREG_RA;420 int r = TREG_RA;
427 load(r, vtop);421 load(S, r, S->tccgen_vtop);
428 r = ireg(r);422 r = ireg(r);
429 EI(0x67, 0, tr, r, 0); // jalr TR, 0(R)423 EI(S, 0x67, 0, tr, r, 0); // jalr TR, 0(R)
430 }424 }
431}425}
432 426
433#if defined(CONFIG_TCC_BCHECK)427#if defined(CONFIG_TCC_BCHECK)
434 428
435static void gen_bounds_call(int v)429static void gen_bounds_call(TCCState* S, int v)
436{430{
437 Sym *sym = external_helper_sym(v);431 Sym *sym = external_helper_sym(S, v);
438 432
439 greloca(cur_text_section, sym, ind, R_RISCV_CALL_PLT, 0);433 greloca(S, cur_text_section, sym, S->tccgen_ind, R_RISCV_CALL_PLT, 0);
440 o(0x17 | (1 << 7)); // auipc TR, 0 %call(func)434 o(S, 0x17 | (1 << 7)); // auipc TR, 0 %call(func)
441 EI(0x67, 0, 1, 1, 0); // jalr TR, r(TR)435 EI(S, 0x67, 0, 1, 1, 0); // jalr TR, r(TR)
442}436}
443 437
444static void gen_bounds_prolog(void)438static void gen_bounds_prolog(TCCState* S)
445{439{
446 /* leave some room for bound checking code */440 /* leave some room for bound checking code */
447 func_bound_offset = lbounds_section->data_offset;441 S->func_bound_offset = lbounds_section->data_offset;
448 func_bound_ind = ind;442 S->func_bound_ind = S->tccgen_ind;
449 func_bound_add_epilog = 0;443 S->func_bound_add_epilog = 0;
450 o(0x00000013); /* ld a0,#lbound section pointer */444 o(S, 0x00000013); /* ld a0,#lbound section pointer */
451 o(0x00000013);445 o(S, 0x00000013);
452 o(0x00000013); /* nop -> call __bound_local_new */446 o(S, 0x00000013); /* nop -> call __bound_local_new */
453 o(0x00000013);447 o(S, 0x00000013);
454}448}
455 449
456static void gen_bounds_epilog(void)450static void gen_bounds_epilog(TCCState* S)
457{451{
458 addr_t saved_ind;452 addr_t saved_ind;
459 addr_t *bounds_ptr;453 addr_t *bounds_ptr;
460 Sym *sym_data;454 Sym *sym_data;
461 Sym label = {0};455 Sym label = {0};
462 456
463 int offset_modified = func_bound_offset != lbounds_section->data_offset;457 int offset_modified = S->func_bound_offset != lbounds_section->data_offset;
464 458
465 if (!offset_modified && !func_bound_add_epilog)459 if (!offset_modified && !S->func_bound_add_epilog)
466 return;460 return;
467 461
468 /* add end of table info */462 /* add end of table info */
469 bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));463 bounds_ptr = section_ptr_add(S, lbounds_section, sizeof(addr_t));
470 *bounds_ptr = 0;464 *bounds_ptr = 0;
471 465
472 sym_data = get_sym_ref(&char_pointer_type, lbounds_section,466 sym_data = get_sym_ref(S, &S->tccgen_char_pointer_type, lbounds_section,
473 func_bound_offset, lbounds_section->data_offset);467 S->func_bound_offset, lbounds_section->data_offset);
474 468
475 label.type.t = VT_VOID | VT_STATIC;469 label.type.t = VT_VOID | VT_STATIC;
476 /* generate bound local allocation */470 /* generate bound local allocation */
477 if (offset_modified) {471 if (offset_modified) {
478 saved_ind = ind;472 saved_ind = S->tccgen_ind;
479 ind = func_bound_ind;473 S->tccgen_ind = S->func_bound_ind;
480 put_extern_sym(&label, cur_text_section, ind, 0);474 put_extern_sym(S, &label, cur_text_section, S->tccgen_ind, 0);
481 greloca(cur_text_section, sym_data, ind, R_RISCV_GOT_HI20, 0);475 greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_RISCV_GOT_HI20, 0);
482 o(0x17 | (10 << 7)); // auipc a0, 0 %pcrel_hi(sym)+addend476 o(S, 0x17 | (10 << 7)); // auipc a0, 0 %pcrel_hi(sym)+addend
483 greloca(cur_text_section, &label, ind, R_RISCV_PCREL_LO12_I, 0);477 greloca(S, cur_text_section, &label, S->tccgen_ind, R_RISCV_PCREL_LO12_I, 0);
484 EI(0x03, 3, 10, 10, 0); // ld a0, 0(a0)478 EI(S, 0x03, 3, 10, 10, 0); // ld a0, 0(a0)
485 gen_bounds_call(TOK___bound_local_new);479 gen_bounds_call(S, TOK___bound_local_new);
486 ind = saved_ind;480 S->tccgen_ind = saved_ind;
487 label.c = 0; /* force new local ELF symbol */481 label.c = 0; /* force new local ELF symbol */
488 }482 }
489 483
490 /* generate bound check local freeing */484 /* generate bound check local freeing */
491 o(0xe02a1101); /* addi sp,sp,-32 sd a0,0(sp) */485 o(S, 0xe02a1101); /* addi sp,sp,-32 sd a0,0(sp) */
492 o(0xa82ae42e); /* sd a1,8(sp) fsd fa0,16(sp) */486 o(S, 0xa82ae42e); /* sd a1,8(sp) fsd fa0,16(sp) */
493 put_extern_sym(&label, cur_text_section, ind, 0);487 put_extern_sym(S, &label, cur_text_section, S->tccgen_ind, 0);
494 greloca(cur_text_section, sym_data, ind, R_RISCV_GOT_HI20, 0);488 greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_RISCV_GOT_HI20, 0);
495 o(0x17 | (10 << 7)); // auipc a0, 0 %pcrel_hi(sym)+addend489 o(S, 0x17 | (10 << 7)); // auipc a0, 0 %pcrel_hi(sym)+addend
496 greloca(cur_text_section, &label, ind, R_RISCV_PCREL_LO12_I, 0);490 greloca(S, cur_text_section, &label, S->tccgen_ind, R_RISCV_PCREL_LO12_I, 0);
497 EI(0x03, 3, 10, 10, 0); // ld a0, 0(a0)491 EI(S, 0x03, 3, 10, 10, 0); // ld a0, 0(a0)
498 gen_bounds_call(TOK___bound_local_delete);492 gen_bounds_call(S, TOK___bound_local_delete);
499 o(0x65a26502); /* ld a0,0(sp) ld a1,8(sp) */493 o(S, 0x65a26502); /* ld a0,0(sp) ld a1,8(sp) */
500 o(0x61052542); /* fld fa0,16(sp) addi sp,sp,32 */494 o(S, 0x61052542); /* fld fa0,16(sp) addi sp,sp,32 */
501}495}
502#endif496#endif
503 497
@@ -546,27 +540,27 @@ static void reg_pass(CType *type, int *prc, int *fieldofs, int named) · 42 unmodified lines
546 }540 }
547}541}
548 542
549ST_FUNC void gfunc_call(int nb_args)543ST_FUNC void gfunc_call(TCCState* S, int nb_args)
550{544{
551 int i, align, size, areg[2];545 int i, align, size, areg[2];
552 int *info = tcc_malloc((nb_args + 1) * sizeof (int));546 int *info = tcc_malloc(S, (nb_args + 1) * sizeof (int));
553 int stack_adj = 0, tempspace = 0, stack_add, ofs, splitofs = 0;547 int stack_adj = 0, tempspace = 0, stack_add, ofs, splitofs = 0;
554 SValue *sv;548 SValue *sv;
555 Sym *sa;549 Sym *sa;
556 550
557#ifdef CONFIG_TCC_BCHECK551#ifdef CONFIG_TCC_BCHECK
558 int bc_save = tcc_state->do_bounds_check;552 int bc_save = S->do_bounds_check;
559 if (tcc_state->do_bounds_check)553 if (S->do_bounds_check)
560 gbound_args(nb_args);554 gbound_args(S, nb_args);
561#endif555#endif
562 556
563 areg[0] = 0; /* int arg regs */557 areg[0] = 0; /* int arg regs */
564 areg[1] = 8; /* float arg regs */558 areg[1] = 8; /* float arg regs */
565 sa = vtop[-nb_args].type.ref->next;559 sa = S->tccgen_vtop[-nb_args].type.ref->next;
566 for (i = 0; i < nb_args; i++) {560 for (i = 0; i < nb_args; i++) {
567 int nregs, byref = 0, tempofs;561 int nregs, byref = 0, tempofs;
568 int prc[3], fieldofs[3];562 int prc[3], fieldofs[3];
569 sv = &vtop[1 + i - nb_args];563 sv = &S->tccgen_vtop[1 + i - nb_args];
570 sv->type.t &= ~VT_ARRAY; // XXX this should be done in tccgen.c564 sv->type.t &= ~VT_ARRAY; // XXX this should be done in tccgen.c
571 size = type_size(&sv->type, &align);565 size = type_size(&sv->type, &align);
572 if (size > 16) {566 if (size > 16) {
@@ -623,53 +617,53 @@ ST_FUNC void gfunc_call(int nb_args) · 50 unmodified lines
623 stack_add = stack_adj + tempspace;617 stack_add = stack_adj + tempspace;
624 618
625 /* fetch cpu flag before generating any code */619 /* fetch cpu flag before generating any code */
626 if ((vtop->r & VT_VALMASK) == VT_CMP)620 if ((S->tccgen_vtop->r & VT_VALMASK) == VT_CMP)
627 gv(RC_INT);621 gv(S, RC_INT);
628 622
629 if (stack_add) {623 if (stack_add) {
630 if (stack_add >= 0x1000) {624 if (stack_add >= 0x1000) {
631 o(0x37 | (5 << 7) | (-stack_add & 0xfffff000)); //lui t0, upper(v)625 o(S, 0x37 | (5 << 7) | (-stack_add & 0xfffff000)); //lui t0, upper(v)
632 EI(0x13, 0, 5, 5, -stack_add << 20 >> 20); // addi t0, t0, lo(v)626 EI(S, 0x13, 0, 5, 5, -stack_add << 20 >> 20); // addi t0, t0, lo(v)
633 ER(0x33, 0, 2, 2, 5, 0); // add sp, sp, t0627 ER(S, 0x33, 0, 2, 2, 5, 0); // add sp, sp, t0
634 }628 }
635 else629 else
636 EI(0x13, 0, 2, 2, -stack_add); // addi sp, sp, -adj630 EI(S, 0x13, 0, 2, 2, -stack_add); // addi sp, sp, -adj
637 for (i = ofs = 0; i < nb_args; i++) {631 for (i = ofs = 0; i < nb_args; i++) {
638 if (info[i] & (64 | 32)) {632 if (info[i] & (64 | 32)) {
639 vrotb(nb_args - i);633 vrotb(S, nb_args - i);
640 size = type_size(&vtop->type, &align);634 size = type_size(&S->tccgen_vtop->type, &align);
641 if (info[i] & 64) {635 if (info[i] & 64) {
642 vset(&char_pointer_type, TREG_SP, 0);636 vset(S, &S->tccgen_char_pointer_type, TREG_SP, 0);
643 vpushi(stack_adj + (info[i] >> 7));637 vpushi(S, stack_adj + (info[i] >> 7));
644 gen_op('+');638 gen_op(S, '+');
645 vpushv(vtop); // this replaces the old argument639 vpushv(S, S->tccgen_vtop); // this replaces the old argument
646 vrott(3);640 vrott(S, 3);
647 indir();641 indir(S);
648 vtop->type = vtop[-1].type;642 S->tccgen_vtop->type = S->tccgen_vtop[-1].type;
649 vswap();643 vswap(S);
650 vstore();644 vstore(S);
651 vpop();645 vpop(S);
652 size = align = 8;646 size = align = 8;
653 }647 }
654 if (info[i] & 32) {648 if (info[i] & 32) {
655 if (align < XLEN)649 if (align < XLEN)
656 align = XLEN;650 align = XLEN;
657 /* Once we support offseted regs we can do this:651 /* Once we support offseted regs we can do this:
658 vset(&vtop->type, TREG_SP | VT_LVAL, ofs);652 vset(S, &S->tccgen_vtop->type, TREG_SP | VT_LVAL, ofs);
659 to construct the lvalue for the outgoing stack slot,653 to construct the lvalue for the outgoing stack slot,
660 until then we have to jump through hoops. */654 until then we have to jump through hoops. */
661 vset(&char_pointer_type, TREG_SP, 0);655 vset(S, &S->tccgen_char_pointer_type, TREG_SP, 0);
662 ofs = (ofs + align - 1) & -align;656 ofs = (ofs + align - 1) & -align;
663 vpushi(ofs);657 vpushi(S, ofs);
664 gen_op('+');658 gen_op(S, '+');
665 indir();659 indir(S);
666 vtop->type = vtop[-1].type;660 S->tccgen_vtop->type = S->tccgen_vtop[-1].type;
667 vswap();661 vswap(S);
668 vstore();662 vstore(S);
669 vtop->r = vtop->r2 = VT_CONST; // this arg is done663 S->tccgen_vtop->r = S->tccgen_vtop->r2 = VT_CONST; // this arg is done
670 ofs += size;664 ofs += size;
671 }665 }
672 vrott(nb_args - i);666 vrott(S, nb_args - i);
673 } else if (info[i] & 16) {667 } else if (info[i] & 16) {
674 assert(!splitofs);668 assert(!splitofs);
675 splitofs = ofs;669 splitofs = ofs;
@@ -685,12 +679,12 @@ ST_FUNC void gfunc_call(int nb_args) · 9 unmodified lines
685 r &= 15;679 r &= 15;
686 r2 = r2 & 64 ? 0 : (r2 >> 7) & 31;680 r2 = r2 & 64 ? 0 : (r2 >> 7) & 31;
687 assert(r2 <= 16);681 assert(r2 <= 16);
688 vrotb(i+1);682 vrotb(S, i+1);
689 origtype = vtop->type;683 origtype = S->tccgen_vtop->type;
690 size = type_size(&vtop->type, &align);684 size = type_size(&S->tccgen_vtop->type, &align);
691 if (size == 0)685 if (size == 0)
692 goto done;686 goto done;
693 loadt = vtop->type.t & VT_BTYPE;687 loadt = S->tccgen_vtop->type.t & VT_BTYPE;
694 if (loadt == VT_STRUCT) {688 if (loadt == VT_STRUCT) {
695 loadt = (ii >> 12) & VT_BTYPE;689 loadt = (ii >> 12) & VT_BTYPE;
696 }690 }
@@ -702,74 +696,74 @@ ST_FUNC void gfunc_call(int nb_args) · 5 unmodified lines
702 assert(r2);696 assert(r2);
703 r2--;697 r2--;
704 } else if (r2) {698 } else if (r2) {
705 test_lvalue();699 test_lvalue(S);
706 vpushv(vtop);700 vpushv(S, S->tccgen_vtop);
707 }701 }
708 vtop->type.t = loadt | (vtop->type.t & VT_UNSIGNED);702 S->tccgen_vtop->type.t = loadt | (S->tccgen_vtop->type.t & VT_UNSIGNED);
709 gv(r < 8 ? RC_R(r) : RC_F(r - 8));703 gv(S, r < 8 ? RC_R(r) : RC_F(r - 8));
710 vtop->type = origtype;704 S->tccgen_vtop->type = origtype;
711 705
712 if (r2 && loadt != VT_LDOUBLE) {706 if (r2 && loadt != VT_LDOUBLE) {
713 r2--;707 r2--;
714 assert(r2 < 16 || r2 == TREG_RA);708 assert(r2 < 16 || r2 == TREG_RA);
715 vswap();709 vswap(S);
716 gaddrof();710 gaddrof(S);
717 vtop->type = char_pointer_type;711 S->tccgen_vtop->type = S->tccgen_char_pointer_type;
718 vpushi(ii >> 20);712 vpushi(S, ii >> 20);
719#ifdef CONFIG_TCC_BCHECK713#ifdef CONFIG_TCC_BCHECK
720 if ((origtype.t & VT_BTYPE) == VT_STRUCT)714 if ((origtype.t & VT_BTYPE) == VT_STRUCT)
721 tcc_state->do_bounds_check = 0;715 S->do_bounds_check = 0;
722#endif716#endif
723 gen_op('+');717 gen_op(S, '+');
724#ifdef CONFIG_TCC_BCHECK718#ifdef CONFIG_TCC_BCHECK
725 tcc_state->do_bounds_check = bc_save;719 S->do_bounds_check = bc_save;
726#endif720#endif
727 indir();721 indir(S);
728 vtop->type = origtype;722 S->tccgen_vtop->type = origtype;
729 loadt = vtop->type.t & VT_BTYPE;723 loadt = S->tccgen_vtop->type.t & VT_BTYPE;
730 if (loadt == VT_STRUCT) {724 if (loadt == VT_STRUCT) {
731 loadt = (ii >> 16) & VT_BTYPE;725 loadt = (ii >> 16) & VT_BTYPE;
732 }726 }
733 save_reg_upstack(r2, 1);727 save_reg_upstack(S, r2, 1);
734 vtop->type.t = loadt | (vtop->type.t & VT_UNSIGNED);728 S->tccgen_vtop->type.t = loadt | (S->tccgen_vtop->type.t & VT_UNSIGNED);
735 load(r2, vtop);729 load(S, r2, S->tccgen_vtop);
736 assert(r2 < VT_CONST);730 assert(r2 < VT_CONST);
737 vtop--;731 S->tccgen_vtop--;
738 vtop->r2 = r2;732 S->tccgen_vtop->r2 = r2;
739 }733 }
740 if (info[nb_args - 1 - i] & 16) {734 if (info[nb_args - 1 - i] & 16) {
741 ES(0x23, 3, 2, ireg(vtop->r2), splitofs); // sd t0, ofs(sp)735 ES(S, 0x23, 3, 2, ireg(S->tccgen_vtop->r2), splitofs); // sd t0, ofs(sp)
742 vtop->r2 = VT_CONST;736 S->tccgen_vtop->r2 = VT_CONST;
743 } else if (loadt == VT_LDOUBLE && vtop->r2 != r2) {737 } else if (loadt == VT_LDOUBLE && S->tccgen_vtop->r2 != r2) {
744 assert(vtop->r2 <= 7 && r2 <= 7);738 assert(S->tccgen_vtop->r2 <= 7 && r2 <= 7);
745 /* XXX we'd like to have 'gv' move directly into739 /* XXX we'd like to have 'gv' move directly into
746 the right class instead of us fixing it up. */740 the right class instead of us fixing it up. */
747 EI(0x13, 0, ireg(r2), ireg(vtop->r2), 0); // mv Ra+1, RR2741 EI(S, 0x13, 0, ireg(r2), ireg(S->tccgen_vtop->r2), 0); // mv Ra+1, RR2
748 vtop->r2 = r2;742 S->tccgen_vtop->r2 = r2;
749 }743 }
750done:744done:
751 vrott(i+1);745 vrott(S, i+1);
752 }746 }
753 }747 }
754 vrotb(nb_args + 1);748 vrotb(S, nb_args + 1);
755 save_regs(nb_args + 1);749 save_regs(S, nb_args + 1);
756 gcall_or_jmp(1);750 gcall_or_jmp(S, 1);
757 vtop -= nb_args + 1;751 S->tccgen_vtop -= nb_args + 1;
758 if (stack_add) {752 if (stack_add) {
759 if (stack_add >= 0x1000) {753 if (stack_add >= 0x1000) {
760 o(0x37 | (5 << 7) | (stack_add & 0xfffff000)); //lui t0, upper(v)754 o(S, 0x37 | (5 << 7) | (stack_add & 0xfffff000)); //lui t0, upper(v)
761 EI(0x13, 0, 5, 5, stack_add << 20 >> 20); // addi t0, t0, lo(v)755 EI(S, 0x13, 0, 5, 5, stack_add << 20 >> 20); // addi t0, t0, lo(v)
762 ER(0x33, 0, 2, 2, 5, 0); // add sp, sp, t0756 ER(S, 0x33, 0, 2, 2, 5, 0); // add sp, sp, t0
763 }757 }
764 else758 else
765 EI(0x13, 0, 2, 2, stack_add); // addi sp, sp, adj759 EI(S, 0x13, 0, 2, 2, stack_add); // addi sp, sp, adj
766 }760 }
767 tcc_free(info);761 tcc_free(S, info);
768}762}
769 763
770static int func_sub_sp_offset, num_va_regs, func_va_list_ofs;764static int func_sub_sp_offset, num_va_regs, func_va_list_ofs;
771 765
772ST_FUNC void gfunc_prolog(Sym *func_sym)766ST_FUNC void gfunc_prolog(TCCState* S, Sym *func_sym)
773{767{
774 CType *func_type = &func_sym->type;768 CType *func_type = &func_sym->type;
775 int i, addr, align, size;769 int i, addr, align, size;
@@ -779,19 +773,19 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 3 unmodified lines
779 CType *type;773 CType *type;
780 774
781 sym = func_type->ref;775 sym = func_type->ref;
782 loc = -16; // for ra and s0776 S->tccgen_loc = -16; // for ra and s0
783 func_sub_sp_offset = ind;777 func_sub_sp_offset = S->tccgen_ind;
784 ind += 5 * 4;778 S->tccgen_ind += 5 * 4;
785 779
786 areg[0] = 0, areg[1] = 0;780 areg[0] = 0, areg[1] = 0;
787 addr = 0;781 addr = 0;
788 /* if the function returns by reference, then add an782 /* if the function returns by reference, then add an
789 implicit pointer parameter */783 implicit pointer parameter */
790 size = type_size(&func_vt, &align);784 size = type_size(&S->tccgen_func_vt, &align);
791 if (size > 2 * XLEN) {785 if (size > 2 * XLEN) {
792 loc -= 8;786 S->tccgen_loc -= 8;
793 func_vc = loc;787 S->tccgen_func_vc = S->tccgen_loc;
794 ES(0x23, 3, 8, 10 + areg[0]++, loc); // sd a0, loc(s0)788 ES(S, 0x23, 3, 8, 10 + areg[0]++, S->tccgen_loc); // sd a0, loc(s0)
795 }789 }
796 /* define parameters */790 /* define parameters */
797 while ((sym = sym->next) != NULL) {791 while ((sym = sym->next) != NULL) {
@@ -801,7 +795,7 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 3 unmodified lines
801 type = &sym->type;795 type = &sym->type;
802 size = type_size(type, &align);796 size = type_size(type, &align);
803 if (size > 2 * XLEN) {797 if (size > 2 * XLEN) {
804 type = &char_pointer_type;798 type = &S->tccgen_char_pointer_type;
805 size = align = byref = 8;799 size = align = byref = 8;
806 }800 }
807 reg_pass(type, prc, fieldofs, 1);801 reg_pass(type, prc, fieldofs, 1);
@@ -816,36 +810,36 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 8 unmodified lines
816 param_addr = addr;810 param_addr = addr;
817 addr += size;811 addr += size;
818 } else {812 } else {
819 loc -= regcount * 8; // XXX could reserve only 'size' bytes813 S->tccgen_loc -= regcount * 8; // XXX could reserve only 'size' bytes
820 param_addr = loc;814 param_addr = S->tccgen_loc;
821 for (i = 0; i < regcount; i++) {815 for (i = 0; i < regcount; i++) {
822 if (areg[prc[1+i] - 1] >= 8) {816 if (areg[prc[1+i] - 1] >= 8) {
823 assert(i == 1 && regcount == 2 && !(addr & 7));817 assert(i == 1 && regcount == 2 && !(addr & 7));
824 EI(0x03, 3, 5, 8, addr); // ld t0, addr(s0)818 EI(S, 0x03, 3, 5, 8, addr); // ld t0, addr(s0)
825 addr += 8;819 addr += 8;
826 ES(0x23, 3, 8, 5, loc + i*8); // sd t0, loc(s0)820 ES(S, 0x23, 3, 8, 5, S->tccgen_loc + i*8); // sd t0, loc(s0)
827 } else if (prc[1+i] == RC_FLOAT) {821 } else if (prc[1+i] == RC_FLOAT) {
828 ES(0x27, (size / regcount) == 4 ? 2 : 3, 8, 10 + areg[1]++, loc + (fieldofs[i+1] >> 4)); // fs[wd] FAi, loc(s0)822 ES(S, 0x27, (size / regcount) == 4 ? 2 : 3, 8, 10 + areg[1]++, S->tccgen_loc + (fieldofs[i+1] >> 4)); // fs[wd] FAi, loc(s0)
829 } else {823 } else {
830 ES(0x23, 3, 8, 10 + areg[0]++, loc + i*8); // sd aX, loc(s0) // XXX824 ES(S, 0x23, 3, 8, 10 + areg[0]++, S->tccgen_loc + i*8); // sd aX, loc(s0) // XXX
831 }825 }
832 }826 }
833 }827 }
834 sym_push(sym->v & ~SYM_FIELD, &sym->type,828 sym_push(S, sym->v & ~SYM_FIELD, &sym->type,
835 (byref ? VT_LLOCAL : VT_LOCAL) | VT_LVAL,829 (byref ? VT_LLOCAL : VT_LOCAL) | VT_LVAL,
836 param_addr);830 param_addr);
837 }831 }
838 func_va_list_ofs = addr;832 func_va_list_ofs = addr;
839 num_va_regs = 0;833 num_va_regs = 0;
840 if (func_var) {834 if (S->tccgen_func_var) {
841 for (; areg[0] < 8; areg[0]++) {835 for (; areg[0] < 8; areg[0]++) {
842 num_va_regs++;836 num_va_regs++;
843 ES(0x23, 3, 8, 10 + areg[0], -8 + num_va_regs * 8); // sd aX, loc(s0)837 ES(S, 0x23, 3, 8, 10 + areg[0], -8 + num_va_regs * 8); // sd aX, loc(s0)
844 }838 }
845 }839 }
846#ifdef CONFIG_TCC_BCHECK840#ifdef CONFIG_TCC_BCHECK
847 if (tcc_state->do_bounds_check)841 if (S->do_bounds_check)
848 gen_bounds_prolog();842 gen_bounds_prolog(S);
849#endif843#endif
850}844}
851 845
@@ -870,113 +864,113 @@ ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, · 18 unmodified lines
870 return nregs;864 return nregs;
871}865}
872 866
873ST_FUNC void arch_transfer_ret_regs(int aftercall)867ST_FUNC void arch_transfer_ret_regs(TCCState* S, int aftercall)
874{868{
875 int prc[3], fieldofs[3];869 int prc[3], fieldofs[3];
876 reg_pass(&vtop->type, prc, fieldofs, 1);870 reg_pass(&S->tccgen_vtop->type, prc, fieldofs, 1);
877 assert(prc[0] == 2 && prc[1] != prc[2] && !(fieldofs[1] >> 4));871 assert(prc[0] == 2 && prc[1] != prc[2] && !(fieldofs[1] >> 4));
878 assert(vtop->r == (VT_LOCAL | VT_LVAL));872 assert(S->tccgen_vtop->r == (VT_LOCAL | VT_LVAL));
879 vpushv(vtop);873 vpushv(S, S->tccgen_vtop);
880 vtop->type.t = fieldofs[1] & VT_BTYPE;874 S->tccgen_vtop->type.t = fieldofs[1] & VT_BTYPE;
881 (aftercall ? store : load)(prc[1] == RC_INT ? REG_IRET : REG_FRET, vtop);875 (aftercall ? store : load)(S, prc[1] == RC_INT ? REG_IRET : REG_FRET, S->tccgen_vtop);
882 vtop->c.i += fieldofs[2] >> 4;876 S->tccgen_vtop->c.i += fieldofs[2] >> 4;
883 vtop->type.t = fieldofs[2] & VT_BTYPE;877 S->tccgen_vtop->type.t = fieldofs[2] & VT_BTYPE;
884 (aftercall ? store : load)(prc[2] == RC_INT ? REG_IRET : REG_FRET, vtop);878 (aftercall ? store : load)(S, prc[2] == RC_INT ? REG_IRET : REG_FRET, S->tccgen_vtop);
885 vtop--;879 S->tccgen_vtop--;
886}880}
887 881
888ST_FUNC void gfunc_epilog(void)882ST_FUNC void gfunc_epilog(TCCState* S)
889{883{
890 int v, saved_ind, d, large_ofs_ind;884 int v, saved_ind, d, large_ofs_ind;
891 885
892#ifdef CONFIG_TCC_BCHECK886#ifdef CONFIG_TCC_BCHECK
893 if (tcc_state->do_bounds_check)887 if (S->do_bounds_check)
894 gen_bounds_epilog();888 gen_bounds_epilog(S);
895#endif889#endif
896 890
897 loc = (loc - num_va_regs * 8);891 S->tccgen_loc = (S->tccgen_loc - num_va_regs * 8);
898 d = v = (-loc + 15) & -16;892 d = v = (-S->tccgen_loc + 15) & -16;
899 893
900 if (v >= (1 << 11)) {894 if (v >= (1 << 11)) {
901 d = 16;895 d = 16;
902 o(0x37 | (5 << 7) | ((0x800 + (v-16)) & 0xfffff000)); //lui t0, upper(v)896 o(S, 0x37 | (5 << 7) | ((0x800 + (v-16)) & 0xfffff000)); //lui t0, upper(v)
903 EI(0x13, 0, 5, 5, (v-16) << 20 >> 20); // addi t0, t0, lo(v)897 EI(S, 0x13, 0, 5, 5, (v-16) << 20 >> 20); // addi t0, t0, lo(v)
904 ER(0x33, 0, 2, 2, 5, 0); // add sp, sp, t0898 ER(S, 0x33, 0, 2, 2, 5, 0); // add sp, sp, t0
905 }899 }
906 EI(0x03, 3, 1, 2, d - 8 - num_va_regs * 8); // ld ra, v-8(sp)900 EI(S, 0x03, 3, 1, 2, d - 8 - num_va_regs * 8); // ld ra, v-8(sp)
907 EI(0x03, 3, 8, 2, d - 16 - num_va_regs * 8); // ld s0, v-16(sp)901 EI(S, 0x03, 3, 8, 2, d - 16 - num_va_regs * 8); // ld s0, v-16(sp)
908 EI(0x13, 0, 2, 2, d); // addi sp, sp, v902 EI(S, 0x13, 0, 2, 2, d); // addi sp, sp, v
909 EI(0x67, 0, 0, 1, 0); // jalr x0, 0(x1), aka ret903 EI(S, 0x67, 0, 0, 1, 0); // jalr x0, 0(x1), aka ret
910 large_ofs_ind = ind;904 large_ofs_ind = S->tccgen_ind;
911 if (v >= (1 << 11)) {905 if (v >= (1 << 11)) {
912 EI(0x13, 0, 8, 2, d - num_va_regs * 8); // addi s0, sp, d906 EI(S, 0x13, 0, 8, 2, d - num_va_regs * 8); // addi s0, sp, d
913 o(0x37 | (5 << 7) | ((0x800 + (v-16)) & 0xfffff000)); //lui t0, upper(v)907 o(S, 0x37 | (5 << 7) | ((0x800 + (v-16)) & 0xfffff000)); //lui t0, upper(v)
914 EI(0x13, 0, 5, 5, (v-16) << 20 >> 20); // addi t0, t0, lo(v)908 EI(S, 0x13, 0, 5, 5, (v-16) << 20 >> 20); // addi t0, t0, lo(v)
915 ER(0x33, 0, 2, 2, 5, 0x20); // sub sp, sp, t0909 ER(S, 0x33, 0, 2, 2, 5, 0x20); // sub sp, sp, t0
916 gjmp_addr(func_sub_sp_offset + 5*4);910 gjmp_addr(S, func_sub_sp_offset + 5*4);
917 }911 }
918 saved_ind = ind;912 saved_ind = S->tccgen_ind;
919 913
920 ind = func_sub_sp_offset;914 S->tccgen_ind = func_sub_sp_offset;
921 EI(0x13, 0, 2, 2, -d); // addi sp, sp, -d915 EI(S, 0x13, 0, 2, 2, -d); // addi sp, sp, -d
922 ES(0x23, 3, 2, 1, d - 8 - num_va_regs * 8); // sd ra, d-8(sp)916 ES(S, 0x23, 3, 2, 1, d - 8 - num_va_regs * 8); // sd ra, d-8(sp)
923 ES(0x23, 3, 2, 8, d - 16 - num_va_regs * 8); // sd s0, d-16(sp)917 ES(S, 0x23, 3, 2, 8, d - 16 - num_va_regs * 8); // sd s0, d-16(sp)
924 if (v < (1 << 11))918 if (v < (1 << 11))
925 EI(0x13, 0, 8, 2, d - num_va_regs * 8); // addi s0, sp, d919 EI(S, 0x13, 0, 8, 2, d - num_va_regs * 8); // addi s0, sp, d
926 else920 else
927 gjmp_addr(large_ofs_ind);921 gjmp_addr(S, large_ofs_ind);
928 if ((ind - func_sub_sp_offset) != 5*4)922 if ((S->tccgen_ind - func_sub_sp_offset) != 5*4)
929 EI(0x13, 0, 0, 0, 0); // addi x0, x0, 0 == nop923 EI(S, 0x13, 0, 0, 0, 0); // addi x0, x0, 0 == nop
930 ind = saved_ind;924 S->tccgen_ind = saved_ind;
931}925}
932 926
933ST_FUNC void gen_va_start(void)927ST_FUNC void gen_va_start(TCCState *S)
934{928{
935 vtop--;929 S->tccgen_vtop--;
936 vset(&char_pointer_type, VT_LOCAL, func_va_list_ofs);930 vset(S, &S->tccgen_char_pointer_type, VT_LOCAL, func_va_list_ofs);
937}931}
938 932
939ST_FUNC void gen_fill_nops(int bytes)933ST_FUNC void gen_fill_nops(TCCState* S, int bytes)
940{934{
941 if ((bytes & 3))935 if ((bytes & 3))
942 tcc_error("alignment of code section not multiple of 4");936 tcc_error(S, "alignment of code section not multiple of 4");
943 while (bytes > 0) {937 while (bytes > 0) {
944 EI(0x13, 0, 0, 0, 0); // addi x0, x0, 0 == nop938 EI(S, 0x13, 0, 0, 0, 0); // addi x0, x0, 0 == nop
945 bytes -= 4;939 bytes -= 4;
946 }940 }
947}941}
948 942
949// Generate forward branch to label:943// Generate forward branch to label:
950ST_FUNC int gjmp(int t)944ST_FUNC int gjmp(TCCState* S, int t)
951{945{
952 if (nocode_wanted)946 if (S->tccgen_nocode_wanted)
953 return t;947 return t;
954 o(t);948 o(S, t);
955 return ind - 4;949 return S->tccgen_ind - 4;
956}950}
957 951
958// Generate branch to known address:952// Generate branch to known address:
959ST_FUNC void gjmp_addr(int a)953ST_FUNC void gjmp_addr(TCCState* S, int a)
960{954{
961 uint32_t r = a - ind, imm;955 uint32_t r = a - S->tccgen_ind, imm;
962 if ((r + (1 << 21)) & ~((1U << 22) - 2)) {956 if ((r + (1 << 21)) & ~((1U << 22) - 2)) {
963 o(0x17 | (5 << 7) | (((r + 0x800) & 0xfffff000))); // lui RR, up(r)957 o(S, 0x17 | (5 << 7) | (((r + 0x800) & 0xfffff000))); // lui RR, up(r)
964 r = (int)r << 20 >> 20;958 r = (int)r << 20 >> 20;
965 EI(0x67, 0, 0, 5, r); // jalr x0, r(t0)959 EI(S, 0x67, 0, 0, 5, r); // jalr x0, r(t0)
966 } else {960 } else {
967 imm = (((r >> 12) & 0xff) << 12)961 imm = (((r >> 12) & 0xff) << 12)
968 | (((r >> 11) & 1) << 20)962 | (((r >> 11) & 1) << 20)
969 | (((r >> 1) & 0x3ff) << 21)963 | (((r >> 1) & 0x3ff) << 21)
970 | (((r >> 20) & 1) << 31);964 | (((r >> 20) & 1) << 31);
971 o(0x6f | imm); // jal x0, imm == j imm965 o(S, 0x6f | imm); // jal x0, imm == j imm
972 }966 }
973}967}
974 968
975ST_FUNC int gjmp_cond(int op, int t)969ST_FUNC int gjmp_cond(TCCState* S, int op, int t)
976{970{
977 int tmp;971 int tmp;
978 int a = vtop->cmp_r & 0xff;972 int a = S->tccgen_vtop->cmp_r & 0xff;
979 int b = (vtop->cmp_r >> 8) & 0xff;973 int b = (S->tccgen_vtop->cmp_r >> 8) & 0xff;
980 switch (op) {974 switch (op) {
981 case TOK_ULT: op = 6; break;975 case TOK_ULT: op = 6; break;
982 case TOK_UGE: op = 7; break;976 case TOK_UGE: op = 7; break;
@@ -989,11 +983,11 @@ ST_FUNC int gjmp_cond(int op, int t) · 6 unmodified lines
989 case TOK_NE: op = 1; break;983 case TOK_NE: op = 1; break;
990 case TOK_EQ: op = 0; break;984 case TOK_EQ: op = 0; break;
991 }985 }
992 o(0x63 | (op ^ 1) << 12 | a << 15 | b << 20 | 8 << 7); // bOP a,b,+4986 o(S, 0x63 | (op ^ 1) << 12 | a << 15 | b << 20 | 8 << 7); // bOP a,b,+4
993 return gjmp(t);987 return gjmp(S, t);
994}988}
995 989
996ST_FUNC int gjmp_append(int n, int t)990ST_FUNC int gjmp_append(TCCState* S, int n, int t)
997{991{
998 void *p;992 void *p;
999 /* insert jump list n into t */993 /* insert jump list n into t */
@@ -1007,23 +1001,23 @@ ST_FUNC int gjmp_append(int n, int t) · 7 unmodified lines
1007 return t;1001 return t;
1008}1002}
1009 1003
1010static void gen_opil(int op, int ll)1004static void gen_opil(TCCState* S, int op, int ll)
1011{1005{
1012 int a, b, d;1006 int a, b, d;
1013 int func3 = 0;1007 int func3 = 0;
1014 ll = ll ? 0 : 8;1008 ll = ll ? 0 : 8;
1015 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {1009 if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1016 int fc = vtop->c.i;1010 int fc = S->tccgen_vtop->c.i;
1017 if (fc == vtop->c.i && !(((unsigned)fc + (1 << 11)) >> 12)) {1011 if (fc == S->tccgen_vtop->c.i && !(((unsigned)fc + (1 << 11)) >> 12)) {
1018 int cll = 0;1012 int cll = 0;
1019 int m = ll ? 31 : 63;1013 int m = ll ? 31 : 63;
1020 vswap();1014 vswap(S);
1021 gv(RC_INT);1015 gv(S, RC_INT);
1022 a = ireg(vtop[0].r);1016 a = ireg(S->tccgen_vtop[0].r);
1023 --vtop;1017 --S->tccgen_vtop;
1024 d = get_reg(RC_INT);1018 d = get_reg(S, RC_INT);
1025 ++vtop;1019 ++S->tccgen_vtop;
1026 vswap();1020 vswap(S);
1027 switch (op) {1021 switch (op) {
1028 case '-':1022 case '-':
1029 if (fc <= -(1 << 11))1023 if (fc <= -(1 << 11))
@@ -1033,13 +1027,13 @@ static void gen_opil(int op, int ll) · 3 unmodified lines
1033 func3 = 0; // addi d, a, fc1027 func3 = 0; // addi d, a, fc
1034 cll = ll;1028 cll = ll;
1035 do_cop:1029 do_cop:
1036 EI(0x13 | cll, func3, ireg(d), a, fc);1030 EI(S, 0x13 | cll, func3, ireg(d), a, fc);
1037 --vtop;1031 --S->tccgen_vtop;
1038 if (op >= TOK_ULT && op <= TOK_GT) {1032 if (op >= TOK_ULT && op <= TOK_GT) {
1039 vset_VT_CMP(TOK_NE);1033 vset_VT_CMP(S, TOK_NE);
1040 vtop->cmp_r = ireg(d) | 0 << 8;1034 S->tccgen_vtop->cmp_r = ireg(d) | 0 << 8;
1041 } else1035 } else
1042 vtop[0].r = d;1036 S->tccgen_vtop[0].r = d;
1043 return;1037 return;
1044 case TOK_LE:1038 case TOK_LE:
1045 if (fc >= (1 << 11) - 1)1039 if (fc >= (1 << 11) - 1)
@@ -1062,97 +1056,97 @@ static void gen_opil(int op, int ll) · 16 unmodified lines
1062 case TOK_UGT: /* -> TOK_ULE */1056 case TOK_UGT: /* -> TOK_ULE */
1063 case TOK_GE: /* -> TOK_LT */1057 case TOK_GE: /* -> TOK_LT */
1064 case TOK_GT: /* -> TOK_LE */1058 case TOK_GT: /* -> TOK_LE */
1065 gen_opil(op - 1, !ll);1059 gen_opil(S, op - 1, !ll);
1066 vtop->cmp_op ^= 1;1060 S->tccgen_vtop->cmp_op ^= 1;
1067 return;1061 return;
1068 1062
1069 case TOK_NE:1063 case TOK_NE:
1070 case TOK_EQ:1064 case TOK_EQ:
1071 if (fc)1065 if (fc)
1072 gen_opil('-', !ll), a = ireg(vtop++->r);1066 gen_opil(S, '-', !ll), a = ireg(S->tccgen_vtop++->r);
1073 --vtop;1067 --S->tccgen_vtop;
1074 vset_VT_CMP(op);1068 vset_VT_CMP(S, op);
1075 vtop->cmp_r = a | 0 << 8;1069 S->tccgen_vtop->cmp_r = a | 0 << 8;
1076 return;1070 return;
1077 }1071 }
1078 }1072 }
1079 }1073 }
1080 gv2(RC_INT, RC_INT);1074 gv2(S, RC_INT, RC_INT);
1081 a = ireg(vtop[-1].r);1075 a = ireg(S->tccgen_vtop[-1].r);
1082 b = ireg(vtop[0].r);1076 b = ireg(S->tccgen_vtop[0].r);
1083 vtop -= 2;1077 S->tccgen_vtop -= 2;
1084 d = get_reg(RC_INT);1078 d = get_reg(S, RC_INT);
1085 vtop++;1079 S->tccgen_vtop++;
1086 vtop[0].r = d;1080 S->tccgen_vtop[0].r = d;
1087 d = ireg(d);1081 d = ireg(d);
1088 switch (op) {1082 switch (op) {
1089 default:1083 default:
1090 if (op >= TOK_ULT && op <= TOK_GT) {1084 if (op >= TOK_ULT && op <= TOK_GT) {
1091 vset_VT_CMP(op);1085 vset_VT_CMP(S, op);
1092 vtop->cmp_r = a | b << 8;1086 S->tccgen_vtop->cmp_r = a | b << 8;
1093 break;1087 break;
1094 }1088 }
1095 tcc_error("implement me: %s(%s)", __FUNCTION__, get_tok_str(op, NULL));1089 tcc_error(S, "implement me: %s(%s)", __FUNCTION__, get_tok_str(S, op, NULL));
1096 break;1090 break;
1097 1091
1098 case '+':1092 case '+':
1099 ER(0x33 | ll, 0, d, a, b, 0); // add d, a, b1093 ER(S, 0x33 | ll, 0, d, a, b, 0); // add d, a, b
1100 break;1094 break;
1101 case '-':1095 case '-':
1102 ER(0x33 | ll, 0, d, a, b, 0x20); // sub d, a, b1096 ER(S, 0x33 | ll, 0, d, a, b, 0x20); // sub d, a, b
1103 break;1097 break;
1104 case TOK_SAR:1098 case TOK_SAR:
1105 ER(0x33 | ll | ll, 5, d, a, b, 0x20); // sra d, a, b1099 ER(S, 0x33 | ll | ll, 5, d, a, b, 0x20); // sra d, a, b
1106 break;1100 break;
1107 case TOK_SHR:1101 case TOK_SHR:
1108 ER(0x33 | ll | ll, 5, d, a, b, 0); // srl d, a, b1102 ER(S, 0x33 | ll | ll, 5, d, a, b, 0); // srl d, a, b
1109 break;1103 break;
1110 case TOK_SHL:1104 case TOK_SHL:
1111 ER(0x33 | ll, 1, d, a, b, 0); // sll d, a, b1105 ER(S, 0x33 | ll, 1, d, a, b, 0); // sll d, a, b
1112 break;1106 break;
1113 case '*':1107 case '*':
1114 ER(0x33 | ll, 0, d, a, b, 1); // mul d, a, b1108 ER(S, 0x33 | ll, 0, d, a, b, 1); // mul d, a, b
1115 break;1109 break;
1116 case '/':1110 case '/':
1117 ER(0x33 | ll, 4, d, a, b, 1); // div d, a, b1111 ER(S, 0x33 | ll, 4, d, a, b, 1); // div d, a, b
1118 break;1112 break;
1119 case '&':1113 case '&':
1120 ER(0x33, 7, d, a, b, 0); // and d, a, b1114 ER(S, 0x33, 7, d, a, b, 0); // and d, a, b
1121 break;1115 break;
1122 case '^':1116 case '^':
1123 ER(0x33, 4, d, a, b, 0); // xor d, a, b1117 ER(S, 0x33, 4, d, a, b, 0); // xor d, a, b
1124 break;1118 break;
1125 case '|':1119 case '|':
1126 ER(0x33, 6, d, a, b, 0); // or d, a, b1120 ER(S, 0x33, 6, d, a, b, 0); // or d, a, b
1127 break;1121 break;
1128 case '%':1122 case '%':
1129 ER(ll ? 0x3b: 0x33, 6, d, a, b, 1); // rem d, a, b1123 ER(S, ll ? 0x3b: 0x33, 6, d, a, b, 1); // rem d, a, b
1130 break;1124 break;
1131 case TOK_UMOD:1125 case TOK_UMOD:
1132 ER(0x33 | ll, 7, d, a, b, 1); // remu d, a, b1126 ER(S, 0x33 | ll, 7, d, a, b, 1); // remu d, a, b
1133 break;1127 break;
1134 case TOK_PDIV:1128 case TOK_PDIV:
1135 case TOK_UDIV:1129 case TOK_UDIV:
1136 ER(0x33 | ll, 5, d, a, b, 1); // divu d, a, b1130 ER(S, 0x33 | ll, 5, d, a, b, 1); // divu d, a, b
1137 break;1131 break;
1138 }1132 }
1139}1133}
1140 1134
1141ST_FUNC void gen_opi(int op)1135ST_FUNC void gen_opi(TCCState* S, int op)
1142{1136{
1143 gen_opil(op, 0);1137 gen_opil(S, op, 0);
1144}1138}
1145 1139
1146ST_FUNC void gen_opl(int op)1140ST_FUNC void gen_opl(TCCState* S, int op)
1147{1141{
1148 gen_opil(op, 1);1142 gen_opil(S, op, 1);
1149}1143}
1150 1144
1151ST_FUNC void gen_opf(int op)1145ST_FUNC void gen_opf(TCCState* S, int op)
1152{1146{
1153 int rs1, rs2, rd, dbl, invert;1147 int rs1, rs2, rd, dbl, invert;
1154 if (vtop[0].type.t == VT_LDOUBLE) {1148 if (S->tccgen_vtop[0].type.t == VT_LDOUBLE) {
1155 CType type = vtop[0].type;1149 CType type = S->tccgen_vtop[0].type;
1156 int func = 0;1150 int func = 0;
1157 int cond = -1;1151 int cond = -1;
1158 switch (op) {1152 switch (op) {
@@ -1168,27 +1162,27 @@ ST_FUNC void gen_opf(int op) · 9 unmodified lines
1168 case TOK_GT: func = TOK___gttf2; cond = 13; break;1162 case TOK_GT: func = TOK___gttf2; cond = 13; break;
1169 default: assert(0); break;1163 default: assert(0); break;
1170 }1164 }
1171 vpush_helper_func(func);1165 vpush_helper_func(S, func);
1172 vrott(3);1166 vrott(S, 3);
1173 gfunc_call(2);1167 gfunc_call(S, 2);
1174 vpushi(0);1168 vpushi(S, 0);
1175 vtop->r = REG_IRET;1169 S->tccgen_vtop->r = REG_IRET;
1176 vtop->r2 = cond < 0 ? TREG_R(1) : VT_CONST;1170 S->tccgen_vtop->r2 = cond < 0 ? TREG_R(1) : VT_CONST;
1177 if (cond < 0)1171 if (cond < 0)
1178 vtop->type = type;1172 S->tccgen_vtop->type = type;
1179 else {1173 else {
1180 vpushi(0);1174 vpushi(S, 0);
1181 gen_opil(op, 1);1175 gen_opil(S, op, 1);
1182 }1176 }
1183 return;1177 return;
1184 }1178 }
1185 1179
1186 gv2(RC_FLOAT, RC_FLOAT);1180 gv2(S, RC_FLOAT, RC_FLOAT);
1187 assert(vtop->type.t == VT_DOUBLE || vtop->type.t == VT_FLOAT);1181 assert(S->tccgen_vtop->type.t == VT_DOUBLE || S->tccgen_vtop->type.t == VT_FLOAT);
1188 dbl = vtop->type.t == VT_DOUBLE;1182 dbl = S->tccgen_vtop->type.t == VT_DOUBLE;
1189 rs1 = freg(vtop[-1].r);1183 rs1 = freg(S->tccgen_vtop[-1].r);
1190 rs2 = freg(vtop->r);1184 rs2 = freg(S->tccgen_vtop->r);
1191 vtop--;1185 S->tccgen_vtop--;
1192 invert = 0;1186 invert = 0;
1193 switch(op) {1187 switch(op) {
1194 default:1188 default:
@@ -1196,10 +1190,10 @@ ST_FUNC void gen_opf(int op) · 1 unmodified line
1196 case '+':1190 case '+':
1197 op = 0; // fadd1191 op = 0; // fadd
1198 arithop:1192 arithop:
1199 rd = get_reg(RC_FLOAT);1193 rd = get_reg(S, RC_FLOAT);
1200 vtop->r = rd;1194 S->tccgen_vtop->r = rd;
1201 rd = freg(rd);1195 rd = freg(rd);
1202 ER(0x53, 7, rd, rs1, rs2, dbl | (op << 2)); // fop.[sd] RD, RS1, RS2 (dyn rm)1196 ER(S, 0x53, 7, rd, rs1, rs2, dbl | (op << 2)); // fop.[sd] RD, RS1, RS2 (dyn rm)
1203 break;1197 break;
1204 case '-':1198 case '-':
1205 op = 1; // fsub1199 op = 1; // fsub
@@ -1213,12 +1207,12 @@ ST_FUNC void gen_opf(int op) · 7 unmodified lines
1213 case TOK_EQ:1207 case TOK_EQ:
1214 op = 2; // EQ1208 op = 2; // EQ
1215 cmpop:1209 cmpop:
1216 rd = get_reg(RC_INT);1210 rd = get_reg(S, RC_INT);
1217 vtop->r = rd;1211 S->tccgen_vtop->r = rd;
1218 rd = ireg(rd);1212 rd = ireg(rd);
1219 ER(0x53, op, rd, rs1, rs2, dbl | 0x50); // fcmp.[sd] RD, RS1, RS2 (op == eq/lt/le)1213 ER(S, 0x53, op, rd, rs1, rs2, dbl | 0x50); // fcmp.[sd] RD, RS1, RS2 (op == eq/lt/le)
1220 if (invert)1214 if (invert)
1221 EI(0x13, 4, rd, rd, 1); // xori RD, 11215 EI(S, 0x13, 4, rd, rd, 1); // xori RD, 1
1222 break;1216 break;
1223 case TOK_NE:1217 case TOK_NE:
1224 invert = 1;1218 invert = 1;
@@ -1241,67 +1235,67 @@ ST_FUNC void gen_opf(int op) · 16 unmodified lines
1241 }1235 }
1242}1236}
1243 1237
1244ST_FUNC void gen_cvt_sxtw(void)1238ST_FUNC void gen_cvt_sxtw(TCCState *S)
1245{1239{
1246 /* XXX on risc-v the registers are usually sign-extended already.1240 /* XXX on risc-v the registers are usually sign-extended already.
1247 Let's try to not do anything here. */1241 Let's try to not do anything here. */
1248}1242}
1249 1243
1250ST_FUNC void gen_cvt_itof(int t)1244ST_FUNC void gen_cvt_itof(TCCState* S, int t)
1251{1245{
1252 int rr = ireg(gv(RC_INT)), dr;1246 int rr = ireg(gv(S, RC_INT)), dr;
1253 int u = vtop->type.t & VT_UNSIGNED;1247 int u = S->tccgen_vtop->type.t & VT_UNSIGNED;
1254 int l = (vtop->type.t & VT_BTYPE) == VT_LLONG;1248 int l = (S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG;
1255 if (t == VT_LDOUBLE) {1249 if (t == VT_LDOUBLE) {
1256 int func = l ?1250 int func = l ?
1257 (u ? TOK___floatunditf : TOK___floatditf) :1251 (u ? TOK___floatunditf : TOK___floatditf) :
1258 (u ? TOK___floatunsitf : TOK___floatsitf);1252 (u ? TOK___floatunsitf : TOK___floatsitf);
1259 vpush_helper_func(func);1253 vpush_helper_func(S, func);
1260 vrott(2);1254 vrott(S, 2);
1261 gfunc_call(1);1255 gfunc_call(S, 1);
1262 vpushi(0);1256 vpushi(S, 0);
1263 vtop->type.t = t;1257 S->tccgen_vtop->type.t = t;
1264 vtop->r = REG_IRET;1258 S->tccgen_vtop->r = REG_IRET;
1265 vtop->r2 = TREG_R(1);1259 S->tccgen_vtop->r2 = TREG_R(1);
1266 } else {1260 } else {
1267 vtop--;1261 S->tccgen_vtop--;
1268 dr = get_reg(RC_FLOAT);1262 dr = get_reg(S, RC_FLOAT);
1269 vtop++;1263 S->tccgen_vtop++;
1270 vtop->r = dr;1264 S->tccgen_vtop->r = dr;
1271 dr = freg(dr);1265 dr = freg(dr);
1272 EIu(0x53, 7, dr, rr, ((0x68 | (t == VT_DOUBLE ? 1 : 0)) << 5) | (u ? 1 : 0) | (l ? 2 : 0)); // fcvt.[sd].[wl][u]1266 EIu(S, 0x53, 7, dr, rr, ((0x68 | (t == VT_DOUBLE ? 1 : 0)) << 5) | (u ? 1 : 0) | (l ? 2 : 0)); // fcvt.[sd].[wl][u]
1273 }1267 }
1274}1268}
1275 1269
1276ST_FUNC void gen_cvt_ftoi(int t)1270ST_FUNC void gen_cvt_ftoi(TCCState* S, int t)
1277{1271{
1278 int ft = vtop->type.t & VT_BTYPE;1272 int ft = S->tccgen_vtop->type.t & VT_BTYPE;
1279 int l = (t & VT_BTYPE) == VT_LLONG;1273 int l = (t & VT_BTYPE) == VT_LLONG;
1280 int u = t & VT_UNSIGNED;1274 int u = t & VT_UNSIGNED;
1281 if (ft == VT_LDOUBLE) {1275 if (ft == VT_LDOUBLE) {
1282 int func = l ?1276 int func = l ?
1283 (u ? TOK___fixunstfdi : TOK___fixtfdi) :1277 (u ? TOK___fixunstfdi : TOK___fixtfdi) :
1284 (u ? TOK___fixunstfsi : TOK___fixtfsi);1278 (u ? TOK___fixunstfsi : TOK___fixtfsi);
1285 vpush_helper_func(func);1279 vpush_helper_func(S, func);
1286 vrott(2);1280 vrott(S, 2);
1287 gfunc_call(1);1281 gfunc_call(S, 1);
1288 vpushi(0);1282 vpushi(S, 0);
1289 vtop->type.t = t;1283 S->tccgen_vtop->type.t = t;
1290 vtop->r = REG_IRET;1284 S->tccgen_vtop->r = REG_IRET;
1291 } else {1285 } else {
1292 int rr = freg(gv(RC_FLOAT)), dr;1286 int rr = freg(gv(S, RC_FLOAT)), dr;
1293 vtop--;1287 S->tccgen_vtop--;
1294 dr = get_reg(RC_INT);1288 dr = get_reg(S, RC_INT);
1295 vtop++;1289 S->tccgen_vtop++;
1296 vtop->r = dr;1290 S->tccgen_vtop->r = dr;
1297 dr = ireg(dr);1291 dr = ireg(dr);
1298 EIu(0x53, 1, dr, rr, ((0x60 | (ft == VT_DOUBLE ? 1 : 0)) << 5) | (u ? 1 : 0) | (l ? 2 : 0)); // fcvt.[wl][u].[sd] rtz1292 EIu(S, 0x53, 1, dr, rr, ((0x60 | (ft == VT_DOUBLE ? 1 : 0)) << 5) | (u ? 1 : 0) | (l ? 2 : 0)); // fcvt.[wl][u].[sd] rtz
1299 }1293 }
1300}1294}
1301 1295
1302ST_FUNC void gen_cvt_ftof(int dt)1296ST_FUNC void gen_cvt_ftof(TCCState* S, int dt)
1303{1297{
1304 int st = vtop->type.t & VT_BTYPE, rs, rd;1298 int st = S->tccgen_vtop->type.t & VT_BTYPE, rs, rd;
1305 dt &= VT_BTYPE;1299 dt &= VT_BTYPE;
1306 if (st == dt)1300 if (st == dt)
1307 return;1301 return;
@@ -1313,109 +1307,109 @@ ST_FUNC void gen_cvt_ftof(int dt) · 5 unmodified lines
1313 functions, and on riscv unnamed float args are passed like1307 functions, and on riscv unnamed float args are passed like
1314 integers. But we really need them in the float argument registers1308 integers. But we really need them in the float argument registers
1315 for extendsftf2/extenddftf2. So, do it explicitely. */1309 for extendsftf2/extenddftf2. So, do it explicitely. */
1316 save_regs(1);1310 save_regs(S, 1);
1317 if (dt == VT_LDOUBLE)1311 if (dt == VT_LDOUBLE)
1318 gv(RC_F(0));1312 gv(S, RC_F(0));
1319 else {1313 else {
1320 gv(RC_R(0));1314 gv(S, RC_R(0));
1321 assert(vtop->r2 < 7);1315 assert(S->tccgen_vtop->r2 < 7);
1322 if (vtop->r2 != 1 + vtop->r) {1316 if (S->tccgen_vtop->r2 != 1 + S->tccgen_vtop->r) {
1323 EI(0x13, 0, ireg(vtop->r) + 1, ireg(vtop->r2), 0); // mv Ra+1, RR21317 EI(S, 0x13, 0, ireg(S->tccgen_vtop->r) + 1, ireg(S->tccgen_vtop->r2), 0); // mv Ra+1, RR2
1324 vtop->r2 = 1 + vtop->r;1318 S->tccgen_vtop->r2 = 1 + S->tccgen_vtop->r;
1325 }1319 }
1326 }1320 }
1327 vpush_helper_func(func);1321 vpush_helper_func(S, func);
1328 gcall_or_jmp(1);1322 gcall_or_jmp(S, 1);
1329 vtop -= 2;1323 S->tccgen_vtop -= 2;
1330 vpushi(0);1324 vpushi(S, 0);
1331 vtop->type.t = dt;1325 S->tccgen_vtop->type.t = dt;
1332 if (dt == VT_LDOUBLE)1326 if (dt == VT_LDOUBLE)
1333 vtop->r = REG_IRET, vtop->r2 = REG_IRET+1;1327 S->tccgen_vtop->r = REG_IRET, S->tccgen_vtop->r2 = REG_IRET+1;
1334 else1328 else
1335 vtop->r = REG_FRET;1329 S->tccgen_vtop->r = REG_FRET;
1336 } else {1330 } else {
1337 assert (dt == VT_FLOAT || dt == VT_DOUBLE);1331 assert (dt == VT_FLOAT || dt == VT_DOUBLE);
1338 assert (st == VT_FLOAT || st == VT_DOUBLE);1332 assert (st == VT_FLOAT || st == VT_DOUBLE);
1339 rs = gv(RC_FLOAT);1333 rs = gv(S, RC_FLOAT);
1340 rd = get_reg(RC_FLOAT);1334 rd = get_reg(S, RC_FLOAT);
1341 if (dt == VT_DOUBLE)1335 if (dt == VT_DOUBLE)
1342 EI(0x53, 0, freg(rd), freg(rs), 0x21 << 5); // fcvt.d.s RD, RS (no rm)1336 EI(S, 0x53, 0, freg(rd), freg(rs), 0x21 << 5); // fcvt.d.s RD, RS (no rm)
1343 else1337 else
1344 EI(0x53, 7, freg(rd), freg(rs), (0x20 << 5) | 1); // fcvt.s.d RD, RS (dyn rm)1338 EI(S, 0x53, 7, freg(rd), freg(rs), (0x20 << 5) | 1); // fcvt.s.d RD, RS (dyn rm)
1345 vtop->r = rd;1339 S->tccgen_vtop->r = rd;
1346 }1340 }
1347}1341}
1348 1342
1349/* increment tcov counter */1343/* increment tcov counter */
1350ST_FUNC void gen_increment_tcov (SValue *sv)1344ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv)
1351{1345{
1352 int r1, r2;1346 int r1, r2;
1353 Sym label = {0};1347 Sym label = {0};
1354 label.type.t = VT_VOID | VT_STATIC;1348 label.type.t = VT_VOID | VT_STATIC;
1355 1349
1356 vpushv(sv);1350 vpushv(S, sv);
1357 vtop->r = r1 = get_reg(RC_INT);1351 S->tccgen_vtop->r = r1 = get_reg(S, RC_INT);
1358 r2 = get_reg(RC_INT);1352 r2 = get_reg(S, RC_INT);
1359 r1 = ireg(r1);1353 r1 = ireg(r1);
1360 r2 = ireg(r2);1354 r2 = ireg(r2);
1361 greloca(cur_text_section, sv->sym, ind, R_RISCV_PCREL_HI20, 0);1355 greloca(S, cur_text_section, sv->sym, S->tccgen_ind, R_RISCV_PCREL_HI20, 0);
1362 put_extern_sym(&label, cur_text_section, ind, 0);1356 put_extern_sym(S, &label, cur_text_section, S->tccgen_ind, 0);
1363 o(0x17 | (r1 << 7)); // auipc RR, 0 %pcrel_hi(sym)1357 o(S, 0x17 | (r1 << 7)); // auipc RR, 0 %pcrel_hi(sym)
1364 greloca(cur_text_section, &label, ind, R_RISCV_PCREL_LO12_I, 0);1358 greloca(S, cur_text_section, &label, S->tccgen_ind, R_RISCV_PCREL_LO12_I, 0);
1365 EI(0x03, 3, r2, r1, 0); // ld r2, x[r1]1359 EI(S, 0x03, 3, r2, r1, 0); // ld r2, x[r1]
1366 EI(0x13, 0, r2, r2, 1); // addi r2, r2, #11360 EI(S, 0x13, 0, r2, r2, 1); // addi r2, r2, #1
1367 greloca(cur_text_section, sv->sym, ind, R_RISCV_PCREL_HI20, 0);1361 greloca(S, cur_text_section, sv->sym, S->tccgen_ind, R_RISCV_PCREL_HI20, 0);
1368 label.c = 0; /* force new local ELF symbol */1362 label.c = 0; /* force new local ELF symbol */
1369 put_extern_sym(&label, cur_text_section, ind, 0);1363 put_extern_sym(S, &label, cur_text_section, S->tccgen_ind, 0);
1370 o(0x17 | (r1 << 7)); // auipc RR, 0 %pcrel_hi(sym)1364 o(S, 0x17 | (r1 << 7)); // auipc RR, 0 %pcrel_hi(sym)
1371 greloca(cur_text_section, &label, ind, R_RISCV_PCREL_LO12_S, 0);1365 greloca(S, cur_text_section, &label, S->tccgen_ind, R_RISCV_PCREL_LO12_S, 0);
1372 ES(0x23, 3, r1, r2, 0); // sd r2, [r1]1366 ES(S, 0x23, 3, r1, r2, 0); // sd r2, [r1]
1373 vpop();1367 vpop(S);
1374}1368}
1375 1369
1376ST_FUNC void ggoto(void)1370ST_FUNC void ggoto(TCCState* S)
1377{1371{
1378 gcall_or_jmp(0);1372 gcall_or_jmp(S, 0);
1379 vtop--;1373 S->tccgen_vtop--;
1380}1374}
1381 1375
1382ST_FUNC void gen_vla_sp_save(int addr)1376ST_FUNC void gen_vla_sp_save(TCCState* S, int addr)
1383{1377{
1384 ES(0x23, 3, 8, 2, addr); // sd sp, fc(s0)1378 ES(S, 0x23, 3, 8, 2, addr); // sd sp, fc(s0)
1385}1379}
1386 1380
1387ST_FUNC void gen_vla_sp_restore(int addr)1381ST_FUNC void gen_vla_sp_restore(TCCState* S, int addr)
1388{1382{
1389 EI(0x03, 3, 2, 8, addr); // ld sp, fc(s0)1383 EI(S, 0x03, 3, 2, 8, addr); // ld sp, fc(s0)
1390}1384}
1391 1385
1392ST_FUNC void gen_vla_alloc(CType *type, int align)1386ST_FUNC void gen_vla_alloc(TCCState* S, CType *type, int align)
1393{1387{
1394 int rr;1388 int rr;
1395#if defined(CONFIG_TCC_BCHECK)1389#if defined(CONFIG_TCC_BCHECK)
1396 if (tcc_state->do_bounds_check)1390 if (S->do_bounds_check)
1397 vpushv(vtop);1391 vpushv(S, S->tccgen_vtop);
1398#endif1392#endif
1399 rr = ireg(gv(RC_INT));1393 rr = ireg(gv(S, RC_INT));
1400#if defined(CONFIG_TCC_BCHECK)1394#if defined(CONFIG_TCC_BCHECK)
1401 if (tcc_state->do_bounds_check)1395 if (S->do_bounds_check)
1402 EI(0x13, 0, rr, rr, 15+1); // addi RR, RR, 15+11396 EI(S, 0x13, 0, rr, rr, 15+1); // addi RR, RR, 15+1
1403 else1397 else
1404#endif1398#endif
1405 EI(0x13, 0, rr, rr, 15); // addi RR, RR, 151399 EI(S, 0x13, 0, rr, rr, 15); // addi RR, RR, 15
1406 EI(0x13, 7, rr, rr, -16); // andi, RR, RR, -161400 EI(S, 0x13, 7, rr, rr, -16); // andi, RR, RR, -16
1407 ER(0x33, 0, 2, 2, rr, 0x20); // sub sp, sp, rr1401 ER(S, 0x33, 0, 2, 2, rr, 0x20); // sub sp, sp, rr
1408 vpop();1402 vpop(S);
1409#if defined(CONFIG_TCC_BCHECK)1403#if defined(CONFIG_TCC_BCHECK)
1410 if (tcc_state->do_bounds_check) {1404 if (S->do_bounds_check) {
1411 vpushi(0);1405 vpushi(S, 0);
1412 vtop->r = TREG_R(0);1406 S->tccgen_vtop->r = TREG_R(0);
1413 o(0x00010513); /* mv a0,sp */1407 o(S, 0x00010513); /* mv a0,sp */
1414 vswap();1408 vswap(S);
1415 vpush_helper_func(TOK___bound_new_region);1409 vpush_helper_func(S, TOK___bound_new_region);
1416 vrott(3);1410 vrott(S, 3);
1417 gfunc_call(2);1411 gfunc_call(S, 2);
1418 func_bound_add_epilog = 1;1412 S->func_bound_add_epilog = 1;
1419 }1413 }
1420#endif1414#endif
1421}1415}
riscv64-link.c+30−30
@@ -95,39 +95,39 @@ int gotplt_entry_type (int reloc_type) · 94 unmodified lines
95 return -1;95 return -1;
96}96}
97 97
98ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)98ST_FUNC unsigned create_plt_entry(TCCState *S, unsigned got_offset, struct sym_attr *attr)
99{99{
100 Section *plt = s1->plt;100 Section *plt = S->plt;
101 uint8_t *p;101 uint8_t *p;
102 unsigned plt_offset;102 unsigned plt_offset;
103 103
104 if (plt->data_offset == 0)104 if (plt->data_offset == 0)
105 section_ptr_add(plt, 32);105 section_ptr_add(S, plt, 32);
106 plt_offset = plt->data_offset;106 plt_offset = plt->data_offset;
107 107
108 p = section_ptr_add(plt, 16);108 p = section_ptr_add(S, plt, 16);
109 write64le(p, got_offset);109 write64le(p, got_offset);
110 return plt_offset;110 return plt_offset;
111}111}
112 112
113/* relocate the PLT: compute addresses and offsets in the PLT now that final113/* relocate the PLT: compute addresses and offsets in the PLT now that final
114 address for PLT and GOT are known (see fill_program_header) */114 address for PLT and GOT are known (see fill_program_header) */
115ST_FUNC void relocate_plt(TCCState *s1)115ST_FUNC void relocate_plt(TCCState *S)
116{116{
117 uint8_t *p, *p_end;117 uint8_t *p, *p_end;
118 118
119 if (!s1->plt)119 if (!S->plt)
120 return;120 return;
121 121
122 p = s1->plt->data;122 p = S->plt->data;
123 p_end = p + s1->plt->data_offset;123 p_end = p + S->plt->data_offset;
124 124
125 if (p < p_end) {125 if (p < p_end) {
126 uint64_t plt = s1->plt->sh_addr;126 uint64_t plt = S->plt->sh_addr;
127 uint64_t got = s1->got->sh_addr;127 uint64_t got = S->got->sh_addr;
128 uint64_t off = (got - plt + 0x800) >> 12;128 uint64_t off = (got - plt + 0x800) >> 12;
129 if ((off + ((uint32_t)1 << 20)) >> 21)129 if ((off + ((uint32_t)1 << 20)) >> 21)
130 tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt);130 tcc_error(S, "Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt);
131 write32le(p, 0x397 | (off << 12)); // auipc t2, %pcrel_hi(got)131 write32le(p, 0x397 | (off << 12)); // auipc t2, %pcrel_hi(got)
132 write32le(p + 4, 0x41c30333); // sub t1, t1, t3132 write32le(p + 4, 0x41c30333); // sub t1, t1, t3
133 write32le(p + 8, 0x0003be03 // ld t3, %pcrel_lo(got)(t2)133 write32le(p + 8, 0x0003be03 // ld t3, %pcrel_lo(got)(t2)
@@ -140,11 +140,11 @@ ST_FUNC void relocate_plt(TCCState *s1) · 6 unmodified lines
140 write32le(p + 28, 0x000e0067); // jr t3140 write32le(p + 28, 0x000e0067); // jr t3
141 p += 32;141 p += 32;
142 while (p < p_end) {142 while (p < p_end) {
143 uint64_t pc = plt + (p - s1->plt->data);143 uint64_t pc = plt + (p - S->plt->data);
144 uint64_t addr = got + read64le(p);144 uint64_t addr = got + read64le(p);
145 uint64_t off = (addr - pc + 0x800) >> 12;145 uint64_t off = (addr - pc + 0x800) >> 12;
146 if ((off + ((uint32_t)1 << 20)) >> 21)146 if ((off + ((uint32_t)1 << 20)) >> 21)
147 tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc);147 tcc_error(S, "Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc);
148 write32le(p, 0xe17 | (off << 12)); // auipc t3, %pcrel_hi(func@got)148 write32le(p, 0xe17 | (off << 12)); // auipc t3, %pcrel_hi(func@got)
149 write32le(p + 4, 0x000e3e03 // ld t3, %pcrel_lo(func@got)(t3)149 write32le(p + 4, 0x000e3e03 // ld t3, %pcrel_lo(func@got)(t3)
150 | (((addr - pc) & 0xfff) << 20));150 | (((addr - pc) & 0xfff) << 20));
@@ -154,16 +154,16 @@ ST_FUNC void relocate_plt(TCCState *s1) · 3 unmodified lines
154 }154 }
155 }155 }
156 156
157 if (s1->plt->reloc) {157 if (S->plt->reloc) {
158 ElfW_Rel *rel;158 ElfW_Rel *rel;
159 p = s1->got->data;159 p = S->got->data;
160 for_each_elem(s1->plt->reloc, 0, rel, ElfW_Rel) {160 for_each_elem(S->plt->reloc, 0, rel, ElfW_Rel) {
161 write64le(p + rel->r_offset, s1->plt->sh_addr);161 write64le(p + rel->r_offset, S->plt->sh_addr);
162 }162 }
163 }163 }
164}164}
165 165
166void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr,166void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr,
167 addr_t addr, addr_t val)167 addr_t addr, addr_t val)
168{168{
169 uint64_t off64;169 uint64_t off64;
@@ -179,7 +179,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 9 unmodified lines
179 case R_RISCV_BRANCH:179 case R_RISCV_BRANCH:
180 off64 = val - addr;180 off64 = val - addr;
181 if ((off64 + (1 << 12)) & ~(uint64_t)0x1ffe)181 if ((off64 + (1 << 12)) & ~(uint64_t)0x1ffe)
182 tcc_error("R_RISCV_BRANCH relocation failed"182 tcc_error(S, "R_RISCV_BRANCH relocation failed"
183 " (val=%lx, addr=%lx)", (long)val, (long)addr);183 " (val=%lx, addr=%lx)", (long)val, (long)addr);
184 off32 = off64 >> 1;184 off32 = off64 >> 1;
185 write32le(ptr, (read32le(ptr) & ~0xfe000f80)185 write32le(ptr, (read32le(ptr) & ~0xfe000f80)
@@ -191,7 +191,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 5 unmodified lines
191 case R_RISCV_JAL:191 case R_RISCV_JAL:
192 off64 = val - addr;192 off64 = val - addr;
193 if ((off64 + (1 << 21)) & ~(((uint64_t)1 << 22) - 2))193 if ((off64 + (1 << 21)) & ~(((uint64_t)1 << 22) - 2))
194 tcc_error("R_RISCV_JAL relocation failed"194 tcc_error(S, "R_RISCV_JAL relocation failed"
195 " (val=%lx, addr=%lx)", (long)val, (long)addr);195 " (val=%lx, addr=%lx)", (long)val, (long)addr);
196 off32 = off64;196 off32 = off64;
197 write32le(ptr, (read32le(ptr) & 0xfff)197 write32le(ptr, (read32le(ptr) & 0xfff)
@@ -213,7 +213,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 15 unmodified lines
213#endif213#endif
214 off64 = (int64_t)(val - addr + 0x800) >> 12;214 off64 = (int64_t)(val - addr + 0x800) >> 12;
215 if ((off64 + ((uint64_t)1 << 20)) >> 21)215 if ((off64 + ((uint64_t)1 << 20)) >> 21)
216 tcc_error("R_RISCV_PCREL_HI20 relocation failed: off=%lx cond=%lx sym=%s",216 tcc_error(S, "R_RISCV_PCREL_HI20 relocation failed: off=%lx cond=%lx sym=%s",
217 (long)off64, (long)((int64_t)(off64 + ((uint64_t)1 << 20)) >> 21),217 (long)off64, (long)((int64_t)(off64 + ((uint64_t)1 << 20)) >> 21),
218 symtab_section->link->data + sym->st_name);218 symtab_section->link->data + sym->st_name);
219 write32le(ptr, (read32le(ptr) & 0xfff)219 write32le(ptr, (read32le(ptr) & 0xfff)
@@ -222,10 +222,10 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 2 unmodified lines
222 last_hi.val = val;222 last_hi.val = val;
223 return;223 return;
224 case R_RISCV_GOT_HI20:224 case R_RISCV_GOT_HI20:
225 val = s1->got->sh_addr + get_sym_attr(s1, sym_index, 0)->got_offset;225 val = S->got->sh_addr + get_sym_attr(S, sym_index, 0)->got_offset;
226 off64 = (int64_t)(val - addr + 0x800) >> 12;226 off64 = (int64_t)(val - addr + 0x800) >> 12;
227 if ((off64 + ((uint64_t)1 << 20)) >> 21)227 if ((off64 + ((uint64_t)1 << 20)) >> 21)
228 tcc_error("R_RISCV_GOT_HI20 relocation failed");228 tcc_error(S, "R_RISCV_GOT_HI20 relocation failed");
229 last_hi.addr = addr;229 last_hi.addr = addr;
230 last_hi.val = val;230 last_hi.val = val;
231 write32le(ptr, (read32le(ptr) & 0xfff)231 write32le(ptr, (read32le(ptr) & 0xfff)
@@ -236,7 +236,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 4 unmodified lines
236 printf("PCREL_LO12_I: val=%lx addr=%lx\n", (long)val, (long)addr);236 printf("PCREL_LO12_I: val=%lx addr=%lx\n", (long)val, (long)addr);
237#endif237#endif
238 if (val != last_hi.addr)238 if (val != last_hi.addr)
239 tcc_error("unsupported hi/lo pcrel reloc scheme");239 tcc_error(S, "unsupported hi/lo pcrel reloc scheme");
240 val = last_hi.val;240 val = last_hi.val;
241 addr = last_hi.addr;241 addr = last_hi.addr;
242 write32le(ptr, (read32le(ptr) & 0xfffff)242 write32le(ptr, (read32le(ptr) & 0xfffff)
@@ -244,7 +244,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 1 unmodified line
244 return;244 return;
245 case R_RISCV_PCREL_LO12_S:245 case R_RISCV_PCREL_LO12_S:
246 if (val != last_hi.addr)246 if (val != last_hi.addr)
247 tcc_error("unsupported hi/lo pcrel reloc scheme");247 tcc_error(S, "unsupported hi/lo pcrel reloc scheme");
248 val = last_hi.val;248 val = last_hi.val;
249 addr = last_hi.addr;249 addr = last_hi.addr;
250 off32 = val - addr;250 off32 = val - addr;
@@ -256,7 +256,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 5 unmodified lines
256 case R_RISCV_RVC_BRANCH:256 case R_RISCV_RVC_BRANCH:
257 off64 = (val - addr);257 off64 = (val - addr);
258 if ((off64 + (1 << 8)) & ~(uint64_t)0x1fe)258 if ((off64 + (1 << 8)) & ~(uint64_t)0x1fe)
259 tcc_error("R_RISCV_RVC_BRANCH relocation failed"259 tcc_error(S, "R_RISCV_RVC_BRANCH relocation failed"
260 " (val=%lx, addr=%lx)", (long)val, (long)addr);260 " (val=%lx, addr=%lx)", (long)val, (long)addr);
261 off32 = off64;261 off32 = off64;
262 write16le(ptr, (read16le(ptr) & 0xe383)262 write16le(ptr, (read16le(ptr) & 0xe383)
@@ -269,7 +269,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 6 unmodified lines
269 case R_RISCV_RVC_JUMP:269 case R_RISCV_RVC_JUMP:
270 off64 = (val - addr);270 off64 = (val - addr);
271 if ((off64 + (1 << 11)) & ~(uint64_t)0xffe)271 if ((off64 + (1 << 11)) & ~(uint64_t)0xffe)
272 tcc_error("R_RISCV_RVC_BRANCH relocation failed"272 tcc_error(S, "R_RISCV_RVC_BRANCH relocation failed"
273 " (val=%lx, addr=%lx)", (long)val, (long)addr);273 " (val=%lx, addr=%lx)", (long)val, (long)addr);
274 off32 = off64;274 off32 = off64;
275 write16le(ptr, (read16le(ptr) & 0xe003)275 write16le(ptr, (read16le(ptr) & 0xe003)
@@ -284,7 +284,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 8 unmodified lines
284 return;284 return;
285 285
286 case R_RISCV_32:286 case R_RISCV_32:
287 if (s1->output_type == TCC_OUTPUT_DLL) {287 if (S->output_type == TCC_OUTPUT_DLL) {
288 /* XXX: this logic may depend on TCC's codegen288 /* XXX: this logic may depend on TCC's codegen
289 now TCC uses R_RISCV_RELATIVE even for a 64bit pointer */289 now TCC uses R_RISCV_RELATIVE even for a 64bit pointer */
290 qrel->r_offset = rel->r_offset;290 qrel->r_offset = rel->r_offset;
@@ -296,8 +296,8 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 5 unmodified lines
296 add32le(ptr, val);296 add32le(ptr, val);
297 return;297 return;
298 case R_RISCV_64:298 case R_RISCV_64:
299 if (s1->output_type == TCC_OUTPUT_DLL) {299 if (S->output_type == TCC_OUTPUT_DLL) {
300 esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;300 esym_index = get_sym_attr(S, sym_index, 0)->dyn_index;
301 qrel->r_offset = rel->r_offset;301 qrel->r_offset = rel->r_offset;
302 if (esym_index) {302 if (esym_index) {
303 qrel->r_info = ELFW(R_INFO)(esym_index, R_RISCV_64);303 qrel->r_info = ELFW(R_INFO)(esym_index, R_RISCV_64);
tcc.c+168−70
@@ -199,40 +199,40 @@ static void print_dirs(const char *msg, char **paths, int nb_paths) · 198 unmodified lines
199 printf(" %s\n", paths[i]);199 printf(" %s\n", paths[i]);
200}200}
201 201
202static void print_search_dirs(TCCState *s)202static void print_search_dirs(TCCState *S)
203{203{
204 printf("install: %s\n", s->tcc_lib_path);204 printf("install: %s\n", S->tcc_lib_path);
205 /* print_dirs("programs", NULL, 0); */205 /* print_dirs("programs", NULL, 0); */
206 print_dirs("include", s->sysinclude_paths, s->nb_sysinclude_paths);206 print_dirs("include", S->sysinclude_paths, S->nb_sysinclude_paths);
207 print_dirs("libraries", s->library_paths, s->nb_library_paths);207 print_dirs("libraries", S->library_paths, S->nb_library_paths);
208#ifdef TCC_TARGET_PE208#ifdef TCC_TARGET_PE
209 printf("libtcc1:\n %s/lib/"TCC_LIBTCC1"\n", s->tcc_lib_path);209 printf("libtcc1:\n %s/lib/"TCC_LIBTCC1"\n", S->tcc_lib_path);
210#else210#else
211 printf("libtcc1:\n %s/"TCC_LIBTCC1"\n", s->tcc_lib_path);211 printf("libtcc1:\n %s/"TCC_LIBTCC1"\n", S->tcc_lib_path);
212 print_dirs("crt", s->crt_paths, s->nb_crt_paths);212 print_dirs("crt", S->crt_paths, S->nb_crt_paths);
213 printf("elfinterp:\n %s\n", DEFAULT_ELFINTERP(s));213 printf("elfinterp:\n %s\n", DEFAULT_ELFINTERP(S));
214#endif214#endif
215}215}
216 216
217static void set_environment(TCCState *s)217static void set_environment(TCCState *S)
218{218{
219 char * path;219 char * path;
220 220
221 path = getenv("C_INCLUDE_PATH");221 path = getenv("C_INCLUDE_PATH");
222 if(path != NULL) {222 if(path != NULL) {
223 tcc_add_sysinclude_path(s, path);223 tcc_add_sysinclude_path(S, path);
224 }224 }
225 path = getenv("CPATH");225 path = getenv("CPATH");
226 if(path != NULL) {226 if(path != NULL) {
227 tcc_add_include_path(s, path);227 tcc_add_include_path(S, path);
228 }228 }
229 path = getenv("LIBRARY_PATH");229 path = getenv("LIBRARY_PATH");
230 if(path != NULL) {230 if(path != NULL) {
231 tcc_add_library_path(s, path);231 tcc_add_library_path(S, path);
232 }232 }
233}233}
234 234
235static char *default_outputfile(TCCState *s, const char *first_file)235static char *default_outputfile(TCCState *S, const char *first_file)
236{236{
237 char buf[1024];237 char buf[1024];
238 char *ext;238 char *ext;
@@ -243,18 +243,18 @@ static char *default_outputfile(TCCState *s, const char *first_file) · 4 unmodified lines
243 snprintf(buf, sizeof(buf), "%s", name);243 snprintf(buf, sizeof(buf), "%s", name);
244 ext = tcc_fileextension(buf);244 ext = tcc_fileextension(buf);
245#ifdef TCC_TARGET_PE245#ifdef TCC_TARGET_PE
246 if (s->output_type == TCC_OUTPUT_DLL)246 if (S->output_type == TCC_OUTPUT_DLL)
247 strcpy(ext, ".dll");247 strcpy(ext, ".dll");
248 else248 else
249 if (s->output_type == TCC_OUTPUT_EXE)249 if (S->output_type == TCC_OUTPUT_EXE)
250 strcpy(ext, ".exe");250 strcpy(ext, ".exe");
251 else251 else
252#endif252#endif
253 if ((s->just_deps || s->output_type == TCC_OUTPUT_OBJ) && !s->option_r && *ext)253 if ((S->just_deps || S->output_type == TCC_OUTPUT_OBJ) && !S->option_r && *ext)
254 strcpy(ext, ".o");254 strcpy(ext, ".o");
255 else255 else
256 strcpy(buf, "a.out");256 strcpy(buf, "a.out");
257 return tcc_strdup(buf);257 return tcc_strdup(S, buf);
258}258}
259 259
260static unsigned getclock_ms(void)260static unsigned getclock_ms(void)
@@ -268,9 +268,101 @@ static unsigned getclock_ms(void) · 7 unmodified lines
268#endif268#endif
269}269}
270 270
271#ifdef WITH_ATTACHMENTS
272#include "tcc_attachments.h"
273#define ATTACH_PREFIX "/_attach_"
274
275static vio_module_t vio_module;
276
277typedef struct vio_memfile_t {
278 off_t size;
279 off_t pos;
280 const unsigned char *mem;
281} vio_memfile_t;
282
283static int vio_mem_open(vio_fd *fd, const char *fn, int oflag) {
284 //printf("%d:%s\n", fd->fd, fn);
285 if(fd->vio_module && strncmp(ATTACH_PREFIX, fn, sizeof(ATTACH_PREFIX)-1) == 0){
286 int i, count = sizeof(bin2c_filesAttached)/sizeof(bin2c_filesAttached_st);
287 for(i=0; i < count; ++i) {
288 //printf("%s:%s\n", fn, bin2c_filesAttached[i].file_name);
289 if(strcmp(fn, bin2c_filesAttached[i].file_name) == 0) {
290 vio_memfile_t *mf = (vio_memfile_t*)tcc_malloc(S, fd->vio_module->tcc_state);
291 mf->mem = bin2c_filesAttached[i].sym_name;
292 mf->size = bin2c_filesAttached[i].size;
293 mf->pos = 0;
294 fd->fd = 1;
295 fd->vio_udata = mf;
296 //printf("%d:%s\n", fd->fd, fn);
297 return fd->fd;
298 }
299 }
300 }
301 return -1;
302}
303
304static off_t vio_mem_lseek(vio_fd fd, off_t offset, int whence) {
305 if(fd.vio_udata) {
306 off_t loffset = 0;
307 vio_memfile_t *mf = (vio_memfile_t*)fd.vio_udata;
308 if (whence == SEEK_CUR)
309 loffset = mf->pos + offset;
310 else if (whence == SEEK_SET)
311 loffset = offset;
312 else if (whence == SEEK_END)
313 loffset = ((off_t)mf->size) + offset;
314
315 if (loffset < 0 && loffset > mf->size)
316 return -1;
317
318 mf->pos = loffset;
319
320 return mf->pos;
321 }
322 return lseek(fd.fd, offset, whence);
323}
324
325static size_t vio_mem_read(vio_fd fd, void *buf, size_t bytes) {
326 if(fd.vio_udata) {
327 vio_memfile_t *mf = (vio_memfile_t*)fd.vio_udata;
328 if( (mf->pos + bytes) > mf->size) {
329 long bc = mf->size - mf->pos;
330 if(bc > 0) {
331 memcpy(buf, mf->mem + mf->pos, bc);
332 mf->pos = mf->size;
333 return bc;
334 }
335 return 0;
336 }
337 memcpy(buf, mf->mem + mf->pos, bytes);
338 mf->pos += bytes;
339 return bytes;
340 }
341 return 0;
342}
343
344static int vio_mem_close(vio_fd *fd) {
345 if(fd->vio_udata){
346 tcc_free(S, fd->vio_udata);
347 }
348 return 0;
349}
350
351void set_vio_module(TCCState *S){
352 vio_module.user_data = NULL;
353 vio_module.call_vio_open_flags = CALL_VIO_OPEN_FIRST;
354 vio_module.vio_open = &vio_mem_open;
355 vio_module.vio_lseek = &vio_mem_lseek;
356 vio_module.vio_read = &vio_mem_read;
357 vio_module.vio_close = &vio_mem_close;
358 tcc_set_vio_module(s, &vio_module);
359}
360
361#endif
362
271int main(int argc0, char **argv0)363int main(int argc0, char **argv0)
272{364{
273 TCCState *s, *s1;365 TCCState *S, *s1;
274 int ret, opt, n = 0, t = 0, done;366 int ret, opt, n = 0, t = 0, done;
275 unsigned start_time = 0, end_time = 0;367 unsigned start_time = 0, end_time = 0;
276 const char *first_file;368 const char *first_file;
@@ -279,13 +371,19 @@ int main(int argc0, char **argv0) · 2 unmodified lines
279 371
280redo:372redo:
281 argc = argc0, argv = argv0;373 argc = argc0, argv = argv0;
282 s = s1 = tcc_new();374 S = s1 = tcc_new();
283 opt = tcc_parse_args(s, &argc, &argv, 1);375 opt = tcc_parse_args(S, &argc, &argv, 1);
376
377#ifdef WITH_ATTACHMENTS
378 tcc_set_lib_path(S, ATTACH_PREFIX);
379 tcc_add_include_path(S, ATTACH_PREFIX);
380 set_vio_module(S);
381#endif
284 382
285 if (n == 0) {383 if (n == 0) {
286 if (opt == OPT_HELP) {384 if (opt == OPT_HELP) {
287 fputs(help, stdout);385 fputs(help, stdout);
288 if (!s->verbose)386 if (!S->verbose)
289 return 0;387 return 0;
290 ++opt;388 ++opt;
291 }389 }
@@ -294,57 +392,57 @@ redo: · 2 unmodified lines
294 return 0;392 return 0;
295 }393 }
296 if (opt == OPT_M32 || opt == OPT_M64)394 if (opt == OPT_M32 || opt == OPT_M64)
297 tcc_tool_cross(s, argv, opt); /* never returns */395 tcc_tool_cross(S, argv, opt); /* never returns */
298 if (s->verbose)396 if (S->verbose)
299 printf(version);397 printf(version);
300 if (opt == OPT_AR)398 if (opt == OPT_AR)
301 return tcc_tool_ar(s, argc, argv);399 return tcc_tool_ar(S, argc, argv);
302#ifdef TCC_TARGET_PE400#ifdef TCC_TARGET_PE
303 if (opt == OPT_IMPDEF)401 if (opt == OPT_IMPDEF)
304 return tcc_tool_impdef(s, argc, argv);402 return tcc_tool_impdef(S, argc, argv);
305#endif403#endif
306 if (opt == OPT_V)404 if (opt == OPT_V)
307 return 0;405 return 0;
308 if (opt == OPT_PRINT_DIRS) {406 if (opt == OPT_PRINT_DIRS) {
309 /* initialize search dirs */407 /* initialize search dirs */
310 set_environment(s);408 set_environment(S);
311 tcc_set_output_type(s, TCC_OUTPUT_MEMORY);409 tcc_set_output_type(S, TCC_OUTPUT_MEMORY);
312 print_search_dirs(s);410 print_search_dirs(S);
313 return 0;411 return 0;
314 }412 }
315 413
316 if (s->nb_files == 0)414 if (S->nb_files == 0)
317 tcc_error("no input files");415 tcc_error(S, "no input files");
318 416
319 if (s->output_type == TCC_OUTPUT_PREPROCESS) {417 if (S->output_type == TCC_OUTPUT_PREPROCESS) {
320 if (s->outfile && 0!=strcmp("-",s->outfile)) {418 if (S->outfile && 0!=strcmp("-",S->outfile)) {
321 ppfp = fopen(s->outfile, "w");419 ppfp = fopen(S->outfile, "w");
322 if (!ppfp)420 if (!ppfp)
323 tcc_error("could not write '%s'", s->outfile);421 tcc_error(S, "could not write '%s'", S->outfile);
324 }422 }
325 } else if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) {423 } else if (S->output_type == TCC_OUTPUT_OBJ && !S->option_r) {
326 if (s->nb_libraries)424 if (S->nb_libraries)
327 tcc_error("cannot specify libraries with -c");425 tcc_error(S, "cannot specify libraries with -c");
328 if (s->nb_files > 1 && s->outfile)426 if (S->nb_files > 1 && S->outfile)
329 tcc_error("cannot specify output file with -c many files");427 tcc_error(S, "cannot specify output file with -c many files");
330 }428 }
331 429
332 if (s->do_bench)430 if (S->do_bench)
333 start_time = getclock_ms();431 start_time = getclock_ms();
334 }432 }
335 433
336 set_environment(s);434 set_environment(S);
337 if (s->output_type == 0)435 if (S->output_type == 0)
338 s->output_type = TCC_OUTPUT_EXE;436 S->output_type = TCC_OUTPUT_EXE;
339 tcc_set_output_type(s, s->output_type);437 tcc_set_output_type(S, S->output_type);
340 s->ppfp = ppfp;438 S->ppfp = ppfp;
341 439
342 if ((s->output_type == TCC_OUTPUT_MEMORY440 if ((S->output_type == TCC_OUTPUT_MEMORY
343 || s->output_type == TCC_OUTPUT_PREPROCESS)441 || S->output_type == TCC_OUTPUT_PREPROCESS)
344 && (s->dflag & 16)) { /* -dt option */442 && (S->dflag & TCC_OPTION_d_t)) { /* -dt option */
345 if (t)443 if (t)
346 s->dflag |= 32;444 S->dflag |= TCC_OPTION_d_32;
347 s->run_test = ++t;445 S->run_test = ++t;
348 if (n)446 if (n)
349 --n;447 --n;
350 }448 }
@@ -352,48 +450,48 @@ redo: · 1 unmodified line
352 /* compile or add each files or library */450 /* compile or add each files or library */
353 first_file = NULL, ret = 0;451 first_file = NULL, ret = 0;
354 do {452 do {
355 struct filespec *f = s->files[n];453 struct filespec *f = S->files[n];
356 s->filetype = f->type;454 S->filetype = f->type;
357 if (f->type & AFF_TYPE_LIB) {455 if (f->type & AFF_TYPE_LIB) {
358 if (tcc_add_library_err(s, f->name) < 0)456 if (tcc_add_library_err(S, f->name) < 0)
359 ret = 1;457 ret = 1;
360 } else {458 } else {
361 if (1 == s->verbose)459 if (1 == S->verbose)
362 printf("-> %s\n", f->name);460 printf("-> %s\n", f->name);
363 if (!first_file)461 if (!first_file)
364 first_file = f->name;462 first_file = f->name;
365 if (tcc_add_file(s, f->name) < 0)463 if (tcc_add_file(S, f->name) < 0)
366 ret = 1;464 ret = 1;
367 }465 }
368 done = ret || ++n >= s->nb_files;466 done = ret || ++n >= S->nb_files;
369 } while (!done && (s->output_type != TCC_OUTPUT_OBJ || s->option_r));467 } while (!done && (S->output_type != TCC_OUTPUT_OBJ || S->option_r));
370 468
371 if (s->do_bench)469 if (S->do_bench)
372 end_time = getclock_ms();470 end_time = getclock_ms();
373 471
374 if (s->run_test) {472 if (S->run_test) {
375 t = 0;473 t = 0;
376 } else if (s->output_type == TCC_OUTPUT_PREPROCESS) {474 } else if (S->output_type == TCC_OUTPUT_PREPROCESS) {
377 ;475 ;
378 } else if (0 == ret) {476 } else if (0 == ret) {
379 if (s->output_type == TCC_OUTPUT_MEMORY) {477 if (S->output_type == TCC_OUTPUT_MEMORY) {
380#ifdef TCC_IS_NATIVE478#ifdef TCC_IS_NATIVE
381 ret = tcc_run(s, argc, argv);479 ret = tcc_run(S, argc, argv);
382#endif480#endif
383 } else {481 } else {
384 if (!s->outfile)482 if (!S->outfile)
385 s->outfile = default_outputfile(s, first_file);483 S->outfile = default_outputfile(S, first_file);
386 if (!s->just_deps && tcc_output_file(s, s->outfile))484 if (!S->just_deps && tcc_output_file(S, S->outfile))
387 ret = 1;485 ret = 1;
388 else if (s->gen_deps)486 else if (S->gen_deps)
389 gen_makedeps(s, s->outfile, s->deps_outfile);487 gen_makedeps(S, S->outfile, S->deps_outfile);
390 }488 }
391 }489 }
392 490
393 if (done && 0 == t && 0 == ret && s->do_bench)491 if (done && 0 == t && 0 == ret && S->do_bench)
394 tcc_print_stats(s, end_time - start_time);492 tcc_print_stats(S, end_time - start_time);
395 493
396 tcc_delete(s);494 tcc_delete(S);
397 if (!done)495 if (!done)
398 goto redo; /* compile more files with -c */496 goto redo; /* compile more files with -c */
399 if (t)497 if (t)
tcc.h+458−299
@@ -585,7 +585,7 @@ typedef struct Section { · 584 unmodified lines
585 unsigned long data_offset; /* current data offset */585 unsigned long data_offset; /* current data offset */
586 unsigned char *data; /* section data */586 unsigned char *data; /* section data */
587 unsigned long data_allocated; /* used for realloc() handling */587 unsigned long data_allocated; /* used for realloc() handling */
588 TCCState *s1;588 TCCState *S;
589 int sh_name; /* elf section name (only used during output) */589 int sh_name; /* elf section name (only used during output) */
590 int sh_num; /* elf section number */590 int sh_num; /* elf section number */
591 int sh_type; /* elf section type */591 int sh_type; /* elf section type */
@@ -743,6 +743,78 @@ struct sym_attr { · 151 unmodified lines
743#endif743#endif
744};744};
745 745
746/*From tccpp.c*/
747typedef struct TinyAlloc {
748 unsigned limit;
749 unsigned size;
750 uint8_t *buffer;
751 uint8_t *p;
752 unsigned nb_allocs;
753 struct TinyAlloc *next, *top;
754#ifdef TAL_INFO
755 unsigned nb_peak;
756 unsigned nb_total;
757 unsigned nb_missed;
758 uint8_t *peak_p;
759#endif
760} TinyAlloc;
761
762/*From tccgen.c*/
763typedef struct scope_t {
764 struct scope_t *prev;
765 struct { int loc, locorig, num; } vla;
766 struct { Sym *s; int n; } cl;
767 int *bsym, *csym;
768 Sym *lstk, *llstk;
769} scope_t;
770
771typedef struct switch_t {
772 struct case_t {
773 int64_t v1, v2;
774 int sym;
775 } **p; int n; /* list of case ranges */
776 int def_sym; /* default symbol */
777 int *bsym;
778 scope_t *scope;
779 struct switch_t *prev;
780 SValue sv;
781} switch_t;
782
783#define MAX_TEMP_LOCAL_VARIABLE_NUMBER 8
784/*list of temporary local variables on the stack in current function. */
785typedef struct temp_local_variable_t {
786 int location; //offset on stack. Svalue.c.i
787 short size;
788 short align;
789} temp_local_variable_t;
790
791typedef struct {
792 unsigned long offset;
793 unsigned long last_file_name;
794 unsigned long last_func_name;
795 int ind;
796 int line;
797} tcov_data_t;
798
799typedef struct {
800 int debug_type;
801 Sym *type;
802} debug_hash_t;
803
804typedef struct debug_info_t {
805 int start;
806 int end;
807 int n_sym;
808 struct debug_sym {
809 int type;
810 unsigned long value;
811 char *str;
812 Section *sec;
813 int sym_index;
814 } *sym;
815 struct debug_info_t *child, *next, *last, *parent;
816} debug_info_t;
817
746struct TCCState {818struct TCCState {
747 unsigned char verbose; /* if true, display some information during compilation */819 unsigned char verbose; /* if true, display some information during compilation */
748 unsigned char nostdinc; /* if true, no standard headers are added */820 unsigned char nostdinc; /* if true, no standard headers are added */
@@ -927,11 +999,11 @@ struct TCCState { · 178 unmodified lines
927 int nb_sym_attrs;999 int nb_sym_attrs;
928 /* ptr to next reloc entry reused */1000 /* ptr to next reloc entry reused */
929 ElfW_Rel *qrel;1001 ElfW_Rel *qrel;
930 #define qrel s1->qrel1002 #define qrel S->qrel
931 1003
932#ifdef TCC_TARGET_RISCV641004#ifdef TCC_TARGET_RISCV64
933 struct pcrel_hi { addr_t addr, val; } last_hi;1005 struct pcrel_hi { addr_t addr, val; } last_hi;
934 #define last_hi s1->last_hi1006 #define last_hi S->last_hi
935#endif1007#endif
936 1008
937#ifdef TCC_TARGET_PE1009#ifdef TCC_TARGET_PE
@@ -962,6 +1034,10 @@ struct TCCState { · 24 unmodified lines
962 const char *runtime_main;1034 const char *runtime_main;
963 void **runtime_mem;1035 void **runtime_mem;
964 int nb_runtime_mem;1036 int nb_runtime_mem;
1037# ifdef HAVE_SELINUX
1038 void *write_mem;
1039 unsigned long mem_size;
1040# endif
965#endif1041#endif
966 1042
967#ifdef CONFIG_TCC_BACKTRACE1043#ifdef CONFIG_TCC_BACKTRACE
@@ -991,6 +1067,117 @@ struct TCCState { · 23 unmodified lines
991 char *deps_outfile; /* option -MF */1067 char *deps_outfile; /* option -MF */
992 int argc;1068 int argc;
993 char **argv;1069 char **argv;
1070
1071 /* Entries needed to make it reentrant */
1072 vio_module_t *vio_module;
1073
1074 /* ------------ tccpp.c ------------ */
1075
1076 struct BufferedFile *tccpp_file;
1077 int tccpp_ch, tccpp_tok;
1078 CValue tccpp_tokc;
1079 const int *tccpp_macro_ptr;
1080 int tccpp_parse_flags;
1081 int tccpp_tok_flags;
1082 CString tccpp_tokcstr; /* current parsed string, if any */
1083 CString tccpp_cstr_buf;
1084 CString tccpp_macro_equal_buf;
1085 TokenString tccpp_tokstr_buf;
1086 TokenString *tccpp_macro_stack;
1087
1088 /* display benchmark infos */
1089 int tccpp_total_lines;
1090 int tccpp_total_bytes;
1091 int tccpp_tok_ident;
1092 TokenSym **tccpp_table_ident;
1093
1094 int *tccpp_macro_ptr_allocated;
1095 const int *tccpp_unget_saved_macro_ptr;
1096 int tccpp_unget_saved_buffer[TOK_MAX_SIZE + 1];
1097 int tccpp_unget_buffer_enabled;
1098 TokenSym *tccpp_hash_ident[TOK_HASH_SIZE];
1099 char tccpp_token_buf[STRING_MAX_SIZE + 1];
1100 /* true if isid(c) || isnum(c) */
1101 unsigned char tccpp_isidnum_table[256-CH_EOF];
1102
1103 int tccpp_pp_debug_tok, tccpp_pp_debug_symv;
1104 int tccpp_pp_once;
1105 int tccpp_pp_expr;
1106 int tccpp_pp_counter;
1107
1108 TinyAlloc *tccpp_toksym_alloc;
1109 TinyAlloc *tccpp_tokstr_alloc;
1110
1111 /*----------- tccasm.c --------*/
1112 Section *tccasm_last_text_section; /* to handle .previous asm directive */
1113
1114 /* ------------ tccgen.c ------------ */
1115
1116 Sym *tccgen_global_stack;
1117 Sym *tccgen_local_stack;
1118 Sym *tccgen_local_label_stack;
1119 Sym *tccgen_global_label_stack;
1120 Sym *tccgen_define_stack;
1121 CType tccgen_int_type, tccgen_func_old_type, tccgen_char_type, tccgen_char_pointer_type;
1122 SValue *tccgen_vtop;
1123 SValue tccgen__vstack[1 + VSTACK_SIZE];
1124 int tccgen_rsym, tccgen_anon_sym, tccgen_ind, tccgen_loc;
1125 char tccgen_debug_modes;
1126
1127 int tccgen_const_wanted; /* true if constant wanted */
1128 int tccgen_nocode_wanted; /* true if no code generation wanted for an expression */
1129 int tccgen_global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
1130 CType tccgen_func_vt; /* current function return type (used by return instruction) */
1131 int tccgen_func_var; /* true if current function is variadic */
1132 int tccgen_func_vc;
1133 const char *tccgen_funcname;
1134
1135 Sym *tccgen_sym_free_first;
1136 void **tccgen_sym_pools;
1137 int tccgen_nb_sym_pools;
1138 Sym *tccgen_all_cleanups, *tccgen_pending_gotos;
1139 int tccgen_local_scope;
1140 int tccgen_in_sizeof;
1141 int tccgen_in_generic;
1142 int tccgen_section_sym;
1143
1144 int tccgen_last_line_num, tccgen_new_file, tccgen_func_ind; /* debug info control */
1145 CString tccgen_initstr;
1146
1147 switch_t *tccgen_cur_switch; /* current switch */
1148
1149 temp_local_variable_t tccgen_arr_temp_local_vars[MAX_TEMP_LOCAL_VARIABLE_NUMBER];
1150 int tccgen_nb_temp_local_vars;
1151
1152 scope_t *tccgen_cur_scope, *tccgen_loop_scope, *tccgen_root_scope;
1153
1154 tcov_data_t tccgen_tcov_data;
1155 int tccgen_debug_next_type;
1156 debug_hash_t *tccgen_debug_hash;
1157 int tccgen_n_debug_hash;
1158 debug_info_t *tccgen_debug_info, *tccgen_debug_info_root;
1159
1160 unsigned char tccgen_prec[256];
1161
1162 /*--------armg-gen.c-----------*/
1163/*#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)*/
1164 CType armgen_float_type, armgen_double_type, armgen_func_float_type, armgen_func_double_type;
1165/*#endif*/
1166
1167 /*------- tccrun.c ------------*/
1168
1169 /*--------x86_64-gen.c --------*/
1170 unsigned long x86_64_gen_func_sub_sp_offset;
1171 int x86_64_gen_func_ret_sub;
1172#if defined(CONFIG_TCC_BCHECK)
1173 addr_t func_bound_offset;
1174 unsigned long func_bound_ind;
1175 int func_bound_add_epilog;
1176#endif
1177#ifdef TCC_TARGET_PE
1178 int x86_64_gen_func_scratch, x86_64_gen_func_alloca;
1179#endif
1180
994};1181};
995 1182
996struct filespec {1183struct filespec {
@@ -1174,7 +1361,7 @@ enum tcc_token { · 177 unmodified lines
1174 1361
1175/* ------------ libtcc.c ------------ */1362/* ------------ libtcc.c ------------ */
1176 1363
1177ST_DATA struct TCCState *tcc_state;1364//ST_DATA struct TCCState *S;
1178 1365
1179/* public functions currently used by the tcc main function */1366/* public functions currently used by the tcc main function */
1180ST_FUNC char *pstrcpy(char *buf, size_t buf_size, const char *s);1367ST_FUNC char *pstrcpy(char *buf, size_t buf_size, const char *s);
@@ -1183,53 +1370,56 @@ ST_FUNC char *pstrncpy(char *out, const char *in, size_t num); · 2 unmodified lines
1183PUB_FUNC char *tcc_basename(const char *name);1370PUB_FUNC char *tcc_basename(const char *name);
1184PUB_FUNC char *tcc_fileextension (const char *name);1371PUB_FUNC char *tcc_fileextension (const char *name);
1185 1372
1373PUB_FUNC void tcc_free_base(void *ptr);
1374PUB_FUNC void *tcc_malloc_base(unsigned long size);
1375PUB_FUNC void *tcc_mallocz_base(unsigned long size);
1186#ifndef MEM_DEBUG1376#ifndef MEM_DEBUG
1187PUB_FUNC void tcc_free(void *ptr);1377PUB_FUNC void tcc_free(TCCState* S, void *ptr);
1188PUB_FUNC void *tcc_malloc(unsigned long size);1378PUB_FUNC void *tcc_malloc(TCCState* S, unsigned long size);
1189PUB_FUNC void *tcc_mallocz(unsigned long size);1379PUB_FUNC void *tcc_mallocz(TCCState* S, unsigned long size);
1190PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size);1380PUB_FUNC void *tcc_realloc(TCCState* S, void *ptr, unsigned long size);
1191PUB_FUNC char *tcc_strdup(const char *str);1381PUB_FUNC char *tcc_strdup(TCCState* S, const char *str);
1192#else1382#else
1193#define tcc_free(ptr) tcc_free_debug(ptr)1383#define tcc_free(s, ptr) tcc_free_debug(s, ptr)
1194#define tcc_malloc(size) tcc_malloc_debug(size, __FILE__, __LINE__)1384#define tcc_malloc(s, size) tcc_malloc_debug(s, size, __FILE__, __LINE__)
1195#define tcc_mallocz(size) tcc_mallocz_debug(size, __FILE__, __LINE__)1385#define tcc_mallocz(s, size) tcc_mallocz_debug(s, size, __FILE__, __LINE__)
1196#define tcc_realloc(ptr,size) tcc_realloc_debug(ptr, size, __FILE__, __LINE__)1386#define tcc_realloc(s, ptr, size) tcc_realloc_debug(s, ptr, size, __FILE__, __LINE__)
1197#define tcc_strdup(str) tcc_strdup_debug(str, __FILE__, __LINE__)1387#define tcc_strdup(s, str) tcc_strdup_debug(s, str, __FILE__, __LINE__)
1198PUB_FUNC void tcc_free_debug(void *ptr);1388PUB_FUNC void tcc_free_debug(TCCState* S, void *ptr);
1199PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line);1389PUB_FUNC void *tcc_malloc_debug(TCCState* S, unsigned long size, const char *file, int line);
1200PUB_FUNC void *tcc_mallocz_debug(unsigned long size, const char *file, int line);1390PUB_FUNC void *tcc_mallocz_debug(TCCState* S, unsigned long size, const char *file, int line);
1201PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file, int line);1391PUB_FUNC void *tcc_realloc_debug(TCCState* S, void *ptr, unsigned long size, const char *file, int line);
1202PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line);1392PUB_FUNC char *tcc_strdup_debug(TCCState* S, const char *str, const char *file, int line);
1203#endif1393#endif
1204 1394
1205#define free(p) use_tcc_free(p)1395#define free(p) use_tcc_free(S, p)
1206#define malloc(s) use_tcc_malloc(s)1396#define malloc(s) use_tcc_malloc(S, s)
1207#define realloc(p, s) use_tcc_realloc(p, s)1397#define realloc(p, s) use_tcc_realloc(S, p, s)
1208#undef strdup1398#undef strdup
1209#define strdup(s) use_tcc_strdup(s)1399#define strdup(s) use_tcc_strdup(S, s)
1210PUB_FUNC void _tcc_error_noabort(const char *fmt, ...) PRINTF_LIKE(1,2);1400PUB_FUNC void _tcc_error_noabort(TCCState* S, const char *fmt, ...) PRINTF_LIKE(2,3);
1211PUB_FUNC NORETURN void _tcc_error(const char *fmt, ...) PRINTF_LIKE(1,2);1401PUB_FUNC NORETURN void _tcc_error(TCCState* S, const char *fmt, ...) PRINTF_LIKE(2,3);
1212PUB_FUNC void _tcc_warning(const char *fmt, ...) PRINTF_LIKE(1,2);1402PUB_FUNC void _tcc_warning(TCCState* S, const char *fmt, ...) PRINTF_LIKE(2,3);
1213#define tcc_internal_error(msg) tcc_error("internal compiler error\n"\1403#define tcc_internal_error(S, msg) tcc_error(S, "internal compiler error\n"\
1214 "%s:%d: in %s(): " msg, __FILE__,__LINE__,__FUNCTION__)1404 "%s:%d: in %s(): " msg, __FILE__,__LINE__,__FUNCTION__)
1215 1405
1216/* other utilities */1406/* other utilities */
1217ST_FUNC void dynarray_add(void *ptab, int *nb_ptr, void *data);1407ST_FUNC void dynarray_add(TCCState* S, void *ptab, int *nb_ptr, void *data);
1218ST_FUNC void dynarray_reset(void *pp, int *n);1408ST_FUNC void dynarray_reset(TCCState* S, void *pp, int *n);
1219ST_INLN void cstr_ccat(CString *cstr, int ch);1409ST_INLN void cstr_ccat(TCCState* S, CString *cstr, int ch);
1220ST_FUNC void cstr_cat(CString *cstr, const char *str, int len);1410ST_FUNC void cstr_cat(TCCState* S, CString *cstr, const char *str, int len);
1221ST_FUNC void cstr_wccat(CString *cstr, int ch);1411ST_FUNC void cstr_wccat(TCCState* S, CString *cstr, int ch);
1222ST_FUNC void cstr_new(CString *cstr);1412ST_FUNC void cstr_new(TCCState* S, CString *cstr);
1223ST_FUNC void cstr_free(CString *cstr);1413ST_FUNC void cstr_free(TCCState* S, CString *cstr);
1224ST_FUNC int cstr_printf(CString *cs, const char *fmt, ...) PRINTF_LIKE(2,3);1414ST_FUNC int cstr_printf(TCCState* S, CString *cs, const char *fmt, ...) PRINTF_LIKE(3,4);
1225ST_FUNC int cstr_vprintf(CString *cstr, const char *fmt, va_list ap);1415ST_FUNC int cstr_vprintf(TCCState* S, CString *cstr, const char *fmt, va_list ap);
1226ST_FUNC void cstr_reset(CString *cstr);1416ST_FUNC void cstr_reset(CString *cstr);
1227 1417
1228ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen);1418ST_FUNC void tcc_open_bf(TCCState *S, const char *filename, int initlen);
1229ST_FUNC int tcc_open(TCCState *s1, const char *filename);1419ST_FUNC int tcc_open(TCCState *S, const char *filename);
1230ST_FUNC void tcc_close(void);1420ST_FUNC void tcc_close(TCCState *S);
1231 1421
1232ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags);1422ST_FUNC int tcc_add_file_internal(TCCState *S, const char *filename, int flags);
1233/* flags: */1423/* flags: */
1234#define AFF_PRINT_ERROR 0x10 /* print error if file not found */1424#define AFF_PRINT_ERROR 0x10 /* print error if file not found */
1235#define AFF_REFERENCED_DLL 0x20 /* load a referenced dll from another dll */1425#define AFF_REFERENCED_DLL 0x20 /* load a referenced dll from another dll */
@@ -1249,26 +1439,26 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 13 unmodified lines
1249#define AFF_BINTYPE_C67 41439#define AFF_BINTYPE_C67 4
1250 1440
1251#ifndef ELF_OBJ_ONLY1441#ifndef ELF_OBJ_ONLY
1252ST_FUNC int tcc_add_crt(TCCState *s, const char *filename);1442ST_FUNC int tcc_add_crt(TCCState *S, const char *filename);
1253#endif1443#endif
1254#ifndef TCC_TARGET_MACHO1444#ifndef TCC_TARGET_MACHO
1255ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags);1445ST_FUNC int tcc_add_dll(TCCState *S, const char *filename, int flags);
1256#endif1446#endif
1257#ifdef CONFIG_TCC_BCHECK1447#ifdef CONFIG_TCC_BCHECK
1258ST_FUNC void tcc_add_bcheck(TCCState *s1);1448ST_FUNC void tcc_add_bcheck(TCCState *S);
1259#endif1449#endif
1260#ifdef CONFIG_TCC_BACKTRACE1450#ifdef CONFIG_TCC_BACKTRACE
1261ST_FUNC void tcc_add_btstub(TCCState *s1);1451ST_FUNC void tcc_add_btstub(TCCState *S);
1262#endif1452#endif
1263ST_FUNC void tcc_add_pragma_libs(TCCState *s1);1453ST_FUNC void tcc_add_pragma_libs(TCCState *S);
1264PUB_FUNC int tcc_add_library_err(TCCState *s, const char *f);1454PUB_FUNC int tcc_add_library_err(TCCState *S, const char *f);
1265PUB_FUNC void tcc_print_stats(TCCState *s, unsigned total_time);1455PUB_FUNC void tcc_print_stats(TCCState *S, unsigned total_time);
1266PUB_FUNC int tcc_parse_args(TCCState *s, int *argc, char ***argv, int optind);1456PUB_FUNC int tcc_parse_args(TCCState *S, int *argc, char ***argv, int optind);
1267#ifdef _WIN321457#ifdef _WIN32
1268ST_FUNC char *normalize_slashes(char *path);1458ST_FUNC char *normalize_slashes(char *path);
1269#endif1459#endif
1270ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllname);1460ST_FUNC DLLReference *tcc_add_dllref(TCCState *S, const char *dllname);
1271ST_FUNC char *tcc_load_text(int fd);1461ST_FUNC char *tcc_load_text(TCCState *S, int fd);
1272 1462
1273/* tcc_parse_args return codes: */1463/* tcc_parse_args return codes: */
1274#define OPT_HELP 11464#define OPT_HELP 1
@@ -1282,18 +1472,6 @@ ST_FUNC char *tcc_load_text(int fd); · 7 unmodified lines
1282 1472
1283/* ------------ tccpp.c ------------ */1473/* ------------ tccpp.c ------------ */
1284 1474
1285ST_DATA struct BufferedFile *file;
1286ST_DATA int ch, tok;
1287ST_DATA CValue tokc;
1288ST_DATA const int *macro_ptr;
1289ST_DATA int parse_flags;
1290ST_DATA int tok_flags;
1291ST_DATA CString tokcstr; /* current parsed string, if any */
1292
1293/* display benchmark infos */
1294ST_DATA int tok_ident;
1295ST_DATA TokenSym **table_ident;
1296
1297#define TOK_FLAG_BOL 0x0001 /* beginning of line before */1475#define TOK_FLAG_BOL 0x0001 /* beginning of line before */
1298#define TOK_FLAG_BOF 0x0002 /* beginning of file before */1476#define TOK_FLAG_BOF 0x0002 /* beginning of file before */
1299#define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */1477#define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
@@ -1321,36 +1499,36 @@ enum line_macro_output_format { · 21 unmodified lines
1321 LINE_MACRO_OUTPUT_FORMAT_P10 = 111499 LINE_MACRO_OUTPUT_FORMAT_P10 = 11
1322};1500};
1323 1501
1324ST_FUNC TokenSym *tok_alloc(const char *str, int len);1502ST_FUNC TokenSym *tok_alloc(TCCState* S, const char *str, int len);
1325ST_FUNC int tok_alloc_const(const char *str);1503ST_FUNC int tok_alloc_const(TCCState* S, const char *str);
1326ST_FUNC const char *get_tok_str(int v, CValue *cv);1504ST_FUNC const char *get_tok_str(TCCState* S, int v, CValue *cv);
1327ST_FUNC void begin_macro(TokenString *str, int alloc);1505ST_FUNC void begin_macro(TCCState* S, TokenString *str, int alloc);
1328ST_FUNC void end_macro(void);1506ST_FUNC void end_macro(TCCState* S);
1329ST_FUNC int set_idnum(int c, int val);1507ST_FUNC int set_idnum(TCCState* S, int c, int val);
1330ST_INLN void tok_str_new(TokenString *s);1508ST_INLN void tok_str_new(TokenString *s);
1331ST_FUNC TokenString *tok_str_alloc(void);1509ST_FUNC TokenString *tok_str_alloc(TCCState* S);
1332ST_FUNC void tok_str_free(TokenString *s);1510ST_FUNC void tok_str_free(TCCState* S, TokenString *s);
1333ST_FUNC void tok_str_free_str(int *str);1511ST_FUNC void tok_str_free_str(TCCState* S, int *str);
1334ST_FUNC void tok_str_add(TokenString *s, int t);1512ST_FUNC void tok_str_add(TCCState* S, TokenString *s, int t);
1335ST_FUNC void tok_str_add_tok(TokenString *s);1513ST_FUNC void tok_str_add_tok(TCCState* S, TokenString *s);
1336ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg);1514ST_INLN void define_push(TCCState* S, int v, int macro_type, int *str, Sym *first_arg);
1337ST_FUNC void define_undef(Sym *s);1515ST_FUNC void define_undef(TCCState* S, Sym *s);
1338ST_INLN Sym *define_find(int v);1516ST_INLN Sym *define_find(TCCState* S, int v);
1339ST_FUNC void free_defines(Sym *b);1517ST_FUNC void free_defines(TCCState* S, Sym *b);
1340ST_FUNC Sym *label_find(int v);1518ST_FUNC Sym *label_find(TCCState* S, int v);
1341ST_FUNC Sym *label_push(Sym **ptop, int v, int flags);1519ST_FUNC Sym *label_push(TCCState* S, Sym **ptop, int v, int flags);
1342ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep);1520ST_FUNC void label_pop(TCCState* S, Sym **ptop, Sym *slast, int keep);
1343ST_FUNC void parse_define(void);1521ST_FUNC void parse_define(TCCState* S);
1344ST_FUNC void preprocess(int is_bof);1522ST_FUNC void preprocess(TCCState* S, int is_bof);
1345ST_FUNC void next(void);1523ST_FUNC void next(TCCState* S);
1346ST_INLN void unget_tok(int last_tok);1524ST_INLN void unget_tok(TCCState* S, int last_tok);
1347ST_FUNC void preprocess_start(TCCState *s1, int filetype);1525ST_FUNC void preprocess_start(TCCState *S, int filetype);
1348ST_FUNC void preprocess_end(TCCState *s1);1526ST_FUNC void preprocess_end(TCCState *S);
1349ST_FUNC void tccpp_new(TCCState *s);1527ST_FUNC void tccpp_new(TCCState *S);
1350ST_FUNC void tccpp_delete(TCCState *s);1528ST_FUNC void tccpp_delete(TCCState *S);
1351ST_FUNC int tcc_preprocess(TCCState *s1);1529ST_FUNC int tcc_preprocess(TCCState *S);
1352ST_FUNC void skip(int c);1530ST_FUNC void skip(TCCState* S, int c);
1353ST_FUNC NORETURN void expect(const char *msg);1531ST_FUNC NORETURN void expect(TCCState* S, const char *msg);
1354 1532
1355/* space excluding newline */1533/* space excluding newline */
1356static inline int is_space(int ch) {1534static inline int is_space(int ch) {
@@ -1372,104 +1550,85 @@ static inline int toup(int c) { · 15 unmodified lines
1372/* ------------ tccgen.c ------------ */1550/* ------------ tccgen.c ------------ */
1373 1551
1374#define SYM_POOL_NB (8192 / sizeof(Sym))1552#define SYM_POOL_NB (8192 / sizeof(Sym))
1553ST_FUNC void tcc_debug_start(TCCState *S);
1554ST_FUNC void tcc_debug_end(TCCState *S);
1555ST_FUNC void tcc_debug_bincl(TCCState *S);
1556ST_FUNC void tcc_debug_eincl(TCCState *S);
1557ST_FUNC void tcc_debug_putfile(TCCState *S, const char *filename);
1375 1558
1376ST_DATA Sym *global_stack;1559ST_FUNC void tccgen_init(TCCState *S);
1377ST_DATA Sym *local_stack;1560ST_FUNC int tccgen_compile(TCCState *S);
1378ST_DATA Sym *local_label_stack;1561ST_FUNC void tccgen_finish(TCCState *S);
1379ST_DATA Sym *global_label_stack;1562ST_FUNC void check_vstack(TCCState* S);
1380ST_DATA Sym *define_stack;
1381ST_DATA CType int_type, func_old_type, char_pointer_type;
1382ST_DATA SValue *vtop;
1383ST_DATA int rsym, anon_sym, ind, loc;
1384ST_DATA char debug_modes;
1385
1386ST_DATA int const_wanted; /* true if constant wanted */
1387ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
1388ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
1389ST_DATA CType func_vt; /* current function return type (used by return instruction) */
1390ST_DATA int func_var; /* true if current function is variadic */
1391ST_DATA int func_vc;
1392ST_DATA const char *funcname;
1393
1394ST_FUNC void tcc_debug_start(TCCState *s1);
1395ST_FUNC void tcc_debug_end(TCCState *s1);
1396ST_FUNC void tcc_debug_bincl(TCCState *s1);
1397ST_FUNC void tcc_debug_eincl(TCCState *s1);
1398ST_FUNC void tcc_debug_putfile(TCCState *s1, const char *filename);
1399
1400ST_FUNC void tccgen_init(TCCState *s1);
1401ST_FUNC int tccgen_compile(TCCState *s1);
1402ST_FUNC void tccgen_finish(TCCState *s1);
1403ST_FUNC void check_vstack(void);
1404 1563
1405ST_INLN int is_float(int t);1564ST_INLN int is_float(int t);
1406ST_FUNC int ieee_finite(double d);1565ST_FUNC int ieee_finite(double d);
1407ST_FUNC int exact_log2p1(int i);1566ST_FUNC int exact_log2p1(int i);
1408ST_FUNC void test_lvalue(void);1567ST_FUNC void test_lvalue(TCCState* S);
1409 1568
1410ST_FUNC ElfSym *elfsym(Sym *);1569ST_FUNC ElfSym *elfsym(TCCState* S, Sym *);
1411ST_FUNC void update_storage(Sym *sym);1570ST_FUNC void update_storage(TCCState* S, Sym *sym);
1412ST_FUNC void put_extern_sym2(Sym *sym, int sh_num, addr_t value, unsigned long size, int can_add_underscore);1571ST_FUNC void put_extern_sym2(TCCState* S, Sym *sym, int sh_num, addr_t value, unsigned long size, int can_add_underscore);
1413ST_FUNC void put_extern_sym(Sym *sym, Section *section, addr_t value, unsigned long size);1572ST_FUNC void put_extern_sym(TCCState* S, Sym *sym, Section *section, addr_t value, unsigned long size);
1414#if PTR_SIZE == 41573#if PTR_SIZE == 4
1415ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type);1574ST_FUNC void greloc(TCCState* S, Section *s, Sym *sym, unsigned long offset, int type);
1416#endif1575#endif
1417ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type, addr_t addend);1576ST_FUNC void greloca(TCCState* S, Section *s, Sym *sym, unsigned long offset, int type, addr_t addend);
1418 1577
1419ST_INLN void sym_free(Sym *sym);1578ST_INLN void sym_free(TCCState* S, Sym *sym);
1420ST_FUNC Sym *sym_push(int v, CType *type, int r, int c);1579ST_FUNC Sym *sym_push(TCCState* S, int v, CType *type, int r, int c);
1421ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep);1580ST_FUNC void sym_pop(TCCState* S, Sym **ptop, Sym *b, int keep);
1422ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, int c);1581ST_FUNC Sym *sym_push2(TCCState* S, Sym **ps, int v, int t, int c);
1423ST_FUNC Sym *sym_find2(Sym *s, int v);1582ST_FUNC Sym *sym_find2(Sym *s, int v);
1424ST_INLN Sym *sym_find(int v);1583ST_INLN Sym *sym_find(TCCState* S, int v);
1425ST_INLN Sym *struct_find(int v);1584ST_INLN Sym *struct_find(TCCState* S, int v);
1426 1585
1427ST_FUNC Sym *global_identifier_push(int v, int t, int c);1586ST_FUNC Sym *global_identifier_push(TCCState* S, int v, int t, int c);
1428ST_FUNC Sym *external_global_sym(int v, CType *type);1587ST_FUNC Sym *external_global_sym(TCCState* S, int v, CType *type);
1429ST_FUNC Sym *external_helper_sym(int v);1588ST_FUNC Sym *external_helper_sym(TCCState* S, int v);
1430ST_FUNC void vpush_helper_func(int v);1589ST_FUNC void vpush_helper_func(TCCState* S, int v);
1431ST_FUNC void vset(CType *type, int r, int v);1590ST_FUNC void vset(TCCState* S, CType *type, int r, int v);
1432ST_FUNC void vset_VT_CMP(int op);1591ST_FUNC void vset_VT_CMP(TCCState* S, int op);
1433ST_FUNC void vpushi(int v);1592ST_FUNC void vpushi(TCCState* S, int v);
1434ST_FUNC void vpushv(SValue *v);1593ST_FUNC void vpushv(TCCState* S, SValue *v);
1435ST_FUNC void vpushsym(CType *type, Sym *sym);1594ST_FUNC void vpushsym(TCCState* S, CType *type, Sym *sym);
1436ST_FUNC void vswap(void);1595ST_FUNC void vswap(TCCState* S);
1437ST_FUNC void vrote(SValue *e, int n);1596ST_FUNC void vrote(TCCState* S, SValue *e, int n);
1438ST_FUNC void vrott(int n);1597ST_FUNC void vrott(TCCState* S, int n);
1439ST_FUNC void vrotb(int n);1598ST_FUNC void vrotb(TCCState* S, int n);
1440ST_FUNC void vpop(void);1599ST_FUNC void vpop(TCCState* S);
1441#if PTR_SIZE == 41600#if PTR_SIZE == 4
1442ST_FUNC void lexpand(void);1601ST_FUNC void lexpand(TCCState* S);
1443#endif1602#endif
1444#ifdef TCC_TARGET_ARM1603#ifdef TCC_TARGET_ARM
1445ST_FUNC int get_reg_ex(int rc, int rc2);1604ST_FUNC int get_reg_ex(TCCState* S, int rc, int rc2);
1446#endif1605#endif
1447ST_FUNC void save_reg(int r);1606ST_FUNC void save_reg(TCCState* S, int r);
1448ST_FUNC void save_reg_upstack(int r, int n);1607ST_FUNC void save_reg_upstack(TCCState* S, int r, int n);
1449ST_FUNC int get_reg(int rc);1608ST_FUNC int get_reg(TCCState* S, int rc);
1450ST_FUNC void save_regs(int n);1609ST_FUNC void save_regs(TCCState* S, int n);
1451ST_FUNC void gaddrof(void);1610ST_FUNC void gaddrof(TCCState* S);
1452ST_FUNC int gv(int rc);1611ST_FUNC int gv(TCCState* S, int rc);
1453ST_FUNC void gv2(int rc1, int rc2);1612ST_FUNC void gv2(TCCState* S, int rc1, int rc2);
1454ST_FUNC void gen_op(int op);1613ST_FUNC void gen_op(TCCState* S, int op);
1455ST_FUNC int type_size(CType *type, int *a);1614ST_FUNC int type_size(CType *type, int *a);
1456ST_FUNC void mk_pointer(CType *type);1615ST_FUNC void mk_pointer(TCCState* S, CType *type);
1457ST_FUNC void vstore(void);1616ST_FUNC void vstore(TCCState* S);
1458ST_FUNC void inc(int post, int c);1617ST_FUNC void inc(TCCState* S, int post, int c);
1459ST_FUNC void parse_mult_str (CString *astr, const char *msg);1618ST_FUNC void parse_mult_str (TCCState* S, CString *astr, const char *msg);
1460ST_FUNC void parse_asm_str(CString *astr);1619ST_FUNC void parse_asm_str(TCCState* S, CString *astr);
1461ST_FUNC void indir(void);1620ST_FUNC void indir(TCCState* S);
1462ST_FUNC void unary(void);1621ST_FUNC void unary(TCCState* S);
1463ST_FUNC void gexpr(void);1622ST_FUNC void gexpr(TCCState* S);
1464ST_FUNC int expr_const(void);1623ST_FUNC int expr_const(TCCState* S);
1465#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C671624#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C67
1466ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size);1625ST_FUNC Sym *get_sym_ref(TCCState* S, CType *type, Section *sec, unsigned long offset, unsigned long size);
1467#endif1626#endif
1468#if defined TCC_TARGET_X86_64 && !defined TCC_TARGET_PE1627#if defined TCC_TARGET_X86_64 && !defined TCC_TARGET_PE
1469ST_FUNC int classify_x86_64_va_arg(CType *ty);1628ST_FUNC int classify_x86_64_va_arg(CType *ty);
1470#endif1629#endif
1471#ifdef CONFIG_TCC_BCHECK1630#ifdef CONFIG_TCC_BCHECK
1472ST_FUNC void gbound_args(int nb_args);1631ST_FUNC void gbound_args(TCCState* S, int nb_args);
1473ST_DATA int func_bound_add_epilog;1632ST_DATA int func_bound_add_epilog;
1474#endif1633#endif
1475 1634
@@ -1489,51 +1648,51 @@ typedef struct { · 13 unmodified lines
1489 unsigned int n_value; /* value of symbol */1648 unsigned int n_value; /* value of symbol */
1490} Stab_Sym;1649} Stab_Sym;
1491 1650
1492ST_FUNC void tccelf_new(TCCState *s);1651ST_FUNC void tccelf_new(TCCState *S);
1493ST_FUNC void tccelf_delete(TCCState *s);1652ST_FUNC void tccelf_delete(TCCState *S);
1494ST_FUNC void tccelf_stab_new(TCCState *s);1653ST_FUNC void tccelf_stab_new(TCCState *S);
1495ST_FUNC void tccelf_begin_file(TCCState *s1);1654ST_FUNC void tccelf_begin_file(TCCState *S);
1496ST_FUNC void tccelf_end_file(TCCState *s1);1655ST_FUNC void tccelf_end_file(TCCState *S);
1497#ifdef CONFIG_TCC_BCHECK1656#ifdef CONFIG_TCC_BCHECK
1498ST_FUNC void tccelf_bounds_new(TCCState *s);1657ST_FUNC void tccelf_bounds_new(TCCState *S);
1499#endif1658#endif
1500ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags);1659ST_FUNC Section *new_section(TCCState *S, const char *name, int sh_type, int sh_flags);
1501ST_FUNC void section_realloc(Section *sec, unsigned long new_size);1660ST_FUNC void section_realloc(TCCState* S, Section *sec, unsigned long new_size);
1502ST_FUNC size_t section_add(Section *sec, addr_t size, int align);1661ST_FUNC size_t section_add(TCCState* S, Section *sec, addr_t size, int align);
1503ST_FUNC void *section_ptr_add(Section *sec, addr_t size);1662ST_FUNC void *section_ptr_add(TCCState* S, Section *sec, addr_t size);
1504ST_FUNC Section *find_section(TCCState *s1, const char *name);1663ST_FUNC Section *find_section(TCCState *S, const char *name);
1505ST_FUNC Section *new_symtab(TCCState *s1, const char *symtab_name, int sh_type, int sh_flags, const char *strtab_name, const char *hash_name, int hash_sh_flags);1664ST_FUNC Section *new_symtab(TCCState *S, const char *symtab_name, int sh_type, int sh_flags, const char *strtab_name, const char *hash_name, int hash_sh_flags);
1506 1665
1507ST_FUNC int put_elf_str(Section *s, const char *sym);1666ST_FUNC int put_elf_str(TCCState* S, Section *s, const char *sym);
1508ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int shndx, const char *name);1667ST_FUNC int put_elf_sym(TCCState* S, Section *s, addr_t value, unsigned long size, int info, int other, int shndx, const char *name);
1509ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int shndx, const char *name);1668ST_FUNC int set_elf_sym(Section *S, addr_t value, unsigned long size, int info, int other, int shndx, const char *name);
1510ST_FUNC int find_elf_sym(Section *s, const char *name);1669ST_FUNC int find_elf_sym(Section *S, const char *name);
1511ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, int type, int symbol);1670ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, int type, int symbol);
1512ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset, int type, int symbol, addr_t addend);1671ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset, int type, int symbol, addr_t addend);
1513 1672
1514ST_FUNC void put_stabs(TCCState *s1, const char *str, int type, int other, int desc, unsigned long value);1673ST_FUNC void put_stabs(TCCState *S, const char *str, int type, int other, int desc, unsigned long value);
1515ST_FUNC void put_stabs_r(TCCState *s1, const char *str, int type, int other, int desc, unsigned long value, Section *sec, int sym_index);1674ST_FUNC void put_stabs_r(TCCState *S, const char *str, int type, int other, int desc, unsigned long value, Section *sec, int sym_index);
1516ST_FUNC void put_stabn(TCCState *s1, int type, int other, int desc, int value);1675ST_FUNC void put_stabn(TCCState *S, int type, int other, int desc, int value);
1517 1676
1518ST_FUNC void resolve_common_syms(TCCState *s1);1677ST_FUNC void resolve_common_syms(TCCState *S);
1519ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve);1678ST_FUNC void relocate_syms(TCCState *S, Section *symtab, int do_resolve);
1520ST_FUNC void relocate_sections(TCCState *s1);1679ST_FUNC void relocate_sections(TCCState *S);
1521 1680
1522ST_FUNC ssize_t full_read(int fd, void *buf, size_t count);1681ST_FUNC ssize_t full_read(int fd, void *buf, size_t count);
1523ST_FUNC void *load_data(int fd, unsigned long file_offset, unsigned long size);1682ST_FUNC void *load_data(TCCState* S, int fd, unsigned long file_offset, unsigned long size);
1524ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h);1683ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h);
1525ST_FUNC int tcc_load_object_file(TCCState *s1, int fd, unsigned long file_offset);1684ST_FUNC int tcc_load_object_file(TCCState *S, int fd, unsigned long file_offset);
1526ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte);1685ST_FUNC int tcc_load_archive(TCCState *S, int fd, int alacarte);
1527ST_FUNC void add_array(TCCState *s1, const char *sec, int c);1686ST_FUNC void add_array(TCCState *S, const char *sec, int c);
1528 1687
1529#if !defined(ELF_OBJ_ONLY) || (defined(TCC_TARGET_MACHO) && defined TCC_IS_NATIVE)1688#if !defined(ELF_OBJ_ONLY) || (defined(TCC_TARGET_MACHO) && defined TCC_IS_NATIVE)
1530ST_FUNC void build_got_entries(TCCState *s1);1689ST_FUNC void build_got_entries(TCCState *S);
1531#endif1690#endif
1532ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc);1691ST_FUNC struct sym_attr *get_sym_attr(TCCState *S, int index, int alloc);
1533ST_FUNC addr_t get_sym_addr(TCCState *s, const char *name, int err, int forc);1692ST_FUNC addr_t get_sym_addr(TCCState *S, const char *name, int err, int forc);
1534ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,1693ST_FUNC void list_elf_symbols(TCCState *S, void *ctx,
1535 void (*symbol_cb)(void *ctx, const char *name, const void *val));1694 void (*symbol_cb)(void *ctx, const char *name, const void *val));
1536ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs);1695ST_FUNC int set_global_sym(TCCState *S, const char *name, Section *sec, addr_t offs);
1537 1696
1538/* Browse each elem of type <type> in section <sec> starting at elem <startoff>1697/* Browse each elem of type <type> in section <sec> starting at elem <startoff>
1539 using variable <elem> */1698 using variable <elem> */
@@ -1542,11 +1701,11 @@ ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t · 2 unmodified lines
1542 elem < (type *) (sec->data + sec->data_offset); elem++)1701 elem < (type *) (sec->data + sec->data_offset); elem++)
1543 1702
1544#ifndef ELF_OBJ_ONLY1703#ifndef ELF_OBJ_ONLY
1545ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level);1704ST_FUNC int tcc_load_dll(TCCState *S, int fd, const char *filename, int level);
1546ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd);1705ST_FUNC int tcc_load_ldscript(TCCState *S, int fd);
1547#endif1706#endif
1548#ifndef TCC_TARGET_PE1707#ifndef TCC_TARGET_PE
1549ST_FUNC void tcc_add_runtime(TCCState *s1);1708ST_FUNC void tcc_add_runtime(TCCState *S);
1550#endif1709#endif
1551 1710
1552/* ------------ xxx-link.c ------------ */1711/* ------------ xxx-link.c ------------ */
@@ -1564,41 +1723,41 @@ enum gotplt_entry { · 11 unmodified lines
1564ST_FUNC int code_reloc (int reloc_type);1723ST_FUNC int code_reloc (int reloc_type);
1565ST_FUNC int gotplt_entry_type (int reloc_type);1724ST_FUNC int gotplt_entry_type (int reloc_type);
1566#if !defined(TCC_TARGET_MACHO) || defined TCC_IS_NATIVE1725#if !defined(TCC_TARGET_MACHO) || defined TCC_IS_NATIVE
1567ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr);1726ST_FUNC unsigned create_plt_entry(TCCState *S, unsigned got_offset, struct sym_attr *attr);
1568ST_FUNC void relocate_plt(TCCState *s1);1727ST_FUNC void relocate_plt(TCCState *S);
1569#endif1728#endif
1570#endif1729#endif
1571ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val);1730ST_FUNC void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val);
1572 1731
1573/* ------------ xxx-gen.c ------------ */1732/* ------------ xxx-gen.c ------------ */
1574ST_DATA const char * const target_machine_defs;1733ST_DATA const char * const target_machine_defs;
1575ST_DATA const int reg_classes[NB_REGS];1734ST_DATA const int reg_classes[NB_REGS];
1576 1735
1577ST_FUNC void gsym_addr(int t, int a);1736ST_FUNC void gsym_addr(TCCState* S, int t, int a);
1578ST_FUNC void gsym(int t);1737ST_FUNC void gsym(TCCState* S, int t);
1579ST_FUNC void load(int r, SValue *sv);1738ST_FUNC void load(TCCState *S, int r, SValue *sv);
1580ST_FUNC void store(int r, SValue *v);1739ST_FUNC void store(TCCState *S, int r, SValue *v);
1581ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *align, int *regsize);1740ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *align, int *regsize);
1582ST_FUNC void gfunc_call(int nb_args);1741ST_FUNC void gfunc_call(TCCState *S, int nb_args);
1583ST_FUNC void gfunc_prolog(Sym *func_sym);1742ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym);
1584ST_FUNC void gfunc_epilog(void);1743ST_FUNC void gfunc_epilog(TCCState *S);
1585ST_FUNC void gen_fill_nops(int);1744ST_FUNC void gen_fill_nops(TCCState* S, int);
1586ST_FUNC int gjmp(int t);1745ST_FUNC int gjmp(TCCState* S, int t);
1587ST_FUNC void gjmp_addr(int a);1746ST_FUNC void gjmp_addr(TCCState* S, int a);
1588ST_FUNC int gjmp_cond(int op, int t);1747ST_FUNC int gjmp_cond(TCCState* S, int op, int t);
1589ST_FUNC int gjmp_append(int n, int t);1748ST_FUNC int gjmp_append(TCCState *S, int n, int t);
1590ST_FUNC void gen_opi(int op);1749ST_FUNC void gen_opi(TCCState* S, int op);
1591ST_FUNC void gen_opf(int op);1750ST_FUNC void gen_opf(TCCState* S, int op);
1592ST_FUNC void gen_cvt_ftoi(int t);1751ST_FUNC void gen_cvt_ftoi(TCCState *S, int t);
1593ST_FUNC void gen_cvt_itof(int t);1752ST_FUNC void gen_cvt_itof(TCCState *S, int t);
1594ST_FUNC void gen_cvt_ftof(int t);1753ST_FUNC void gen_cvt_ftof(TCCState *S, int t);
1595ST_FUNC void ggoto(void);1754ST_FUNC void ggoto(TCCState *S);
1596#ifndef TCC_TARGET_C671755#ifndef TCC_TARGET_C67
1597ST_FUNC void o(unsigned int c);1756ST_FUNC void o(TCCState* S, unsigned int c);
1598#endif1757#endif
1599ST_FUNC void gen_vla_sp_save(int addr);1758ST_FUNC void gen_vla_sp_save(TCCState* S, int addr);
1600ST_FUNC void gen_vla_sp_restore(int addr);1759ST_FUNC void gen_vla_sp_restore(TCCState* S, int addr);
1601ST_FUNC void gen_vla_alloc(CType *type, int align);1760ST_FUNC void gen_vla_alloc(TCCState* S, CType *type, int align);
1602 1761
1603static inline uint16_t read16le(unsigned char *p) {1762static inline uint16_t read16le(unsigned char *p) {
1604 return p[0] | (uint16_t)p[1] << 8;1763 return p[0] | (uint16_t)p[1] << 8;
@@ -1627,57 +1786,57 @@ static inline void add64le(unsigned char *p, int64_t x) { · 22 unmodified lines
1627 1786
1628/* ------------ i386-gen.c ------------ */1787/* ------------ i386-gen.c ------------ */
1629#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM1788#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM
1630ST_FUNC void g(int c);1789ST_FUNC void g(TCCState* S, int c);
1631ST_FUNC void gen_le16(int c);1790ST_FUNC void gen_le16(TCCState* S, int c);
1632ST_FUNC void gen_le32(int c);1791ST_FUNC void gen_le32(TCCState* S, int c);
1633#endif1792#endif
1634#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_641793#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
1635ST_FUNC void gen_addr32(int r, Sym *sym, int c);1794ST_FUNC void gen_addr32(TCCState* S, int r, Sym *sym, int c);
1636ST_FUNC void gen_addrpc32(int r, Sym *sym, int c);1795ST_FUNC void gen_addrpc32(TCCState* S, int r, Sym *sym, int c);
1637ST_FUNC void gen_cvt_csti(int t);1796ST_FUNC void gen_cvt_csti(TCCState* S, int t);
1638ST_FUNC void gen_increment_tcov (SValue *sv);1797ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv);
1639#endif1798#endif
1640 1799
1641/* ------------ x86_64-gen.c ------------ */1800/* ------------ x86_64-gen.c ------------ */
1642#ifdef TCC_TARGET_X86_641801#ifdef TCC_TARGET_X86_64
1643ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c);1802ST_FUNC void gen_addr64(TCCState* S, int r, Sym *sym, int64_t c);
1644ST_FUNC void gen_opl(int op);1803ST_FUNC void gen_opl(TCCState* S, int op);
1645#ifdef TCC_TARGET_PE1804#ifdef TCC_TARGET_PE
1646ST_FUNC void gen_vla_result(int addr);1805ST_FUNC void gen_vla_result(TCCState* S, int addr);
1647#endif1806#endif
1648ST_FUNC void gen_cvt_sxtw(void);1807ST_FUNC void gen_cvt_sxtw(TCCState *S);
1649ST_FUNC void gen_cvt_csti(int t);1808ST_FUNC void gen_cvt_csti(TCCState* S, int t);
1650#endif1809#endif
1651 1810
1652/* ------------ arm-gen.c ------------ */1811/* ------------ arm-gen.c ------------ */
1653#ifdef TCC_TARGET_ARM1812#ifdef TCC_TARGET_ARM
1654#if defined(TCC_ARM_EABI) && !defined(CONFIG_TCC_ELFINTERP)1813#if defined(TCC_ARM_EABI) && !defined(CONFIG_TCC_ELFINTERP)
1655PUB_FUNC const char *default_elfinterp(struct TCCState *s);1814PUB_FUNC const char *default_elfinterp(TCCState *S);
1656#endif1815#endif
1657ST_FUNC void arm_init(struct TCCState *s);1816ST_FUNC void arm_init(TCCState *S);
1658ST_FUNC void gen_increment_tcov (SValue *sv);1817ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv);
1659#endif1818#endif
1660 1819
1661/* ------------ arm64-gen.c ------------ */1820/* ------------ arm64-gen.c ------------ */
1662#ifdef TCC_TARGET_ARM641821#ifdef TCC_TARGET_ARM64
1663ST_FUNC void gen_opl(int op);1822ST_FUNC void gen_opl(TCCState* S, int op);
1664ST_FUNC void gfunc_return(CType *func_type);1823ST_FUNC void gfunc_return(TCCState *S, CType *func_type);
1665ST_FUNC void gen_va_start(void);1824ST_FUNC void gen_va_start(TCCState *S);
1666ST_FUNC void gen_va_arg(CType *t);1825ST_FUNC void gen_va_arg(TCCState *S, CType *t);
1667ST_FUNC void gen_clear_cache(void);1826ST_FUNC void gen_clear_cache(TCCState *S);
1668ST_FUNC void gen_cvt_sxtw(void);1827ST_FUNC void gen_cvt_sxtw(TCCState *S);
1669ST_FUNC void gen_cvt_csti(int t);1828ST_FUNC void gen_cvt_csti(TCCState *S, int t);
1670ST_FUNC void gen_increment_tcov (SValue *sv);1829ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv);
1671#endif1830#endif
1672 1831
1673/* ------------ riscv64-gen.c ------------ */1832/* ------------ riscv64-gen.c ------------ */
1674#ifdef TCC_TARGET_RISCV641833#ifdef TCC_TARGET_RISCV64
1675ST_FUNC void gen_opl(int op);1834ST_FUNC void gen_opl(TCCState* S, int op);
1676//ST_FUNC void gfunc_return(CType *func_type);1835//ST_FUNC void gfunc_return(TCCState *S, CType *func_type);
1677ST_FUNC void gen_va_start(void);1836ST_FUNC void gen_va_start(TCCState *S);
1678ST_FUNC void arch_transfer_ret_regs(int);1837ST_FUNC void arch_transfer_ret_regs(TCCState* S, int);
1679ST_FUNC void gen_cvt_sxtw(void);1838ST_FUNC void gen_cvt_sxtw(TCCState *S);
1680ST_FUNC void gen_increment_tcov (SValue *sv);1839ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv);
1681#endif1840#endif
1682 1841
1683/* ------------ c67-gen.c ------------ */1842/* ------------ c67-gen.c ------------ */
@@ -1687,44 +1846,44 @@ ST_FUNC void gen_increment_tcov (SValue *sv); · 3 unmodified lines
1687/* ------------ tcccoff.c ------------ */1846/* ------------ tcccoff.c ------------ */
1688 1847
1689#ifdef TCC_TARGET_COFF1848#ifdef TCC_TARGET_COFF
1690ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f);1849ST_FUNC int tcc_output_coff(TCCState *S, FILE *f);
1691ST_FUNC int tcc_load_coff(TCCState * s1, int fd);1850ST_FUNC int tcc_load_coff(TCCState *S, int fd);
1692#endif1851#endif
1693 1852
1694/* ------------ tccasm.c ------------ */1853/* ------------ tccasm.c ------------ */
1695ST_FUNC void asm_instr(void);1854ST_FUNC void asm_instr(TCCState* S);
1696ST_FUNC void asm_global_instr(void);1855ST_FUNC void asm_global_instr(TCCState* S);
1697ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess);1856ST_FUNC int tcc_assemble(TCCState *S, int do_preprocess);
1698#ifdef CONFIG_TCC_ASM1857#ifdef CONFIG_TCC_ASM
1699ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands, const char *name, const char **pp);1858ST_FUNC int find_constraint(TCCState* S, ASMOperand *operands, int nb_operands, const char *name, const char **pp);
1700ST_FUNC Sym* get_asm_sym(int name, Sym *csym);1859ST_FUNC Sym* get_asm_sym(TCCState* S, int name, Sym *csym);
1701ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe);1860ST_FUNC void asm_expr(TCCState *S, ExprValue *pe);
1702ST_FUNC int asm_int_expr(TCCState *s1);1861ST_FUNC int asm_int_expr(TCCState *S);
1703/* ------------ i386-asm.c ------------ */1862/* ------------ i386-asm.c ------------ */
1704ST_FUNC void gen_expr32(ExprValue *pe);1863ST_FUNC void gen_expr32(TCCState* S, ExprValue *pe);
1705#ifdef TCC_TARGET_X86_641864#ifdef TCC_TARGET_X86_64
1706ST_FUNC void gen_expr64(ExprValue *pe);1865ST_FUNC void gen_expr64(TCCState* S, ExprValue *pe);
1707#endif1866#endif
1708ST_FUNC void asm_opcode(TCCState *s1, int opcode);1867ST_FUNC void asm_opcode(TCCState *S, int opcode);
1709ST_FUNC int asm_parse_regvar(int t);1868ST_FUNC int asm_parse_regvar(TCCState* S, int t);
1710ST_FUNC void asm_compute_constraints(ASMOperand *operands, int nb_operands, int nb_outputs, const uint8_t *clobber_regs, int *pout_reg);1869ST_FUNC void asm_compute_constraints(TCCState* S, ASMOperand *operands, int nb_operands, int nb_outputs, const uint8_t *clobber_regs, int *pout_reg);
1711ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier);1870ST_FUNC void subst_asm_operand(TCCState* S, CString *add_str, SValue *sv, int modifier);
1712ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, int nb_outputs, int is_output, uint8_t *clobber_regs, int out_reg);1871ST_FUNC void asm_gen_code(TCCState* S, ASMOperand *operands, int nb_operands, int nb_outputs, int is_output, uint8_t *clobber_regs, int out_reg);
1713ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str);1872ST_FUNC void asm_clobber(TCCState* S, uint8_t *clobber_regs, const char *str);
1714#endif1873#endif
1715 1874
1716/* ------------ tccpe.c -------------- */1875/* ------------ tccpe.c -------------- */
1717#ifdef TCC_TARGET_PE1876#ifdef TCC_TARGET_PE
1718ST_FUNC int pe_load_file(struct TCCState *s1, int fd, const char *filename);1877ST_FUNC int pe_load_file(struct TCCState *S, int fd, const char *filename);
1719ST_FUNC int pe_output_file(TCCState * s1, const char *filename);1878ST_FUNC int pe_output_file(TCCState * S, const char *filename);
1720ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t value);1879ST_FUNC int pe_putimport(TCCState *S, int dllindex, const char *name, addr_t value);
1721#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_641880#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
1722ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2);1881ST_FUNC SValue *pe_getimport(TCCState * S, SValue *sv, SValue *v2);
1723#endif1882#endif
1724#ifdef TCC_TARGET_X86_641883#ifdef TCC_TARGET_X86_64
1725ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack);1884ST_FUNC void pe_add_unwind_data(TCCState* S, unsigned start, unsigned end, unsigned stack);
1726#endif1885#endif
1727PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp);1886PUB_FUNC int tcc_get_dllexports(TCCState* S, const char *filename, char **pp);
1728/* symbol properties stored in Elf32_Sym->st_other */1887/* symbol properties stored in Elf32_Sym->st_other */
1729# define ST_PE_EXPORT 0x101888# define ST_PE_EXPORT 0x10
1730# define ST_PE_IMPORT 0x201889# define ST_PE_IMPORT 0x20
@@ -1734,11 +1893,11 @@ PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp); · 3 unmodified lines
1734 1893
1735/* ------------ tccmacho.c ----------------- */1894/* ------------ tccmacho.c ----------------- */
1736#ifdef TCC_TARGET_MACHO1895#ifdef TCC_TARGET_MACHO
1737ST_FUNC int macho_output_file(TCCState * s1, const char *filename);1896ST_FUNC int macho_output_file(TCCState * S, const char *filename);
1738ST_FUNC int macho_load_dll(TCCState *s1, int fd, const char *filename, int lev);1897ST_FUNC int macho_load_dll(TCCState *S, int fd, const char *filename, int lev);
1739ST_FUNC int macho_load_tbd(TCCState *s1, int fd, const char *filename, int lev);1898ST_FUNC int macho_load_tbd(TCCState *S, int fd, const char *filename, int lev);
1740#ifdef TCC_IS_NATIVE1899#ifdef TCC_IS_NATIVE
1741ST_FUNC void tcc_add_macos_sdkpath(TCCState* s);1900ST_FUNC void tcc_add_macos_sdkpath(TCCState* S);
1742ST_FUNC const char* macho_tbd_soname(const char* filename);1901ST_FUNC const char* macho_tbd_soname(const char* filename);
1743#endif1902#endif
1744#endif1903#endif
@@ -1755,17 +1914,17 @@ ST_FUNC void dlclose(void *p); · 10 unmodified lines
1755ST_FUNC const char *dlerror(void);1914ST_FUNC const char *dlerror(void);
1756ST_FUNC void *dlsym(void *handle, const char *symbol);1915ST_FUNC void *dlsym(void *handle, const char *symbol);
1757#endif1916#endif
1758ST_FUNC void tcc_run_free(TCCState *s1);1917ST_FUNC void tcc_run_free(TCCState *S);
1759#endif1918#endif
1760 1919
1761/* ------------ tcctools.c ----------------- */1920/* ------------ tcctools.c ----------------- */
1762#if 0 /* included in tcc.c */1921#if 0 /* included in tcc.c */
1763ST_FUNC int tcc_tool_ar(TCCState *s, int argc, char **argv);1922ST_FUNC int tcc_tool_ar(TCCState *S, int argc, char **argv);
1764#ifdef TCC_TARGET_PE1923#ifdef TCC_TARGET_PE
1765ST_FUNC int tcc_tool_impdef(TCCState *s, int argc, char **argv);1924ST_FUNC int tcc_tool_impdef(TCCState *S, int argc, char **argv);
1766#endif1925#endif
1767ST_FUNC void tcc_tool_cross(TCCState *s, char **argv, int option);1926ST_FUNC void tcc_tool_cross(TCCState *S, char **argv, int option);
1768ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename);1927ST_FUNC void gen_makedeps(TCCState *S, const char *target, const char *filename);
1769#endif1928#endif
1770 1929
1771/********************************************************/1930/********************************************************/
@@ -1820,12 +1979,12 @@ ST_FUNC void post_sem(TCCSem *p); · 48 unmodified lines
1820#define total_lines TCC_STATE_VAR(total_lines)1979#define total_lines TCC_STATE_VAR(total_lines)
1821#define total_bytes TCC_STATE_VAR(total_bytes)1980#define total_bytes TCC_STATE_VAR(total_bytes)
1822 1981
1823PUB_FUNC void tcc_enter_state(TCCState *s1);1982PUB_FUNC void tcc_enter_state(TCCState *S);
1824PUB_FUNC void tcc_exit_state(TCCState *s1);1983PUB_FUNC void tcc_exit_state(TCCState *S);
1825 1984
1826/* conditional warning depending on switch */1985/* conditional warning depending on switch */
1827#define tcc_warning_c(sw) TCC_SET_STATE((\1986#define tcc_warning_c(sw) TCC_SET_STATE((\
1828 tcc_state->warn_num = offsetof(TCCState, sw) \1987 S->warn_num = offsetof(TCCState, sw) \
1829 - offsetof(TCCState, warn_none), _tcc_warning))1988 - offsetof(TCCState, warn_none), _tcc_warning))
1830 1989
1831/********************************************************/1990/********************************************************/
@@ -1835,10 +1994,10 @@ PUB_FUNC void tcc_exit_state(TCCState *s1); · 3 unmodified lines
1835#undef TCC_SET_STATE1994#undef TCC_SET_STATE
1836 1995
1837#ifdef USING_GLOBALS1996#ifdef USING_GLOBALS
1838# define TCC_STATE_VAR(sym) tcc_state->sym1997# define TCC_STATE_VAR(sym) S->sym
1839# define TCC_SET_STATE(fn) fn1998# define TCC_SET_STATE(fn) fn
1840# undef USING_GLOBALS1999# undef USING_GLOBALS
1841#else2000#else
1842# define TCC_STATE_VAR(sym) s1->sym2001# define TCC_STATE_VAR(sym) S->sym
1843# define TCC_SET_STATE(fn) (tcc_enter_state(s1),fn)2002# define TCC_SET_STATE(fn) (tcc_enter_state(S),fn)
1844#endif2003#endif
tccasm.c+418−420
@@ -22,18 +22,16 @@ · 21 unmodified lines
22#include "tcc.h"22#include "tcc.h"
23#ifdef CONFIG_TCC_ASM23#ifdef CONFIG_TCC_ASM
24 24
25static Section *last_text_section; /* to handle .previous asm directive */25ST_FUNC int asm_get_local_label_name(TCCState *S, unsigned int n)
26
27ST_FUNC int asm_get_local_label_name(TCCState *s1, unsigned int n)
28{26{
29 char buf[64];27 char buf[64];
30 snprintf(buf, sizeof(buf), "L..%u", n);28 snprintf(buf, sizeof(buf), "L..%u", n);
31 return tok_alloc_const(buf);29 return tok_alloc_const(S, buf);
32}30}
33 31
34static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global);32static int tcc_assemble_internal(TCCState *S, int do_preprocess, int global);
35static Sym* asm_new_label(TCCState *s1, int label, int is_local);33static Sym* asm_new_label(TCCState *S, int label, int is_local);
36static Sym* asm_new_label1(TCCState *s1, int label, int is_local, int sh_num, int value);34static Sym* asm_new_label1(TCCState *S, int label, int is_local, int sh_num, int value);
37 35
38/* If a C name has an _ prepended then only asm labels that start36/* If a C name has an _ prepended then only asm labels that start
39 with _ are representable in C, by removing the first _. ASM names37 with _ are representable in C, by removing the first _. ASM names
@@ -41,44 +39,44 @@ static Sym* asm_new_label1(TCCState *s1, int label, int is_local, int sh_num, in · 1 unmodified line
41 the global C symbol table to track ASM names as well, so we need to39 the global C symbol table to track ASM names as well, so we need to
42 transform those into ones that don't conflict with a C name,40 transform those into ones that don't conflict with a C name,
43 so prepend a '.' for them, but force the ELF asm name to be set. */41 so prepend a '.' for them, but force the ELF asm name to be set. */
44static int asm2cname(int v, int *addeddot)42static int asm2cname(TCCState* S, int v, int *addeddot)
45{43{
46 const char *name;44 const char *name;
47 *addeddot = 0;45 *addeddot = 0;
48 if (!tcc_state->leading_underscore)46 if (!S->leading_underscore)
49 return v;47 return v;
50 name = get_tok_str(v, NULL);48 name = get_tok_str(S, v, NULL);
51 if (!name)49 if (!name)
52 return v;50 return v;
53 if (name[0] == '_') {51 if (name[0] == '_') {
54 v = tok_alloc_const(name + 1);52 v = tok_alloc_const(S, name + 1);
55 } else if (!strchr(name, '.')) {53 } else if (!strchr(name, '.')) {
56 char newname[256];54 char newname[256];
57 snprintf(newname, sizeof newname, ".%s", name);55 snprintf(newname, sizeof newname, ".%s", name);
58 v = tok_alloc_const(newname);56 v = tok_alloc_const(S, newname);
59 *addeddot = 1;57 *addeddot = 1;
60 }58 }
61 return v;59 return v;
62}60}
63 61
64static Sym *asm_label_find(int v)62static Sym *asm_label_find(TCCState* S, int v)
65{63{
66 Sym *sym;64 Sym *sym;
67 int addeddot;65 int addeddot;
68 v = asm2cname(v, &addeddot);66 v = asm2cname(S, v, &addeddot);
69 sym = sym_find(v);67 sym = sym_find(S, v);
70 while (sym && sym->sym_scope && !(sym->type.t & VT_STATIC))68 while (sym && sym->sym_scope && !(sym->type.t & VT_STATIC))
71 sym = sym->prev_tok;69 sym = sym->prev_tok;
72 return sym;70 return sym;
73}71}
74 72
75static Sym *asm_label_push(int v)73static Sym *asm_label_push(TCCState* S, int v)
76{74{
77 int addeddot, v2 = asm2cname(v, &addeddot);75 int addeddot, v2 = asm2cname(S, v, &addeddot);
78 /* We always add VT_EXTERN, for sym definition that's tentative76 /* We always add VT_EXTERN, for sym definition that's tentative
79 (for .set, removed for real defs), for mere references it's correct77 (for .set, removed for real defs), for mere references it's correct
80 as is. */78 as is. */
81 Sym *sym = global_identifier_push(v2, VT_ASM | VT_EXTERN | VT_STATIC, 0);79 Sym *sym = global_identifier_push(S, v2, VT_ASM | VT_EXTERN | VT_STATIC, 0);
82 if (addeddot)80 if (addeddot)
83 sym->asm_label = v;81 sym->asm_label = v;
84 return sym;82 return sym;
@@ -94,55 +92,55 @@ static Sym *asm_label_push(int v) · 9 unmodified lines
94 are anonymous in C, in this case CSYM can be used to transfer92 are anonymous in C, in this case CSYM can be used to transfer
95 all information from that symbol to the (possibly newly created)93 all information from that symbol to the (possibly newly created)
96 asm symbol. */94 asm symbol. */
97ST_FUNC Sym* get_asm_sym(int name, Sym *csym)95ST_FUNC Sym* get_asm_sym(TCCState* S, int name, Sym *csym)
98{96{
99 Sym *sym = asm_label_find(name);97 Sym *sym = asm_label_find(S, name);
100 if (!sym) {98 if (!sym) {
101 sym = asm_label_push(name);99 sym = asm_label_push(S, name);
102 if (csym)100 if (csym)
103 sym->c = csym->c;101 sym->c = csym->c;
104 }102 }
105 return sym;103 return sym;
106}104}
107 105
108static Sym* asm_section_sym(TCCState *s1, Section *sec)106static Sym* asm_section_sym(TCCState *S, Section *sec)
109{107{
110 char buf[100]; int label; Sym *sym;108 char buf[100]; int label; Sym *sym;
111 snprintf(buf, sizeof buf, "L.%s", sec->name);109 snprintf(buf, sizeof buf, "L.%s", sec->name);
112 label = tok_alloc_const(buf);110 label = tok_alloc_const(S, buf);
113 sym = asm_label_find(label);111 sym = asm_label_find(S, label);
114 return sym ? sym : asm_new_label1(s1, label, 1, sec->sh_num, 0);112 return sym ? sym : asm_new_label1(S, label, 1, sec->sh_num, 0);
115}113}
116 114
117/* We do not use the C expression parser to handle symbols. Maybe the115/* We do not use the C expression parser to handle symbols. Maybe the
118 C expression parser could be tweaked to do so. */116 C expression parser could be tweaked to do so. */
119 117
120static void asm_expr_unary(TCCState *s1, ExprValue *pe)118static void asm_expr_unary(TCCState *S, ExprValue *pe)
121{119{
122 Sym *sym;120 Sym *sym;
123 int op, label;121 int op, label;
124 uint64_t n;122 uint64_t n;
125 const char *p;123 const char *p;
126 124
127 switch(tok) {125 switch(S->tccpp_tok) {
128 case TOK_PPNUM:126 case TOK_PPNUM:
129 p = tokc.str.data;127 p = S->tccpp_tokc.str.data;
130 n = strtoull(p, (char **)&p, 0);128 n = strtoull(p, (char **)&p, 0);
131 if (*p == 'b' || *p == 'f') {129 if (*p == 'b' || *p == 'f') {
132 /* backward or forward label */130 /* backward or forward label */
133 label = asm_get_local_label_name(s1, n);131 label = asm_get_local_label_name(S, n);
134 sym = asm_label_find(label);132 sym = asm_label_find(S, label);
135 if (*p == 'b') {133 if (*p == 'b') {
136 /* backward : find the last corresponding defined label */134 /* backward : find the last corresponding defined label */
137 if (sym && (!sym->c || elfsym(sym)->st_shndx == SHN_UNDEF))135 if (sym && (!sym->c || elfsym(S, sym)->st_shndx == SHN_UNDEF))
138 sym = sym->prev_tok;136 sym = sym->prev_tok;
139 if (!sym)137 if (!sym)
140 tcc_error("local label '%d' not found backward", (int)n);138 tcc_error(S, "local label '%d' not found backward", (int)n);
141 } else {139 } else {
142 /* forward */140 /* forward */
143 if (!sym || (sym->c && elfsym(sym)->st_shndx != SHN_UNDEF)) {141 if (!sym || (sym->c && elfsym(S, sym)->st_shndx != SHN_UNDEF)) {
144 /* if the last label is defined, then define a new one */142 /* if the last label is defined, then define a new one */
145 sym = asm_label_push(label);143 sym = asm_label_push(S, label);
146 }144 }
147 }145 }
148 pe->v = 0;146 pe->v = 0;
@@ -153,21 +151,21 @@ static void asm_expr_unary(TCCState *s1, ExprValue *pe) · 4 unmodified lines
153 pe->sym = NULL;151 pe->sym = NULL;
154 pe->pcrel = 0;152 pe->pcrel = 0;
155 } else {153 } else {
156 tcc_error("invalid number syntax");154 tcc_error(S, "invalid number syntax");
157 }155 }
158 next();156 next(S);
159 break;157 break;
160 case '+':158 case '+':
161 next();159 next(S);
162 asm_expr_unary(s1, pe);160 asm_expr_unary(S, pe);
163 break;161 break;
164 case '-':162 case '-':
165 case '~':163 case '~':
166 op = tok;164 op = S->tccpp_tok;
167 next();165 next(S);
168 asm_expr_unary(s1, pe);166 asm_expr_unary(S, pe);
169 if (pe->sym)167 if (pe->sym)
170 tcc_error("invalid operation with label");168 tcc_error(S, "invalid operation with label");
171 if (op == '-')169 if (op == '-')
172 pe->v = -pe->v;170 pe->v = -pe->v;
173 else171 else
@@ -175,28 +173,28 @@ static void asm_expr_unary(TCCState *s1, ExprValue *pe) · 1 unmodified line
175 break;173 break;
176 case TOK_CCHAR:174 case TOK_CCHAR:
177 case TOK_LCHAR:175 case TOK_LCHAR:
178 pe->v = tokc.i;176 pe->v = S->tccpp_tokc.i;
179 pe->sym = NULL;177 pe->sym = NULL;
180 pe->pcrel = 0;178 pe->pcrel = 0;
181 next();179 next(S);
182 break;180 break;
183 case '(':181 case '(':
184 next();182 next(S);
185 asm_expr(s1, pe);183 asm_expr(S, pe);
186 skip(')');184 skip(S, ')');
187 break;185 break;
188 case '.':186 case '.':
189 pe->v = ind;187 pe->v = S->tccgen_ind;
190 pe->sym = asm_section_sym(s1, cur_text_section);188 pe->sym = asm_section_sym(S, cur_text_section);
191 pe->pcrel = 0;189 pe->pcrel = 0;
192 next();190 next(S);
193 break;191 break;
194 default:192 default:
195 if (tok >= TOK_IDENT) {193 if (S->tccpp_tok >= TOK_IDENT) {
196 ElfSym *esym;194 ElfSym *esym;
197 /* label case : if the label was not found, add one */195 /* label case : if the label was not found, add one */
198 sym = get_asm_sym(tok, NULL);196 sym = get_asm_sym(S, S->tccpp_tok, NULL);
199 esym = elfsym(sym);197 esym = elfsym(S, sym);
200 if (esym && esym->st_shndx == SHN_ABS) {198 if (esym && esym->st_shndx == SHN_ABS) {
201 /* if absolute symbol, no need to put a symbol value */199 /* if absolute symbol, no need to put a symbol value */
202 pe->v = esym->st_value;200 pe->v = esym->st_value;
@@ -207,29 +205,29 @@ static void asm_expr_unary(TCCState *s1, ExprValue *pe) · 4 unmodified lines
207 pe->sym = sym;205 pe->sym = sym;
208 pe->pcrel = 0;206 pe->pcrel = 0;
209 }207 }
210 next();208 next(S);
211 } else {209 } else {
212 tcc_error("bad expression syntax [%s]", get_tok_str(tok, &tokc));210 tcc_error(S, "bad expression syntax [%s]", get_tok_str(S, S->tccpp_tok, &S->tccpp_tokc));
213 }211 }
214 break;212 break;
215 }213 }
216}214}
217 215
218static void asm_expr_prod(TCCState *s1, ExprValue *pe)216static void asm_expr_prod(TCCState *S, ExprValue *pe)
219{217{
220 int op;218 int op;
221 ExprValue e2;219 ExprValue e2;
222 220
223 asm_expr_unary(s1, pe);221 asm_expr_unary(S, pe);
224 for(;;) {222 for(;;) {
225 op = tok;223 op = S->tccpp_tok;
226 if (op != '*' && op != '/' && op != '%' && 224 if (op != '*' && op != '/' && op != '%' &&
227 op != TOK_SHL && op != TOK_SAR)225 op != TOK_SHL && op != TOK_SAR)
228 break;226 break;
229 next();227 next(S);
230 asm_expr_unary(s1, &e2);228 asm_expr_unary(S, &e2);
231 if (pe->sym || e2.sym)229 if (pe->sym || e2.sym)
232 tcc_error("invalid operation with label");230 tcc_error(S, "invalid operation with label");
233 switch(op) {231 switch(op) {
234 case '*':232 case '*':
235 pe->v *= e2.v;233 pe->v *= e2.v;
@@ -237,7 +235,7 @@ static void asm_expr_prod(TCCState *s1, ExprValue *pe) · 1 unmodified line
237 case '/': 235 case '/':
238 if (e2.v == 0) {236 if (e2.v == 0) {
239 div_error:237 div_error:
240 tcc_error("division by zero");238 tcc_error(S, "division by zero");
241 }239 }
242 pe->v /= e2.v;240 pe->v /= e2.v;
243 break;241 break;
@@ -257,20 +255,20 @@ static void asm_expr_prod(TCCState *s1, ExprValue *pe) · 13 unmodified lines
257 }255 }
258}256}
259 257
260static void asm_expr_logic(TCCState *s1, ExprValue *pe)258static void asm_expr_logic(TCCState *S, ExprValue *pe)
261{259{
262 int op;260 int op;
263 ExprValue e2;261 ExprValue e2;
264 262
265 asm_expr_prod(s1, pe);263 asm_expr_prod(S, pe);
266 for(;;) {264 for(;;) {
267 op = tok;265 op = S->tccpp_tok;
268 if (op != '&' && op != '|' && op != '^')266 if (op != '&' && op != '|' && op != '^')
269 break;267 break;
270 next();268 next(S);
271 asm_expr_prod(s1, &e2);269 asm_expr_prod(S, &e2);
272 if (pe->sym || e2.sym)270 if (pe->sym || e2.sym)
273 tcc_error("invalid operation with label");271 tcc_error(S, "invalid operation with label");
274 switch(op) {272 switch(op) {
275 case '&':273 case '&':
276 pe->v &= e2.v;274 pe->v &= e2.v;
@@ -286,18 +284,18 @@ static void asm_expr_logic(TCCState *s1, ExprValue *pe) · 9 unmodified lines
286 }284 }
287}285}
288 286
289static inline void asm_expr_sum(TCCState *s1, ExprValue *pe)287static inline void asm_expr_sum(TCCState *S, ExprValue *pe)
290{288{
291 int op;289 int op;
292 ExprValue e2;290 ExprValue e2;
293 291
294 asm_expr_logic(s1, pe);292 asm_expr_logic(S, pe);
295 for(;;) {293 for(;;) {
296 op = tok;294 op = S->tccpp_tok;
297 if (op != '+' && op != '-')295 if (op != '+' && op != '-')
298 break;296 break;
299 next();297 next(S);
300 asm_expr_logic(s1, &e2);298 asm_expr_logic(S, &e2);
301 if (op == '+') {299 if (op == '+') {
302 if (pe->sym != NULL && e2.sym != NULL)300 if (pe->sym != NULL && e2.sym != NULL)
303 goto cannot_relocate;301 goto cannot_relocate;
@@ -315,8 +313,8 @@ static inline void asm_expr_sum(TCCState *s1, ExprValue *pe) · 11 unmodified lines
315 pe->sym = NULL; /* same symbols can be subtracted to NULL */313 pe->sym = NULL; /* same symbols can be subtracted to NULL */
316 } else {314 } else {
317 ElfSym *esym1, *esym2;315 ElfSym *esym1, *esym2;
318 esym1 = elfsym(pe->sym);316 esym1 = elfsym(S, pe->sym);
319 esym2 = elfsym(e2.sym);317 esym2 = elfsym(S, e2.sym);
320 if (esym1 && esym1->st_shndx == esym2->st_shndx318 if (esym1 && esym1->st_shndx == esym2->st_shndx
321 && esym1->st_shndx != SHN_UNDEF) {319 && esym1->st_shndx != SHN_UNDEF) {
322 /* we also accept defined symbols in the same section */320 /* we also accept defined symbols in the same section */
@@ -325,33 +323,33 @@ static inline void asm_expr_sum(TCCState *s1, ExprValue *pe) · 2 unmodified lines
325 } else if (esym2->st_shndx == cur_text_section->sh_num) {323 } else if (esym2->st_shndx == cur_text_section->sh_num) {
326 /* When subtracting a defined symbol in current section324 /* When subtracting a defined symbol in current section
327 this actually makes the value PC-relative. */325 this actually makes the value PC-relative. */
328 pe->v -= esym2->st_value - ind - 4;326 pe->v -= esym2->st_value - S->tccgen_ind - 4;
329 pe->pcrel = 1;327 pe->pcrel = 1;
330 e2.sym = NULL;328 e2.sym = NULL;
331 } else {329 } else {
332cannot_relocate:330cannot_relocate:
333 tcc_error("invalid operation with label");331 tcc_error(S, "invalid operation with label");
334 }332 }
335 }333 }
336 }334 }
337 }335 }
338}336}
339 337
340static inline void asm_expr_cmp(TCCState *s1, ExprValue *pe)338static inline void asm_expr_cmp(TCCState *S, ExprValue *pe)
341{339{
342 int op;340 int op;
343 ExprValue e2;341 ExprValue e2;
344 342
345 asm_expr_sum(s1, pe);343 asm_expr_sum(S, pe);
346 for(;;) {344 for(;;) {
347 op = tok;345 op = S->tccpp_tok;
348 if (op != TOK_EQ && op != TOK_NE346 if (op != TOK_EQ && op != TOK_NE
349 && (op > TOK_GT || op < TOK_ULE))347 && (op > TOK_GT || op < TOK_ULE))
350 break;348 break;
351 next();349 next(S);
352 asm_expr_sum(s1, &e2);350 asm_expr_sum(S, &e2);
353 if (pe->sym || e2.sym)351 if (pe->sym || e2.sym)
354 tcc_error("invalid operation with label");352 tcc_error(S, "invalid operation with label");
355 switch(op) {353 switch(op) {
356 case TOK_EQ:354 case TOK_EQ:
357 pe->v = pe->v == e2.v;355 pe->v = pe->v == e2.v;
@@ -379,29 +377,29 @@ static inline void asm_expr_cmp(TCCState *s1, ExprValue *pe) · 21 unmodified lines
379 }377 }
380}378}
381 379
382ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe)380ST_FUNC void asm_expr(TCCState *S, ExprValue *pe)
383{381{
384 asm_expr_cmp(s1, pe);382 asm_expr_cmp(S, pe);
385}383}
386 384
387ST_FUNC int asm_int_expr(TCCState *s1)385ST_FUNC int asm_int_expr(TCCState *S)
388{386{
389 ExprValue e;387 ExprValue e;
390 asm_expr(s1, &e);388 asm_expr(S, &e);
391 if (e.sym)389 if (e.sym)
392 expect("constant");390 expect(S, "constant");
393 return e.v;391 return e.v;
394}392}
395 393
396static Sym* asm_new_label1(TCCState *s1, int label, int is_local,394static Sym* asm_new_label1(TCCState *S, int label, int is_local,
397 int sh_num, int value)395 int sh_num, int value)
398{396{
399 Sym *sym;397 Sym *sym;
400 ElfSym *esym;398 ElfSym *esym;
401 399
402 sym = asm_label_find(label);400 sym = asm_label_find(S, label);
403 if (sym) {401 if (sym) {
404 esym = elfsym(sym);402 esym = elfsym(S, sym);
405 /* A VT_EXTERN symbol, even if it has a section is considered403 /* A VT_EXTERN symbol, even if it has a section is considered
406 overridable. This is how we "define" .set targets. Real404 overridable. This is how we "define" .set targets. Real
407 definitions won't have VT_EXTERN set. */405 definitions won't have VT_EXTERN set. */
@@ -411,16 +409,16 @@ static Sym* asm_new_label1(TCCState *s1, int label, int is_local, · 3 unmodified lines
411 && (is_local == 1 || (sym->type.t & VT_EXTERN)))409 && (is_local == 1 || (sym->type.t & VT_EXTERN)))
412 goto new_label;410 goto new_label;
413 if (!(sym->type.t & VT_EXTERN))411 if (!(sym->type.t & VT_EXTERN))
414 tcc_error("assembler label '%s' already defined",412 tcc_error(S, "assembler label '%s' already defined",
415 get_tok_str(label, NULL));413 get_tok_str(S, label, NULL));
416 }414 }
417 } else {415 } else {
418 new_label:416 new_label:
419 sym = asm_label_push(label);417 sym = asm_label_push(S, label);
420 }418 }
421 if (!sym->c)419 if (!sym->c)
422 put_extern_sym2(sym, SHN_UNDEF, 0, 0, 1);420 put_extern_sym2(S, sym, SHN_UNDEF, 0, 0, 1);
423 esym = elfsym(sym);421 esym = elfsym(S, sym);
424 esym->st_shndx = sh_num;422 esym->st_shndx = sh_num;
425 esym->st_value = value;423 esym->st_value = value;
426 if (is_local != 2)424 if (is_local != 2)
@@ -428,61 +426,61 @@ static Sym* asm_new_label1(TCCState *s1, int label, int is_local, · 1 unmodified line
428 return sym;426 return sym;
429}427}
430 428
431static Sym* asm_new_label(TCCState *s1, int label, int is_local)429static Sym* asm_new_label(TCCState *S, int label, int is_local)
432{430{
433 return asm_new_label1(s1, label, is_local, cur_text_section->sh_num, ind);431 return asm_new_label1(S, label, is_local, cur_text_section->sh_num, S->tccgen_ind);
434}432}
435 433
436/* Set the value of LABEL to that of some expression (possibly434/* Set the value of LABEL to that of some expression (possibly
437 involving other symbols). LABEL can be overwritten later still. */435 involving other symbols). LABEL can be overwritten later still. */
438static Sym* set_symbol(TCCState *s1, int label)436static Sym* set_symbol(TCCState *S, int label)
439{437{
440 long n;438 long n;
441 ExprValue e;439 ExprValue e;
442 Sym *sym;440 Sym *sym;
443 ElfSym *esym;441 ElfSym *esym;
444 next();442 next(S);
445 asm_expr(s1, &e);443 asm_expr(S, &e);
446 n = e.v;444 n = e.v;
447 esym = elfsym(e.sym);445 esym = elfsym(S, e.sym);
448 if (esym)446 if (esym)
449 n += esym->st_value;447 n += esym->st_value;
450 sym = asm_new_label1(s1, label, 2, esym ? esym->st_shndx : SHN_ABS, n);448 sym = asm_new_label1(S, label, 2, esym ? esym->st_shndx : SHN_ABS, n);
451 elfsym(sym)->st_other |= ST_ASM_SET;449 elfsym(S, sym)->st_other |= ST_ASM_SET;
452 return sym;450 return sym;
453}451}
454 452
455static void use_section1(TCCState *s1, Section *sec)453static void use_section1(TCCState *S, Section *sec)
456{454{
457 cur_text_section->data_offset = ind;455 cur_text_section->data_offset = S->tccgen_ind;
458 cur_text_section = sec;456 cur_text_section = sec;
459 ind = cur_text_section->data_offset;457 S->tccgen_ind = cur_text_section->data_offset;
460}458}
461 459
462static void use_section(TCCState *s1, const char *name)460static void use_section(TCCState *S, const char *name)
463{461{
464 Section *sec;462 Section *sec;
465 sec = find_section(s1, name);463 sec = find_section(S, name);
466 use_section1(s1, sec);464 use_section1(S, sec);
467}465}
468 466
469static void push_section(TCCState *s1, const char *name)467static void push_section(TCCState *S, const char *name)
470{468{
471 Section *sec = find_section(s1, name);469 Section *sec = find_section(S, name);
472 sec->prev = cur_text_section;470 sec->prev = cur_text_section;
473 use_section1(s1, sec);471 use_section1(S, sec);
474}472}
475 473
476static void pop_section(TCCState *s1)474static void pop_section(TCCState *S)
477{475{
478 Section *prev = cur_text_section->prev;476 Section *prev = cur_text_section->prev;
479 if (!prev)477 if (!prev)
480 tcc_error(".popsection without .pushsection");478 tcc_error(S, ".popsection without .pushsection");
481 cur_text_section->prev = NULL;479 cur_text_section->prev = NULL;
482 use_section1(s1, prev);480 use_section1(S, prev);
483}481}
484 482
485static void asm_parse_directive(TCCState *s1, int global)483static void asm_parse_directive(TCCState *S, int global)
486{484{
487 int n, offset, v, size, tok1;485 int n, offset, v, size, tok1;
488 Section *sec;486 Section *sec;
@@ -490,27 +488,27 @@ static void asm_parse_directive(TCCState *s1, int global) · 1 unmodified line
490 488
491 /* assembler directive */489 /* assembler directive */
492 sec = cur_text_section;490 sec = cur_text_section;
493 switch(tok) {491 switch(S->tccpp_tok) {
494 case TOK_ASMDIR_align:492 case TOK_ASMDIR_align:
495 case TOK_ASMDIR_balign:493 case TOK_ASMDIR_balign:
496 case TOK_ASMDIR_p2align:494 case TOK_ASMDIR_p2align:
497 case TOK_ASMDIR_skip:495 case TOK_ASMDIR_skip:
498 case TOK_ASMDIR_space:496 case TOK_ASMDIR_space:
499 tok1 = tok;497 tok1 = S->tccpp_tok;
500 next();498 next(S);
501 n = asm_int_expr(s1);499 n = asm_int_expr(S);
502 if (tok1 == TOK_ASMDIR_p2align)500 if (tok1 == TOK_ASMDIR_p2align)
503 {501 {
504 if (n < 0 || n > 30)502 if (n < 0 || n > 30)
505 tcc_error("invalid p2align, must be between 0 and 30");503 tcc_error(S, "invalid p2align, must be between 0 and 30");
506 n = 1 << n;504 n = 1 << n;
507 tok1 = TOK_ASMDIR_align;505 tok1 = TOK_ASMDIR_align;
508 }506 }
509 if (tok1 == TOK_ASMDIR_align || tok1 == TOK_ASMDIR_balign) {507 if (tok1 == TOK_ASMDIR_align || tok1 == TOK_ASMDIR_balign) {
510 if (n < 0 || (n & (n-1)) != 0)508 if (n < 0 || (n & (n-1)) != 0)
511 tcc_error("alignment must be a positive power of two");509 tcc_error(S, "alignment must be a positive power of two");
512 offset = (ind + n - 1) & -n;510 offset = (S->tccgen_ind + n - 1) & -n;
513 size = offset - ind;511 size = offset - S->tccgen_ind;
514 /* the section must have a compatible alignment */512 /* the section must have a compatible alignment */
515 if (sec->sh_addralign < n)513 if (sec->sh_addralign < n)
516 sec->sh_addralign = n;514 sec->sh_addralign = n;
@@ -520,47 +518,47 @@ static void asm_parse_directive(TCCState *s1, int global) · 3 unmodified lines
520 size = n;518 size = n;
521 }519 }
522 v = 0;520 v = 0;
523 if (tok == ',') {521 if (S->tccpp_tok == ',') {
524 next();522 next(S);
525 v = asm_int_expr(s1);523 v = asm_int_expr(S);
526 }524 }
527 zero_pad:525 zero_pad:
528 if (sec->sh_type != SHT_NOBITS) {526 if (sec->sh_type != SHT_NOBITS) {
529 sec->data_offset = ind;527 sec->data_offset = S->tccgen_ind;
530 ptr = section_ptr_add(sec, size);528 ptr = section_ptr_add(S, sec, size);
531 memset(ptr, v, size);529 memset(ptr, v, size);
532 }530 }
533 ind += size;531 S->tccgen_ind += size;
534 break;532 break;
535 case TOK_ASMDIR_quad:533 case TOK_ASMDIR_quad:
536#ifdef TCC_TARGET_X86_64534#ifdef TCC_TARGET_X86_64
537 size = 8;535 size = 8;
538 goto asm_data;536 goto asm_data;
539#else537#else
540 next();538 next(S);
541 for(;;) {539 for(;;) {
542 uint64_t vl;540 uint64_t vl;
543 const char *p;541 const char *p;
544 542
545 p = tokc.str.data;543 p = S->tccpp_tokc.str.data;
546 if (tok != TOK_PPNUM) {544 if (S->tccpp_tok != TOK_PPNUM) {
547 error_constant:545 error_constant:
548 tcc_error("64 bit constant");546 tcc_error(S, "64 bit constant");
549 }547 }
550 vl = strtoll(p, (char **)&p, 0);548 vl = strtoll(p, (char **)&p, 0);
551 if (*p != '\0')549 if (*p != '\0')
552 goto error_constant;550 goto error_constant;
553 next();551 next(S);
554 if (sec->sh_type != SHT_NOBITS) {552 if (sec->sh_type != SHT_NOBITS) {
555 /* XXX: endianness */553 /* XXX: endianness */
556 gen_le32(vl);554 gen_le32(S, vl);
557 gen_le32(vl >> 32);555 gen_le32(S, vl >> 32);
558 } else {556 } else {
559 ind += 8;557 S->tccgen_ind += 8;
560 }558 }
561 if (tok != ',')559 if (S->tccpp_tok != ',')
562 break;560 break;
563 next();561 next(S);
564 }562 }
565 break;563 break;
566#endif564#endif
@@ -575,57 +573,57 @@ static void asm_parse_directive(TCCState *s1, int global) · 8 unmodified lines
575 case TOK_ASMDIR_int:573 case TOK_ASMDIR_int:
576 size = 4;574 size = 4;
577 asm_data:575 asm_data:
578 next();576 next(S);
579 for(;;) {577 for(;;) {
580 ExprValue e;578 ExprValue e;
581 asm_expr(s1, &e);579 asm_expr(S, &e);
582 if (sec->sh_type != SHT_NOBITS) {580 if (sec->sh_type != SHT_NOBITS) {
583 if (size == 4) {581 if (size == 4) {
584 gen_expr32(&e);582 gen_expr32(S, &e);
585#ifdef TCC_TARGET_X86_64583#ifdef TCC_TARGET_X86_64
586 } else if (size == 8) {584 } else if (size == 8) {
587 gen_expr64(&e);585 gen_expr64(S, &e);
588#endif586#endif
589 } else {587 } else {
590 if (e.sym)588 if (e.sym)
591 expect("constant");589 expect(S, "constant");
592 if (size == 1)590 if (size == 1)
593 g(e.v);591 g(S, e.v);
594 else592 else
595 gen_le16(e.v);593 gen_le16(S, e.v);
596 }594 }
597 } else {595 } else {
598 ind += size;596 S->tccgen_ind += size;
599 }597 }
600 if (tok != ',')598 if (S->tccpp_tok != ',')
601 break;599 break;
602 next();600 next(S);
603 }601 }
604 break;602 break;
605 case TOK_ASMDIR_fill:603 case TOK_ASMDIR_fill:
606 {604 {
607 int repeat, size, val, i, j;605 int repeat, size, val, i, j;
608 uint8_t repeat_buf[8];606 uint8_t repeat_buf[8];
609 next();607 next(S);
610 repeat = asm_int_expr(s1);608 repeat = asm_int_expr(S);
611 if (repeat < 0) {609 if (repeat < 0) {
612 tcc_error("repeat < 0; .fill ignored");610 tcc_error(S, "repeat < 0; .fill ignored");
613 break;611 break;
614 }612 }
615 size = 1;613 size = 1;
616 val = 0;614 val = 0;
617 if (tok == ',') {615 if (S->tccpp_tok == ',') {
618 next();616 next(S);
619 size = asm_int_expr(s1);617 size = asm_int_expr(S);
620 if (size < 0) {618 if (size < 0) {
621 tcc_error("size < 0; .fill ignored");619 tcc_error(S, "size < 0; .fill ignored");
622 break;620 break;
623 }621 }
624 if (size > 8)622 if (size > 8)
625 size = 8;623 size = 8;
626 if (tok == ',') {624 if (S->tccpp_tok == ',') {
627 next();625 next(S);
628 val = asm_int_expr(s1);626 val = asm_int_expr(S);
629 }627 }
630 }628 }
631 /* XXX: endianness */629 /* XXX: endianness */
@@ -639,7 +637,7 @@ static void asm_parse_directive(TCCState *s1, int global) · 7 unmodified lines
639 repeat_buf[7] = 0;637 repeat_buf[7] = 0;
640 for(i = 0; i < repeat; i++) {638 for(i = 0; i < repeat; i++) {
641 for(j = 0; j < size; j++) {639 for(j = 0; j < size; j++) {
642 g(repeat_buf[j]);640 g(S, repeat_buf[j]);
643 }641 }
644 }642 }
645 }643 }
@@ -648,24 +646,24 @@ static void asm_parse_directive(TCCState *s1, int global) · 2 unmodified lines
648 {646 {
649 int repeat;647 int repeat;
650 TokenString *init_str;648 TokenString *init_str;
651 next();649 next(S);
652 repeat = asm_int_expr(s1);650 repeat = asm_int_expr(S);
653 init_str = tok_str_alloc();651 init_str = tok_str_alloc(S);
654 while (next(), tok != TOK_ASMDIR_endr) {652 while (next(S), S->tccpp_tok != TOK_ASMDIR_endr) {
655 if (tok == CH_EOF)653 if (S->tccpp_tok == CH_EOF)
656 tcc_error("we at end of file, .endr not found");654 tcc_error(S, "we at end of file, .endr not found");
657 tok_str_add_tok(init_str);655 tok_str_add_tok(S, init_str);
658 }656 }
659 tok_str_add(init_str, -1);657 tok_str_add(S, init_str, -1);
660 tok_str_add(init_str, 0);658 tok_str_add(S, init_str, 0);
661 begin_macro(init_str, 1);659 begin_macro(S, init_str, 1);
662 while (repeat-- > 0) {660 while (repeat-- > 0) {
663 tcc_assemble_internal(s1, (parse_flags & PARSE_FLAG_PREPROCESS),661 tcc_assemble_internal(S, (S->tccpp_parse_flags & PARSE_FLAG_PREPROCESS),
664 global);662 global);
665 macro_ptr = init_str->str;663 S->tccpp_macro_ptr = init_str->str;
666 }664 }
667 end_macro();665 end_macro(S);
668 next();666 next(S);
669 break;667 break;
670 }668 }
671 case TOK_ASMDIR_org:669 case TOK_ASMDIR_org:
@@ -673,49 +671,49 @@ static void asm_parse_directive(TCCState *s1, int global) · 1 unmodified line
673 unsigned long n;671 unsigned long n;
674 ExprValue e;672 ExprValue e;
675 ElfSym *esym;673 ElfSym *esym;
676 next();674 next(S);
677 asm_expr(s1, &e);675 asm_expr(S, &e);
678 n = e.v;676 n = e.v;
679 esym = elfsym(e.sym);677 esym = elfsym(S, e.sym);
680 if (esym) {678 if (esym) {
681 if (esym->st_shndx != cur_text_section->sh_num)679 if (esym->st_shndx != cur_text_section->sh_num)
682 expect("constant or same-section symbol");680 expect(S, "constant or same-section symbol");
683 n += esym->st_value;681 n += esym->st_value;
684 }682 }
685 if (n < ind)683 if (n < S->tccgen_ind)
686 tcc_error("attempt to .org backwards");684 tcc_error(S, "attempt to .org backwards");
687 v = 0;685 v = 0;
688 size = n - ind;686 size = n - S->tccgen_ind;
689 goto zero_pad;687 goto zero_pad;
690 }688 }
691 break;689 break;
692 case TOK_ASMDIR_set:690 case TOK_ASMDIR_set:
693 next();691 next(S);
694 tok1 = tok;692 tok1 = S->tccpp_tok;
695 next();693 next(S);
696 /* Also accept '.set stuff', but don't do anything with this.694 /* Also accept '.set stuff', but don't do anything with this.
697 It's used in GAS to set various features like '.set mips16'. */695 It's used in GAS to set various features like '.set mips16'. */
698 if (tok == ',')696 if (S->tccpp_tok == ',')
699 set_symbol(s1, tok1);697 set_symbol(S, tok1);
700 break;698 break;
701 case TOK_ASMDIR_globl:699 case TOK_ASMDIR_globl:
702 case TOK_ASMDIR_global:700 case TOK_ASMDIR_global:
703 case TOK_ASMDIR_weak:701 case TOK_ASMDIR_weak:
704 case TOK_ASMDIR_hidden:702 case TOK_ASMDIR_hidden:
705 tok1 = tok;703 tok1 = S->tccpp_tok;
706 do { 704 do {
707 Sym *sym;705 Sym *sym;
708 next();706 next(S);
709 sym = get_asm_sym(tok, NULL);707 sym = get_asm_sym(S, S->tccpp_tok, NULL);
710 if (tok1 != TOK_ASMDIR_hidden)708 if (tok1 != TOK_ASMDIR_hidden)
711 sym->type.t &= ~VT_STATIC;709 sym->type.t &= ~VT_STATIC;
712 if (tok1 == TOK_ASMDIR_weak)710 if (tok1 == TOK_ASMDIR_weak)
713 sym->a.weak = 1;711 sym->a.weak = 1;
714 else if (tok1 == TOK_ASMDIR_hidden)712 else if (tok1 == TOK_ASMDIR_hidden)
715 sym->a.visibility = STV_HIDDEN;713 sym->a.visibility = STV_HIDDEN;
716 update_storage(sym);714 update_storage(S, sym);
717 next();715 next(S);
718 } while (tok == ',');716 } while (S->tccpp_tok == ',');
719 break;717 break;
720 case TOK_ASMDIR_string:718 case TOK_ASMDIR_string:
721 case TOK_ASMDIR_ascii:719 case TOK_ASMDIR_ascii:
@@ -724,21 +722,21 @@ static void asm_parse_directive(TCCState *s1, int global) · 2 unmodified lines
724 const uint8_t *p;722 const uint8_t *p;
725 int i, size, t;723 int i, size, t;
726 724
727 t = tok;725 t = S->tccpp_tok;
728 next();726 next(S);
729 for(;;) {727 for(;;) {
730 if (tok != TOK_STR)728 if (S->tccpp_tok != TOK_STR)
731 expect("string constant");729 expect(S, "string constant");
732 p = tokc.str.data;730 p = S->tccpp_tokc.str.data;
733 size = tokc.str.size;731 size = S->tccpp_tokc.str.size;
734 if (t == TOK_ASMDIR_ascii && size > 0)732 if (t == TOK_ASMDIR_ascii && size > 0)
735 size--;733 size--;
736 for(i = 0; i < size; i++)734 for(i = 0; i < size; i++)
737 g(p[i]);735 g(S, p[i]);
738 next();736 next(S);
739 if (tok == ',') {737 if (S->tccpp_tok == ',') {
740 next();738 next(S);
741 } else if (tok != TOK_STR) {739 } else if (S->tccpp_tok != TOK_STR) {
742 break;740 break;
743 }741 }
744 }742 }
@@ -749,18 +747,18 @@ static void asm_parse_directive(TCCState *s1, int global) · 4 unmodified lines
749 case TOK_ASMDIR_bss:747 case TOK_ASMDIR_bss:
750 { 748 {
751 char sname[64];749 char sname[64];
752 tok1 = tok;750 tok1 = S->tccpp_tok;
753 n = 0;751 n = 0;
754 next();752 next(S);
755 if (tok != ';' && tok != TOK_LINEFEED) {753 if (S->tccpp_tok != ';' && S->tccpp_tok != TOK_LINEFEED) {
756 n = asm_int_expr(s1);754 n = asm_int_expr(S);
757 next();755 next(S);
758 }756 }
759 if (n)757 if (n)
760 sprintf(sname, "%s%d", get_tok_str(tok1, NULL), n);758 sprintf(sname, "%s%d", get_tok_str(S, tok1, NULL), n);
761 else759 else
762 sprintf(sname, "%s", get_tok_str(tok1, NULL));760 sprintf(sname, "%s", get_tok_str(S, tok1, NULL));
763 use_section(s1, sname);761 use_section(S, sname);
764 }762 }
765 break;763 break;
766 case TOK_ASMDIR_file:764 case TOK_ASMDIR_file:
@@ -768,13 +766,13 @@ static void asm_parse_directive(TCCState *s1, int global) · 1 unmodified line
768 char filename[512];766 char filename[512];
769 767
770 filename[0] = '\0';768 filename[0] = '\0';
771 next();769 next(S);
772 if (tok == TOK_STR)770 if (S->tccpp_tok == TOK_STR)
773 pstrcat(filename, sizeof(filename), tokc.str.data);771 pstrcat(filename, sizeof(filename), S->tccpp_tokc.str.data);
774 else772 else
775 pstrcat(filename, sizeof(filename), get_tok_str(tok, NULL));773 pstrcat(filename, sizeof(filename), get_tok_str(S, S->tccpp_tok, NULL));
776 tcc_warning_c(warn_unsupported)("ignoring .file %s", filename);774 tcc_warning_c(warn_unsupported)(S, "ignoring .file %s", filename);
777 next();775 next(S);
778 }776 }
779 break;777 break;
780 case TOK_ASMDIR_ident:778 case TOK_ASMDIR_ident:
@@ -782,30 +780,30 @@ static void asm_parse_directive(TCCState *s1, int global) · 1 unmodified line
782 char ident[256];780 char ident[256];
783 781
784 ident[0] = '\0';782 ident[0] = '\0';
785 next();783 next(S);
786 if (tok == TOK_STR)784 if (S->tccpp_tok == TOK_STR)
787 pstrcat(ident, sizeof(ident), tokc.str.data);785 pstrcat(ident, sizeof(ident), S->tccpp_tokc.str.data);
788 else786 else
789 pstrcat(ident, sizeof(ident), get_tok_str(tok, NULL));787 pstrcat(ident, sizeof(ident), get_tok_str(S, S->tccpp_tok, NULL));
790 tcc_warning_c(warn_unsupported)("ignoring .ident %s", ident);788 tcc_warning_c(warn_unsupported)(S, "ignoring .ident %s", ident);
791 next();789 next(S);
792 }790 }
793 break;791 break;
794 case TOK_ASMDIR_size:792 case TOK_ASMDIR_size:
795 { 793 {
796 Sym *sym;794 Sym *sym;
797 795
798 next();796 next(S);
799 sym = asm_label_find(tok);797 sym = asm_label_find(S, S->tccpp_tok);
800 if (!sym) {798 if (!sym) {
801 tcc_error("label not found: %s", get_tok_str(tok, NULL));799 tcc_error(S, "label not found: %s", get_tok_str(S, S->tccpp_tok, NULL));
802 }800 }
803 /* XXX .size name,label2-label1 */801 /* XXX .size name,label2-label1 */
804 tcc_warning_c(warn_unsupported)("ignoring .size %s,*", get_tok_str(tok, NULL));802 tcc_warning_c(warn_unsupported)(S, "ignoring .size %s,*", get_tok_str(S, S->tccpp_tok, NULL));
805 next();803 next(S);
806 skip(',');804 skip(S, ',');
807 while (tok != TOK_LINEFEED && tok != ';' && tok != CH_EOF) {805 while (S->tccpp_tok != TOK_LINEFEED && S->tccpp_tok != ';' && S->tccpp_tok != CH_EOF) {
808 next();806 next(S);
809 }807 }
810 }808 }
811 break;809 break;
@@ -814,182 +812,182 @@ static void asm_parse_directive(TCCState *s1, int global) · 2 unmodified lines
814 Sym *sym;812 Sym *sym;
815 const char *newtype;813 const char *newtype;
816 814
817 next();815 next(S);
818 sym = get_asm_sym(tok, NULL);816 sym = get_asm_sym(S, S->tccpp_tok, NULL);
819 next();817 next(S);
820 skip(',');818 skip(S, ',');
821 if (tok == TOK_STR) {819 if (S->tccpp_tok == TOK_STR) {
822 newtype = tokc.str.data;820 newtype = S->tccpp_tokc.str.data;
823 } else {821 } else {
824 if (tok == '@' || tok == '%')822 if (S->tccpp_tok == '@' || S->tccpp_tok == '%')
825 next();823 next(S);
826 newtype = get_tok_str(tok, NULL);824 newtype = get_tok_str(S, S->tccpp_tok, NULL);
827 }825 }
828 826
829 if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) {827 if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) {
830 sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC;828 sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC;
831 } else829 } else
832 tcc_warning_c(warn_unsupported)("change type of '%s' from 0x%x to '%s' ignored",830 tcc_warning_c(warn_unsupported)(S, "change type of '%s' from 0x%x to '%s' ignored",
833 get_tok_str(sym->v, NULL), sym->type.t, newtype);831 get_tok_str(S, sym->v, NULL), sym->type.t, newtype);
834 832
835 next();833 next(S);
836 }834 }
837 break;835 break;
838 case TOK_ASMDIR_pushsection:836 case TOK_ASMDIR_pushsection:
839 case TOK_ASMDIR_section:837 case TOK_ASMDIR_section:
840 {838 {
841 char sname[256];839 char sname[256];
842 int old_nb_section = s1->nb_sections;840 int old_nb_section = S->nb_sections;
843 841
844 tok1 = tok;842 tok1 = S->tccpp_tok;
845 /* XXX: support more options */843 /* XXX: support more options */
846 next();844 next(S);
847 sname[0] = '\0';845 sname[0] = '\0';
848 while (tok != ';' && tok != TOK_LINEFEED && tok != ',') {846 while (S->tccpp_tok != ';' && S->tccpp_tok != TOK_LINEFEED && S->tccpp_tok != ',') {
849 if (tok == TOK_STR)847 if (S->tccpp_tok == TOK_STR)
850 pstrcat(sname, sizeof(sname), tokc.str.data);848 pstrcat(sname, sizeof(sname), S->tccpp_tokc.str.data);
851 else849 else
852 pstrcat(sname, sizeof(sname), get_tok_str(tok, NULL));850 pstrcat(sname, sizeof(sname), get_tok_str(S, S->tccpp_tok, NULL));
853 next();851 next(S);
854 }852 }
855 if (tok == ',') {853 if (S->tccpp_tok == ',') {
856 /* skip section options */854 /* skip section options */
857 next();855 next(S);
858 if (tok != TOK_STR)856 if (S->tccpp_tok != TOK_STR)
859 expect("string constant");857 expect(S, "string constant");
860 next();858 next(S);
861 if (tok == ',') {859 if (S->tccpp_tok == ',') {
862 next();860 next(S);
863 if (tok == '@' || tok == '%')861 if (S->tccpp_tok == '@' || S->tccpp_tok == '%')
864 next();862 next(S);
865 next();863 next(S);
866 }864 }
867 }865 }
868 last_text_section = cur_text_section;866 S->tccasm_last_text_section = cur_text_section;
869 if (tok1 == TOK_ASMDIR_section)867 if (tok1 == TOK_ASMDIR_section)
870 use_section(s1, sname);868 use_section(S, sname);
871 else869 else
872 push_section(s1, sname);870 push_section(S, sname);
873 /* If we just allocated a new section reset its alignment to871 /* If we just allocated a new section reset its alignment to
874 1. new_section normally acts for GCC compatibility and872 1. new_section normally acts for GCC compatibility and
875 sets alignment to PTR_SIZE. The assembler behaves different. */873 sets alignment to PTR_SIZE. The assembler behaves different. */
876 if (old_nb_section != s1->nb_sections)874 if (old_nb_section != S->nb_sections)
877 cur_text_section->sh_addralign = 1;875 cur_text_section->sh_addralign = 1;
878 }876 }
879 break;877 break;
880 case TOK_ASMDIR_previous:878 case TOK_ASMDIR_previous:
881 { 879 {
882 Section *sec;880 Section *sec;
883 next();881 next(S);
884 if (!last_text_section)882 if (!S->tccasm_last_text_section)
885 tcc_error("no previous section referenced");883 tcc_error(S, "no previous section referenced");
886 sec = cur_text_section;884 sec = cur_text_section;
887 use_section1(s1, last_text_section);885 use_section1(S, S->tccasm_last_text_section);
888 last_text_section = sec;886 S->tccasm_last_text_section = sec;
889 }887 }
890 break;888 break;
891 case TOK_ASMDIR_popsection:889 case TOK_ASMDIR_popsection:
892 next();890 next(S);
893 pop_section(s1);891 pop_section(S);
894 break;892 break;
895#ifdef TCC_TARGET_I386893#ifdef TCC_TARGET_I386
896 case TOK_ASMDIR_code16:894 case TOK_ASMDIR_code16:
897 {895 {
898 next();896 next(S);
899 s1->seg_size = 16;897 S->seg_size = 16;
900 }898 }
901 break;899 break;
902 case TOK_ASMDIR_code32:900 case TOK_ASMDIR_code32:
903 {901 {
904 next();902 next(S);
905 s1->seg_size = 32;903 S->seg_size = 32;
906 }904 }
907 break;905 break;
908#endif906#endif
909#ifdef TCC_TARGET_X86_64907#ifdef TCC_TARGET_X86_64
910 /* added for compatibility with GAS */908 /* added for compatibility with GAS */
911 case TOK_ASMDIR_code64:909 case TOK_ASMDIR_code64:
912 next();910 next(S);
913 break;911 break;
914#endif912#endif
915 default:913 default:
916 tcc_error("unknown assembler directive '.%s'", get_tok_str(tok, NULL));914 tcc_error(S, "unknown assembler directive '.%s'", get_tok_str(S, S->tccpp_tok, NULL));
917 break;915 break;
918 }916 }
919}917}
920 918
921 919
922/* assemble a file */920/* assemble a file */
923static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global)921static int tcc_assemble_internal(TCCState *S, int do_preprocess, int global)
924{922{
925 int opcode;923 int opcode;
926 int saved_parse_flags = parse_flags;924 int saved_parse_flags = S->tccpp_parse_flags;
927 925
928 parse_flags = PARSE_FLAG_ASM_FILE | PARSE_FLAG_TOK_STR;926 S->tccpp_parse_flags = PARSE_FLAG_ASM_FILE | PARSE_FLAG_TOK_STR;
929 if (do_preprocess)927 if (do_preprocess)
930 parse_flags |= PARSE_FLAG_PREPROCESS;928 S->tccpp_parse_flags |= PARSE_FLAG_PREPROCESS;
931 for(;;) {929 for(;;) {
932 next();930 next(S);
933 if (tok == TOK_EOF)931 if (S->tccpp_tok == TOK_EOF)
934 break;932 break;
935 parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */933 S->tccpp_parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
936 redo:934 redo:
937 if (tok == '#') {935 if (S->tccpp_tok == '#') {
938 /* horrible gas comment */936 /* horrible gas comment */
939 while (tok != TOK_LINEFEED)937 while (S->tccpp_tok != TOK_LINEFEED)
940 next();938 next(S);
941 } else if (tok >= TOK_ASMDIR_FIRST && tok <= TOK_ASMDIR_LAST) {939 } else if (S->tccpp_tok >= TOK_ASMDIR_FIRST && S->tccpp_tok <= TOK_ASMDIR_LAST) {
942 asm_parse_directive(s1, global);940 asm_parse_directive(S, global);
943 } else if (tok == TOK_PPNUM) {941 } else if (S->tccpp_tok == TOK_PPNUM) {
944 const char *p;942 const char *p;
945 int n;943 int n;
946 p = tokc.str.data;944 p = S->tccpp_tokc.str.data;
947 n = strtoul(p, (char **)&p, 10);945 n = strtoul(p, (char **)&p, 10);
948 if (*p != '\0')946 if (*p != '\0')
949 expect("':'");947 expect(S, "':'");
950 /* new local label */948 /* new local label */
951 asm_new_label(s1, asm_get_local_label_name(s1, n), 1);949 asm_new_label(S, asm_get_local_label_name(S, n), 1);
952 next();950 next(S);
953 skip(':');951 skip(S, ':');
954 goto redo;952 goto redo;
955 } else if (tok >= TOK_IDENT) {953 } else if (S->tccpp_tok >= TOK_IDENT) {
956 /* instruction or label */954 /* instruction or label */
957 opcode = tok;955 opcode = S->tccpp_tok;
958 next();956 next(S);
959 if (tok == ':') {957 if (S->tccpp_tok == ':') {
960 /* new label */958 /* new label */
961 asm_new_label(s1, opcode, 0);959 asm_new_label(S, opcode, 0);
962 next();960 next(S);
963 goto redo;961 goto redo;
964 } else if (tok == '=') {962 } else if (S->tccpp_tok == '=') {
965 set_symbol(s1, opcode);963 set_symbol(S, opcode);
966 goto redo;964 goto redo;
967 } else {965 } else {
968 asm_opcode(s1, opcode);966 asm_opcode(S, opcode);
969 }967 }
970 }968 }
971 /* end of line */969 /* end of line */
972 if (tok != ';' && tok != TOK_LINEFEED)970 if (S->tccpp_tok != ';' && S->tccpp_tok != TOK_LINEFEED)
973 expect("end of line");971 expect(S, "end of line");
974 parse_flags &= ~PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */972 S->tccpp_parse_flags &= ~PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
975 }973 }
976 974
977 parse_flags = saved_parse_flags;975 S->tccpp_parse_flags = saved_parse_flags;
978 return 0;976 return 0;
979}977}
980 978
981/* Assemble the current file */979/* Assemble the current file */
982ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess)980ST_FUNC int tcc_assemble(TCCState *S, int do_preprocess)
983{981{
984 int ret;982 int ret;
985 tcc_debug_start(s1);983 tcc_debug_start(S);
986 /* default section is text */984 /* default section is text */
987 cur_text_section = text_section;985 cur_text_section = text_section;
988 ind = cur_text_section->data_offset;986 S->tccgen_ind = cur_text_section->data_offset;
989 nocode_wanted = 0;987 S->tccgen_nocode_wanted = 0;
990 ret = tcc_assemble_internal(s1, do_preprocess, 1);988 ret = tcc_assemble_internal(S, do_preprocess, 1);
991 cur_text_section->data_offset = ind;989 cur_text_section->data_offset = S->tccgen_ind;
992 tcc_debug_end(s1);990 tcc_debug_end(S);
993 return ret;991 return ret;
994}992}
995 993
@@ -999,27 +997,27 @@ ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess) · 3 unmodified lines
999/* assemble the string 'str' in the current C compilation unit without997/* assemble the string 'str' in the current C compilation unit without
1000 C preprocessing. NOTE: str is modified by modifying the '\0' at the998 C preprocessing. NOTE: str is modified by modifying the '\0' at the
1001 end */999 end */
1002static void tcc_assemble_inline(TCCState *s1, char *str, int len, int global)1000static void tcc_assemble_inline(TCCState *S, char *str, int len, int global)
1003{1001{
1004 const int *saved_macro_ptr = macro_ptr;1002 const int *saved_macro_ptr = S->tccpp_macro_ptr;
1005 int dotid = set_idnum('.', IS_ID);1003 int dotid = set_idnum(S, '.', IS_ID);
1006 int dolid = set_idnum('$', 0);1004 int dolid = set_idnum(S, '$', 0);
1007 1005
1008 tcc_open_bf(s1, ":asm:", len);1006 tcc_open_bf(S, ":asm:", len);
1009 memcpy(file->buffer, str, len);1007 memcpy(S->tccpp_file->buffer, str, len);
1010 macro_ptr = NULL;1008 S->tccpp_macro_ptr = NULL;
1011 tcc_assemble_internal(s1, 0, global);1009 tcc_assemble_internal(S, 0, global);
1012 tcc_close();1010 tcc_close(S);
1013 1011
1014 set_idnum('$', dolid);1012 set_idnum(S, '$', dolid);
1015 set_idnum('.', dotid);1013 set_idnum(S, '.', dotid);
1016 macro_ptr = saved_macro_ptr;1014 S->tccpp_macro_ptr = saved_macro_ptr;
1017}1015}
1018 1016
1019/* find a constraint by its number or id (gcc 3 extended1017/* find a constraint by its number or id (gcc 3 extended
1020 syntax). return -1 if not found. Return in *pp in char after the1018 syntax). return -1 if not found. Return in *pp in char after the
1021 constraint */1019 constraint */
1022ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands, 1020ST_FUNC int find_constraint(TCCState* S, ASMOperand *operands, int nb_operands,
1023 const char *name, const char **pp)1021 const char *name, const char **pp)
1024{1022{
1025 int index;1023 int index;
@@ -1038,7 +1036,7 @@ ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands, · 12 unmodified lines
1038 name++;1036 name++;
1039 p = strchr(name, ']');1037 p = strchr(name, ']');

339 more lines aren’t shown here.

tcccoff.c+58−58

This diff is large: its 368 lines aren’t shown here.

tccelf.c+672−675

This diff is large: its 3251 lines aren’t shown here.

tccgen.c+2636−2728

This diff is large: its 9788 lines aren’t shown here.

tccmacho.c+112−113

This diff is large: its 616 lines aren’t shown here.

tccpe.c+177−178

This diff is large: its 960 lines aren’t shown here.

tccpp.c+1063−1108

This diff is large: its 4250 lines aren’t shown here.

tccqsort.c+261−0

This diff is large: its 262 lines aren’t shown here.

tccrun.c+64−64

This diff is large: its 311 lines aren’t shown here.

tcctools.c+27−27

This diff is large: its 188 lines aren’t shown here.

x86_64-gen.c+667−680

This diff is large: its 2366 lines aren’t shown here.

x86_64-link.c+38−38

This diff is large: its 222 lines aren’t shown here.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t