History

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

This reverts commit af686a796bda94dc92fc3ad140ef438dafa08950.

mingodad committed 5 years ago

Commit 16456161 parent 2ce2dbc30 files · +10750 −11217Browse files

Unified · Split

30 files
  1. arm-asm.c +556 −556
  2. arm-gen.c +570 −563
  3. arm-link.c +32 −32
  4. arm64-asm.c +13 −13
  5. arm64-gen.c +647 −641
  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 +368 −365
  11. i386-link.c +34 −34
  12. libtcc.c +393 −470
  13. libtcc.h +21 −72
  14. riscv64-asm.c +187 −187
  15. riscv64-gen.c +457 −451
  16. riscv64-link.c +30 −30
  17. tcc.c +70 −168
  18. tcc.h +299 −458
  19. tccasm.c +420 −418
  20. tcccoff.c +58 −58
  21. tccelf.c +675 −672
  22. tccgen.c +2728 −2636
  23. tccmacho.c +113 −112
  24. tccpe.c +178 −177
  25. tccpp.c +1108 −1063
  26. tccqsort.c +0 −261
  27. tccrun.c +64 −64
  28. tcctools.c +27 −27
  29. x86_64-gen.c +680 −667
  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(TCCState* S, int c);27ST_FUNC void g(int c);
28ST_FUNC void gen_le16(TCCState* S, int c);28ST_FUNC void gen_le16(int c);
29ST_FUNC void gen_le32(TCCState* S, int c);29ST_FUNC void gen_le32(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 *S, Operand *op)95static void parse_operand(TCCState *s1, 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 *S, Operand *op) · 1 unmodified line
100 100
101 op->type = 0;101 op->type = 0;
102 102
103 if (S->tccpp_tok == '{') { // regset literal103 if (tok == '{') { // regset literal
104 next(S); // skip '{'104 next(); // skip '{'
105 while (S->tccpp_tok != '}' && S->tccpp_tok != TOK_EOF) {105 while (tok != '}' && tok != TOK_EOF) {
106 reg = asm_parse_regvar(S, S->tccpp_tok);106 reg = asm_parse_regvar(tok);
107 if (reg == -1) {107 if (reg == -1) {
108 expect(S, "register");108 expect("register");
109 return;109 return;
110 } else110 } else
111 next(S); // skip register name111 next(); // skip register name
112 112
113 if ((1 << reg) < regset)113 if ((1 << reg) < regset)
114 tcc_warning(S, "registers will be processed in ascending order by hardware--but are not specified in ascending order here");114 tcc_warning("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 (S->tccpp_tok != ',')116 if (tok != ',')
117 break;117 break;
118 next(S); // skip ','118 next(); // skip ','
119 }119 }
120 if (S->tccpp_tok != '}')120 if (tok != '}')
121 expect(S, "'}'");121 expect("'}'");
122 next(S); // skip '}'122 next(); // 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(S, "empty register list is not supported");125 tcc_error("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(S, S->tccpp_tok)) != -1) {131 } else if ((reg = asm_parse_regvar(tok)) != -1) {
132 next(S); // skip register name132 next(); // 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(S->tccpp_tok, 0)) != -1) {136 } else if ((reg = asm_parse_vfp_regvar(tok, 0)) != -1) {
137 next(S); // skip register name137 next(); // 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(S->tccpp_tok, 1)) != -1) {141 } else if ((reg = asm_parse_vfp_regvar(tok, 1)) != -1) {
142 next(S); // skip register name142 next(); // 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 (S->tccpp_tok == '#' || S->tccpp_tok == '$') {146 } else if (tok == '#' || tok == '$') {
147 /* constant value */147 /* constant value */
148 next(S); // skip '#' or '$'148 next(); // skip '#' or '$'
149 }149 }
150 asm_expr(S, &e);150 asm_expr(s1, &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 *S, 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(S, "operand");159 expect("operand");
160}160}
161 161
162/* XXX: make it faster ? */162/* XXX: make it faster ? */
163ST_FUNC void g(TCCState* S, int c)163ST_FUNC void g(int c)
164{164{
165 int ind1;165 int ind1;
166 if (S->tccgen_nocode_wanted)166 if (nocode_wanted)
167 return;167 return;
168 ind1 = S->tccgen_ind + 1;168 ind1 = ind + 1;
169 if (ind1 > cur_text_section->data_allocated)169 if (ind1 > cur_text_section->data_allocated)
170 section_realloc(S, cur_text_section, ind1);170 section_realloc(cur_text_section, ind1);
171 cur_text_section->data[S->tccgen_ind] = c;171 cur_text_section->data[ind] = c;
172 S->tccgen_ind = ind1;172 ind = ind1;
173}173}
174 174
175ST_FUNC void gen_le16 (TCCState* S, int i)175ST_FUNC void gen_le16 (int i)
176{176{
177 g(S, i);177 g(i);
178 g(S, i>>8);178 g(i>>8);
179}179}
180 180
181ST_FUNC void gen_le32 (TCCState* S, int i)181ST_FUNC void gen_le32 (int i)
182{182{
183 int ind1;183 int ind1;
184 if (S->tccgen_nocode_wanted)184 if (nocode_wanted)
185 return;185 return;
186 ind1 = S->tccgen_ind + 4;186 ind1 = ind + 4;
187 if (ind1 > cur_text_section->data_allocated)187 if (ind1 > cur_text_section->data_allocated)
188 section_realloc(S, cur_text_section, ind1);188 section_realloc(cur_text_section, ind1);
189 cur_text_section->data[S->tccgen_ind++] = i & 0xFF;189 cur_text_section->data[ind++] = i & 0xFF;
190 cur_text_section->data[S->tccgen_ind++] = (i >> 8) & 0xFF;190 cur_text_section->data[ind++] = (i >> 8) & 0xFF;
191 cur_text_section->data[S->tccgen_ind++] = (i >> 16) & 0xFF;191 cur_text_section->data[ind++] = (i >> 16) & 0xFF;
192 cur_text_section->data[S->tccgen_ind++] = (i >> 24) & 0xFF;192 cur_text_section->data[ind++] = (i >> 24) & 0xFF;
193}193}
194 194
195ST_FUNC void gen_expr32(TCCState* S, ExprValue *pe)195ST_FUNC void gen_expr32(ExprValue *pe)
196{196{
197 gen_le32(S, pe->v);197 gen_le32(pe->v);
198}198}
199 199
200static uint32_t condition_code_of_token(TCCState* S, int token) {200static uint32_t condition_code_of_token(int token) {
201 if (token < TOK_ASM_nopeq) {201 if (token < TOK_ASM_nopeq) {
202 expect(S, "condition-enabled instruction");202 expect("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(TCCState* S, int token, uint32_t opcode) {208static void asm_emit_opcode(int token, uint32_t opcode) {
209 gen_le32(S, (condition_code_of_token(S, token) << 28) | opcode);209 gen_le32((condition_code_of_token(token) << 28) | opcode);
210}210}
211 211
212static void asm_emit_unconditional_opcode(TCCState* S, uint32_t opcode) {212static void asm_emit_unconditional_opcode(uint32_t opcode) {
213 gen_le32(S, opcode);213 gen_le32(opcode);
214}214}
215 215
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)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)
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(TCCState* S, uint32_t high_nibble, uint8 · 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(S, (high_nibble << 28) | opcode);233 asm_emit_unconditional_opcode((high_nibble << 28) | opcode);
234}234}
235 235
236static void asm_nullary_opcode(TCCState* S, int token)236static void asm_nullary_opcode(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(S, token, 0xd << 21); // mov r0, r0240 asm_emit_opcode(token, 0xd << 21); // mov r0, r0
241 break;241 break;
242 case TOK_ASM_wfeeq:242 case TOK_ASM_wfeeq:
243 asm_emit_opcode(S, token, 0x320f002);243 asm_emit_opcode(token, 0x320f002);
244 case TOK_ASM_wfieq:244 case TOK_ASM_wfieq:
245 asm_emit_opcode(S, token, 0x320f003);245 asm_emit_opcode(token, 0x320f003);
246 break;246 break;
247 default:247 default:
248 expect(S, "nullary instruction");248 expect("nullary instruction");
249 }249 }
250}250}
251 251
252static void asm_unary_opcode(TCCState *S, int token)252static void asm_unary_opcode(TCCState *s1, int token)
253{253{
254 Operand op;254 Operand op;
255 parse_operand(S, &op);255 parse_operand(s1, &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(S, "immediate 8-bit unsigned integer");261 expect("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(S, token, (0xf << 24) | op.e.v);264 asm_emit_opcode(token, (0xf << 24) | op.e.v);
265 }265 }
266 break;266 break;
267 default:267 default:
268 expect(S, "unary instruction");268 expect("unary instruction");
269 }269 }
270}270}
271 271
272static void asm_binary_opcode(TCCState *S, int token)272static void asm_binary_opcode(TCCState *s1, 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(S, &ops[0]);278 parse_operand(s1, &ops[0]);
279 if (S->tccpp_tok == ',')279 if (tok == ',')
280 next(S);280 next();
281 else281 else
282 expect(S, "','");282 expect("','");
283 parse_operand(S, &ops[1]);283 parse_operand(s1, &ops[1]);
284 if (ops[0].type != OP_REG32) {284 if (ops[0].type != OP_REG32) {
285 expect(S, "(destination operand) register");285 expect("(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, "'%s' does not support 'pc' as operand", get_tok_str(S, token, NULL));290 tcc_error("'%s' does not support 'pc' as operand", get_tok_str(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(S, "Using 'sp' as operand with '%s' is deprecated by ARM", get_tok_str(S, token, NULL));295 tcc_warning("Using 'sp' as operand with '%s' is deprecated by ARM", get_tok_str(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 *S, 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(S, token, 0x3400000 | (ops[0].reg << 12) | (immediate_value & 0xF000) << 4 | (immediate_value & 0xFFF));306 asm_emit_opcode(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(S, token, 0x3000000 | (ops[0].reg << 12) | (immediate_value & 0xF000) << 4 | (immediate_value & 0xFFF));309 asm_emit_opcode(token, 0x3000000 | (ops[0].reg << 12) | (immediate_value & 0xF000) << 4 | (immediate_value & 0xFFF));
310 break;310 break;
311 }311 }
312 } else312 } else
313 expect(S, "(source operand) immediate 16 bit value");313 expect("(source operand) immediate 16 bit value");
314 } else314 } else
315 expect(S, "(source operand) immediate");315 expect("(source operand) immediate");
316 break;316 break;
317 default:317 default:
318 expect(S, "(source operand) register");318 expect("(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, "'%s' does not support 'pc' as operand", get_tok_str(S, token, NULL));324 tcc_error("'%s' does not support 'pc' as operand", get_tok_str(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(S, "Using 'sp' as operand with '%s' is deprecated by ARM", get_tok_str(S, token, NULL));329 tcc_warning("Using 'sp' as operand with '%s' is deprecated by ARM", get_tok_str(token, NULL));
330 330
331 if (S->tccpp_tok == ',') {331 if (tok == ',') {
332 next(S); // skip ','332 next(); // skip ','
333 if (S->tccpp_tok == TOK_ASM_ror) {333 if (tok == TOK_ASM_ror) {
334 next(S); // skip 'ror'334 next(); // skip 'ror'
335 parse_operand(S, &rotation);335 parse_operand(s1, &rotation);
336 if (rotation.type != OP_IM8) {336 if (rotation.type != OP_IM8) {
337 expect(S, "immediate value for rotation");337 expect("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 *S, 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(S, "'8' or '16' or '24'");352 expect("'8' or '16' or '24'");
353 return;353 return;
354 }354 }
355 }355 }
@@ -358,27 +358,27 @@ static void asm_binary_opcode(TCCState *S, 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(S, "clz does not support rotation");361 tcc_error("clz does not support rotation");
362 asm_emit_opcode(S, token, 0x16f0f10 | (ops[0].reg << 12) | ops[1].reg);362 asm_emit_opcode(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(S, token, 0x6af0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation);365 asm_emit_opcode(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(S, token, 0x6bf0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation);368 asm_emit_opcode(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(S, token, 0x6ef0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation);371 asm_emit_opcode(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(S, token, 0x6ff0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation);374 asm_emit_opcode(token, 0x6ff0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation);
375 break;375 break;
376 default:376 default:
377 expect(S, "binary instruction");377 expect("binary instruction");
378 }378 }
379}379}
380 380
381static void asm_coprocessor_opcode(TCCState *S, int token) {381static void asm_coprocessor_opcode(TCCState *s1, 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 *S, 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 (S->tccpp_tok >= TOK_ASM_p0 && S->tccpp_tok <= TOK_ASM_p15) {390 if (tok >= TOK_ASM_p0 && tok <= TOK_ASM_p15) {
391 coprocessor = S->tccpp_tok - TOK_ASM_p0;391 coprocessor = tok - TOK_ASM_p0;
392 next(S);392 next();
393 } else {393 } else {
394 expect(S, "'p<number>'");394 expect("'p<number>'");
395 return;395 return;
396 }396 }
397 397
398 if (S->tccpp_tok == ',')398 if (tok == ',')
399 next(S);399 next();
400 else400 else
401 expect(S, "','");401 expect("','");
402 402
403 parse_operand(S, &opcode1);403 parse_operand(s1, &opcode1);
404 if (opcode1.type != OP_IM8 || opcode1.e.v > 15) {404 if (opcode1.type != OP_IM8 || opcode1.e.v > 15) {
405 tcc_error(S, "opcode1 of instruction '%s' must be an immediate value between 0 and 15", get_tok_str(S, token, NULL));405 tcc_error("opcode1 of instruction '%s' must be an immediate value between 0 and 15", get_tok_str(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 (S->tccpp_tok == ',')410 if (tok == ',')
411 next(S);411 next();
412 else412 else
413 expect(S, "','");413 expect("','");
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 (S->tccpp_tok >= TOK_ASM_r0 && S->tccpp_tok <= TOK_ASM_r15) {415 if (tok >= TOK_ASM_r0 && tok <= TOK_ASM_r15) {
416 registers[i] = S->tccpp_tok - TOK_ASM_r0;416 registers[i] = tok - TOK_ASM_r0;
417 next(S);417 next();
418 } else {418 } else {
419 expect(S, "'r<number>'");419 expect("'r<number>'");
420 return;420 return;
421 }421 }
422 } else {422 } else {
423 if (S->tccpp_tok >= TOK_ASM_c0 && S->tccpp_tok <= TOK_ASM_c15) {423 if (tok >= TOK_ASM_c0 && tok <= TOK_ASM_c15) {
424 registers[i] = S->tccpp_tok - TOK_ASM_c0;424 registers[i] = tok - TOK_ASM_c0;
425 next(S);425 next();
426 } else {426 } else {
427 expect(S, "'c<number>'");427 expect("'c<number>'");
428 return;428 return;
429 }429 }
430 }430 }
431 }431 }
432 if (S->tccpp_tok == ',') {432 if (tok == ',') {
433 next(S);433 next();
434 parse_operand(S, &opcode2);434 parse_operand(s1, &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(S, "opcode2 of instruction '%s' must be an immediate value between 0 and 15", get_tok_str(S, token, NULL));440 tcc_error("opcode2 of instruction '%s' must be an immediate value between 0 and 15", get_tok_str(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(S, high_nibble, coprocessor, opcode1.e.v, registers[0], registers[1], registers[2], opcode2.e.v, 0);446 asm_emit_coprocessor_opcode(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(S, token);449 high_nibble = condition_code_of_token(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(S, high_nibble, coprocessor, opcode1.e.v, registers[0], registers[1], registers[2], opcode2.e.v, 0);453 asm_emit_coprocessor_opcode(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 *S, 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(S, "opcode1 of instruction '%s' must be an immediate value between 0 and 7", get_tok_str(S, token, NULL));462 tcc_error("opcode1 of instruction '%s' must be an immediate value between 0 and 7", get_tok_str(token, NULL));
463 return;463 return;
464 }464 }
465 asm_emit_coprocessor_opcode(S, high_nibble, coprocessor, (opcode1.e.v << 1) | mrc, registers[0], registers[1], registers[2], opcode2.e.v, 1);465 asm_emit_coprocessor_opcode(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(S, "known instruction");468 expect("known instruction");
469 }469 }
470}470}
471 471
@@ -486,27 +486,27 @@ static void asm_coprocessor_opcode(TCCState *S, 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 *S, int token)489static void asm_block_data_transfer_opcode(TCCState *s1, 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(S, &ops[0]);495 parse_operand(s1, &ops[0]);
496 if (S->tccpp_tok == '!') {496 if (tok == '!') {
497 op0_exclam = 1;497 op0_exclam = 1;
498 next(S); // skip '!'498 next(); // skip '!'
499 }499 }
500 if (S->tccpp_tok == ',') {500 if (tok == ',') {
501 next(S); // skip comma501 next(); // skip comma
502 parse_operand(S, &ops[1]);502 parse_operand(s1, &ops[1]);
503 ++nb_ops;503 ++nb_ops;
504 }504 }
505 if (nb_ops < 1) {505 if (nb_ops < 1) {
506 expect(S, "at least one operand");506 expect("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(S, "(last operand) register list");509 expect("(last operand) register list");
510 return;510 return;
511 }511 }
512 512
@@ -522,9 +522,9 @@ static void asm_block_data_transfer_opcode(TCCState *S, 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(S, "exactly one operand");525 expect("exactly one operand");
526 else526 else
527 asm_emit_opcode(S, token, (0x92d << 16) | ops[0].regset); // TODO: base register ?527 asm_emit_opcode(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 *S, 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(S, "exactly one operand");535 expect("exactly one operand");
536 else536 else
537 asm_emit_opcode(S, token, (0x8bd << 16) | ops[0].regset); // TODO: base register ?537 asm_emit_opcode(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 *S, int token) · 33 unmodified lines
574 opcode = 0x99 << 20;574 opcode = 0x99 << 20;
575 break;575 break;
576 default:576 default:
577 tcc_error(S, "internal error: This place should not be reached (fallback in asm_block_data_transfer_opcode)");577 tcc_error("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(S, "exactly two operands");583 expect("exactly two operands");
584 else if (ops[0].type != OP_REG32)584 else if (ops[0].type != OP_REG32)
585 expect(S, "(first operand) register");585 expect("(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(S, token, opcode | ENCODE_RN(ops[0].reg) | ops[1].regset);589 asm_emit_opcode(token, opcode | ENCODE_RN(ops[0].reg) | ops[1].regset);
590 }590 }
591 break;591 break;
592 default:592 default:
593 expect(S, "block data transfer instruction");593 expect("block data transfer instruction");
594 }594 }
595}595}
596 596
@@ -600,17 +600,17 @@ static void asm_block_data_transfer_opcode(TCCState *S, 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* S, int* nb_shift, Operand* shift)603static uint32_t asm_parse_optional_shift(TCCState* s1, 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 (S->tccpp_tok) {607 switch (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 (S->tccpp_tok) {613 switch (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* S, int* nb_shift, Operand* sh · 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(S);629 next();
630 parse_operand(S, shift);630 parse_operand(s1, 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(S);634 next();
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(TCCState *S, Operand* shift)641static uint32_t asm_encode_shift(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(S, "r15 cannot be used as a shift count");648 tcc_error("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(TCCState *S, 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(S, "shift count out of range");659 tcc_error("shift count out of range");
660 break;660 break;
661 default:661 default:
662 tcc_error(S, "unknown shift amount");662 tcc_error("unknown shift amount");
663 }663 }
664 return operands;664 return operands;
665}665}
666 666
667static void asm_data_processing_opcode(TCCState *S, int token)667static void asm_data_processing_opcode(TCCState *s1, 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 *S, 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 (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)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)
681 break;681 break;
682 parse_operand(S, &ops[nb_ops]);682 parse_operand(s1, &ops[nb_ops]);
683 ++nb_ops;683 ++nb_ops;
684 if (S->tccpp_tok != ',')684 if (tok != ',')
685 break;685 break;
686 next(S); // skip ','686 next(); // skip ','
687 }687 }
688 if (S->tccpp_tok == ',')688 if (tok == ',')
689 next(S);689 next();
690 operands |= asm_parse_optional_shift(S, &nb_shift, &shift);690 operands |= asm_parse_optional_shift(s1, &nb_shift, &shift);
691 if (nb_ops < 2)691 if (nb_ops < 2)
692 expect(S, "at least two operands");692 expect("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, "'%s' cannot be used with three operands", get_tok_str(S, token, NULL));699 tcc_error("'%s' cannot be used with three operands", get_tok_str(token, NULL));
700 return;700 return;
701 }701 }
702 }702 }
703 if (nb_ops != 3) {703 if (nb_ops != 3) {
704 expect(S, "two or three operands");704 expect("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 *S, 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(S, "Using the 'pc' register in data processing instructions that have a register-controlled shift is not implemented by ARM");713 tcc_error("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 *S, 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(S, "(destination operand) register");729 expect("(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(S, "(first source operand) register");735 expect("(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 *S, 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(S, "cannot use '%s' with a negative immediate value", get_tok_str(S, token, NULL));812 tcc_error("cannot use '%s' with a negative immediate value", get_tok_str(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 *S, 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(S, "immediate value 0x%X cannot be encoded into ARM immediate", (unsigned) immediate_value);822 tcc_error("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(S, "(second source operand) register or immediate value");829 expect("(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(S, "immediate rotation not implemented");834 tcc_error("immediate rotation not implemented");
835 else835 else
836 operands |= asm_encode_shift(S, &shift);836 operands |= asm_encode_shift(&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(S, token, opcode | operands);841 asm_emit_opcode(token, opcode | operands);
842 }842 }
843}843}
844 844
845static void asm_shift_opcode(TCCState *S, int token)845static void asm_shift_opcode(TCCState *s1, 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 *S, 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(S, &ops[nb_ops]);854 parse_operand(s1, &ops[nb_ops]);
855 if (S->tccpp_tok != ',') {855 if (tok != ',') {
856 ++nb_ops;856 ++nb_ops;
857 break;857 break;
858 }858 }
859 next(S); // skip ','859 next(); // skip ','
860 }860 }
861 if (nb_ops < 2) {861 if (nb_ops < 2) {
862 expect(S, "at least two operands");862 expect("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(S, "(destination operand) register");867 expect("(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 *S, 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(S, token, opcode | operands);881 asm_emit_opcode(token, opcode | operands);
882 } else882 } else
883 tcc_error(S, "(first source operand) register");883 tcc_error("(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 *S, int token) · 2 unmodified lines
889 }889 }
890 }890 }
891 if (nb_ops != 3) {891 if (nb_ops != 3) {
892 expect(S, "two or three operands");892 expect("two or three operands");
893 return;893 return;
894 }894 }
895 895
@@ -909,7 +909,7 @@ static void asm_shift_opcode(TCCState *S, 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(S, "Using an immediate value as the source operand is not possible with '%s' instruction on ARM", get_tok_str(S, token, NULL));912 tcc_error("Using an immediate value as the source operand is not possible with '%s' instruction on ARM", get_tok_str(token, NULL));
913 return;913 return;
914 }914 }
915 915
@@ -917,13 +917,13 @@ static void asm_shift_opcode(TCCState *S, 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(S, "Using the 'pc' register in data processing instructions that have a register-controlled shift is not implemented by ARM");920 tcc_error("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(S, &ops[2]);922 operands |= asm_encode_shift(&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(S, &ops[2]);926 operands |= asm_encode_shift(&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 *S, 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(S, "shift instruction");950 expect("shift instruction");
951 return;951 return;
952 }952 }
953 asm_emit_opcode(S, token, opcode | operands);953 asm_emit_opcode(token, opcode | operands);
954}954}
955 955
956static void asm_multiplication_opcode(TCCState *S, int token)956static void asm_multiplication_opcode(TCCState *s1, 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(S, &ops[nb_ops]);963 parse_operand(s1, &ops[nb_ops]);
964 if (S->tccpp_tok != ',') {964 if (tok != ',') {
965 ++nb_ops;965 ++nb_ops;
966 break;966 break;
967 }967 }
968 next(S); // skip ','968 next(); // skip ','
969 }969 }
970 if (nb_ops < 2)970 if (nb_ops < 2)
971 expect(S, "at least two operands");971 expect("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 *S, 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(S, "at least three operands");979 expect("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 *S, 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(S, "(destination operand) register");995 expect("(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(S, "(first source operand) register");999 expect("(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(S, "(second source operand) register");1003 expect("(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(S, "(third source operand) register");1008 expect("(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 *S, 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(S, "three operands");1017 expect("three operands");
1018 else {1018 else {
1019 asm_emit_opcode(S, token, opcode);1019 asm_emit_opcode(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 *S, 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(S, "four operands");1027 expect("four operands");
1028 else {1028 else {
1029 opcode |= 1 << 21; // Accumulate1029 opcode |= 1 << 21; // Accumulate
1030 asm_emit_opcode(S, token, opcode);1030 asm_emit_opcode(token, opcode);
1031 }1031 }
1032 break;1032 break;
1033 default:1033 default:
1034 expect(S, "known multiplication instruction");1034 expect("known multiplication instruction");
1035 }1035 }
1036}1036}
1037 1037
1038static void asm_long_multiplication_opcode(TCCState *S, int token)1038static void asm_long_multiplication_opcode(TCCState *s1, 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(S, &ops[nb_ops]);1045 parse_operand(s1, &ops[nb_ops]);
1046 if (S->tccpp_tok != ',') {1046 if (tok != ',') {
1047 ++nb_ops;1047 ++nb_ops;
1048 break;1048 break;
1049 }1049 }
1050 next(S); // skip ','1050 next(); // skip ','
1051 }1051 }
1052 if (nb_ops != 4) {1052 if (nb_ops != 4) {
1053 expect(S, "four operands");1053 expect("four operands");
1054 return;1054 return;
1055 }1055 }
1056 1056
@@ -1064,19 +1064,19 @@ static void asm_long_multiplication_opcode(TCCState *S, 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(S, "(destination lo accumulator) register");1067 expect("(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(S, "(destination hi accumulator) register");1071 expect("(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(S, "(first source operand) register");1075 expect("(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(S, "(second source operand) register");1079 expect("(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 *S, 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(S, token, opcode);1087 asm_emit_opcode(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(S, token, opcode);1093 asm_emit_opcode(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 *S, 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(S, token, opcode);1101 asm_emit_opcode(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(S, token, opcode);1108 asm_emit_opcode(token, opcode);
1109 break;1109 break;
1110 default:1110 default:
1111 expect(S, "known long multiplication instruction");1111 expect("known long multiplication instruction");
1112 }1112 }
1113}1113}
1114 1114
1115static void asm_single_data_transfer_opcode(TCCState *S, int token)1115static void asm_single_data_transfer_opcode(TCCState *s1, 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 *S, 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(S, &ops[0]);1129 parse_operand(s1, &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(S, "(destination operand) register");1133 expect("(destination operand) register");
1134 return;1134 return;
1135 }1135 }
1136 if (S->tccpp_tok != ',')1136 if (tok != ',')
1137 expect(S, "at least two arguments");1137 expect("at least two arguments");
1138 else1138 else
1139 next(S); // skip ','1139 next(); // 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(S, &strex_operand);1144 parse_operand(s1, &strex_operand);
1145 if (strex_operand.type != OP_REG32) {1145 if (strex_operand.type != OP_REG32) {
1146 expect(S, "register");1146 expect("register");
1147 return;1147 return;
1148 }1148 }
1149 if (S->tccpp_tok != ',')1149 if (tok != ',')
1150 expect(S, "at least three arguments");1150 expect("at least three arguments");
1151 else1151 else
1152 next(S); // skip ','1152 next(); // skip ','
1153 break;1153 break;
1154 }1154 }
1155 1155
1156 if (S->tccpp_tok != '[')1156 if (tok != '[')
1157 expect(S, "'['");1157 expect("'['");
1158 else1158 else
1159 next(S); // skip '['1159 next(); // skip '['
1160 1160
1161 parse_operand(S, &ops[1]);1161 parse_operand(s1, &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(S, "(first source operand) register");1165 expect("(first source operand) register");
1166 return;1166 return;
1167 }1167 }
1168 if (S->tccpp_tok == ']') {1168 if (tok == ']') {
1169 next(S);1169 next();
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 (S->tccpp_tok == ',') {1173 if (tok == ',') {
1174 next(S); // skip ','1174 next(); // skip ','
1175 if (S->tccpp_tok == '-') {1175 if (tok == '-') {
1176 op2_minus = 1;1176 op2_minus = 1;
1177 next(S);1177 next();
1178 }1178 }
1179 parse_operand(S, &ops[2]);1179 parse_operand(s1, &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(S, "Using 'pc' for register offset in '%s' is not implemented by ARM", get_tok_str(S, token, NULL));1182 tcc_error("Using 'pc' for register offset in '%s' is not implemented by ARM", get_tok_str(token, NULL));
1183 return;1183 return;
1184 }1184 }
1185 if (S->tccpp_tok == ',') {1185 if (tok == ',') {
1186 next(S);1186 next();
1187 opcode |= asm_parse_optional_shift(S, &nb_shift, &shift);1187 opcode |= asm_parse_optional_shift(s1, &nb_shift, &shift);
1188 if (opcode == 0)1188 if (opcode == 0)
1189 expect(S, "shift directive, or no comma");1189 expect("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 *S, 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 (S->tccpp_tok != ']')1199 if (tok != ']')
1200 expect(S, "']'");1200 expect("']'");
1201 else1201 else
1202 next(S); // skip ']'1202 next(); // skip ']'
1203 opcode |= 1 << 24; // add offset before transfer1203 opcode |= 1 << 24; // add offset before transfer
1204 if (S->tccpp_tok == '!') {1204 if (tok == '!') {
1205 exclam = 1;1205 exclam = 1;
1206 next(S); // skip '!'1206 next(); // skip '!'
1207 }1207 }
1208 }1208 }
1209 1209
@@ -1224,16 +1224,16 @@ static void asm_single_data_transfer_opcode(TCCState *S, 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(S, "minus before '#' not supported for immediate values");1227 tcc_error("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(S, "offset out of range for '%s'", get_tok_str(S, token, NULL));1231 tcc_error("offset out of range for '%s'", get_tok_str(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(S, "offset out of range for '%s'", get_tok_str(S, token, NULL));1236 tcc_error("offset out of range for '%s'", get_tok_str(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 *S, 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(S, "register");1246 expect("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 *S, 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(S, &shift);1255 opcode |= asm_encode_shift(&shift);
1256 asm_emit_opcode(S, token, opcode);1256 asm_emit_opcode(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 *S, 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(S, &shift);1265 opcode |= asm_encode_shift(&shift);
1266 asm_emit_opcode(S, token, opcode);1266 asm_emit_opcode(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(S, "neither offset nor shift allowed with 'strex'");1273 tcc_error("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(S, "offset not allowed with 'strex'");1276 tcc_error("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(S, "adding offset after transfer not allowed with 'strex'");1280 tcc_error("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(S, token, opcode);1286 asm_emit_opcode(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(S, "neither offset nor shift allowed with 'ldrex'");1293 tcc_error("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(S, "offset not allowed with 'ldrex'");1296 tcc_error("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(S, "adding offset after transfer not allowed with 'ldrex'");1300 tcc_error("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(S, token, opcode);1306 asm_emit_opcode(token, opcode);
1307 break;1307 break;
1308 default:1308 default:
1309 expect(S, "data transfer instruction");1309 expect("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(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) {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) {
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(TCCState *S, uint32_t high_nibble · 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(S, "register");1331 expect("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(TCCState *S, uint32_t high_nibble · 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(S, "minus before '#' not supported for immediate values");1345 tcc_error("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(S, "immediate offset must be a multiple of 4");1351 tcc_error("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(S, "immediate offset must be between -1020 and 1020");1356 tcc_error("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(TCCState *S, uint32_t high_nibble · 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(S, "Using register offset to register address is not possible here");1365 tcc_error("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(S, "immediate or register");1371 expect("immediate or register");
1372 1372
1373 asm_emit_unconditional_opcode(S, (high_nibble << 28) | opcode);1373 asm_emit_unconditional_opcode((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 *S, int token)1378static void asm_coprocessor_data_transfer_opcode(TCCState *s1, 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 *S, 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 (S->tccpp_tok >= TOK_ASM_p0 && S->tccpp_tok <= TOK_ASM_p15) {1392 if (tok >= TOK_ASM_p0 && tok <= TOK_ASM_p15) {
1393 coprocessor = S->tccpp_tok - TOK_ASM_p0;1393 coprocessor = tok - TOK_ASM_p0;
1394 next(S);1394 next();
1395 } else {1395 } else {
1396 expect(S, "'c<number>'");1396 expect("'c<number>'");
1397 return;1397 return;
1398 }1398 }
1399 1399
1400 if (S->tccpp_tok == ',')1400 if (tok == ',')
1401 next(S);1401 next();
1402 else1402 else
1403 expect(S, "','");1403 expect("','");
1404 1404
1405 if (S->tccpp_tok >= TOK_ASM_c0 && S->tccpp_tok <= TOK_ASM_c15) {1405 if (tok >= TOK_ASM_c0 && tok <= TOK_ASM_c15) {
1406 coprocessor_destination_register = S->tccpp_tok - TOK_ASM_c0;1406 coprocessor_destination_register = tok - TOK_ASM_c0;
1407 next(S);1407 next();
1408 } else {1408 } else {
1409 expect(S, "'c<number>'");1409 expect("'c<number>'");
1410 return;1410 return;
1411 }1411 }
1412 1412
1413 if (S->tccpp_tok == ',')1413 if (tok == ',')
1414 next(S);1414 next();
1415 else1415 else
1416 expect(S, "','");1416 expect("','");
1417 1417
1418 if (S->tccpp_tok != '[')1418 if (tok != '[')
1419 expect(S, "'['");1419 expect("'['");
1420 else1420 else
1421 next(S); // skip '['1421 next(); // skip '['
1422 1422
1423 parse_operand(S, &ops[1]);1423 parse_operand(s1, &ops[1]);
1424 if (ops[1].type != OP_REG32) {1424 if (ops[1].type != OP_REG32) {
1425 expect(S, "(first source operand) register");1425 expect("(first source operand) register");
1426 return;1426 return;
1427 }1427 }
1428 if (S->tccpp_tok == ']') {1428 if (tok == ']') {
1429 next(S);1429 next();
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 (S->tccpp_tok == ',') {1433 if (tok == ',') {
1434 next(S); // skip ','1434 next(); // skip ','
1435 if (S->tccpp_tok == '-') {1435 if (tok == '-') {
1436 op2_minus = 1;1436 op2_minus = 1;
1437 next(S);1437 next();
1438 }1438 }
1439 parse_operand(S, &ops[2]);1439 parse_operand(s1, &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(S, "Using 'pc' for register offset in '%s' is not implemented by ARM", get_tok_str(S, token, NULL));1442 tcc_error("Using 'pc' for register offset in '%s' is not implemented by ARM", get_tok_str(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, "'%s' does not support VFP register operand", get_tok_str(S, token, NULL));1446 tcc_error("'%s' does not support VFP register operand", get_tok_str(token, NULL));
1447 return;1447 return;
1448 }1448 }
1449 } else {1449 } else {
@@ -1453,14 +1453,14 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *S, 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 (S->tccpp_tok != ']')1456 if (tok != ']')
1457 expect(S, "']'");1457 expect("']'");
1458 else1458 else
1459 next(S); // skip ']'1459 next(); // skip ']'
1460 preincrement = 1; // add offset before transfer1460 preincrement = 1; // add offset before transfer
1461 if (S->tccpp_tok == '!') {1461 if (tok == '!') {
1462 exclam = 1;1462 exclam = 1;
1463 next(S); // skip '!'1463 next(); // skip '!'
1464 }1464 }
1465 }1465 }
1466 1466
@@ -1472,13 +1472,13 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *S, 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(S, 0xF, coprocessor, coprocessor_destination_register, &ops[1], &ops[2], op2_minus, preincrement, exclam, long_transfer, 1);1475 asm_emit_coprocessor_data_transfer(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(S, 0xF, coprocessor, coprocessor_destination_register, &ops[1], &ops[2], op2_minus, preincrement, exclam, long_transfer, 0);1481 asm_emit_coprocessor_data_transfer(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 *S, 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(S, condition_code_of_token(S, token), coprocessor, coprocessor_destination_register, &ops[1], &ops[2], op2_minus, preincrement, exclam, long_transfer, 0);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);
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(S, condition_code_of_token(S, token), coprocessor, coprocessor_destination_register, &ops[1], &ops[2], op2_minus, preincrement, exclam, long_transfer, 1);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);
1496 break;1496 break;
1497 default:1497 default:
1498 expect(S, "coprocessor data transfer instruction");1498 expect("coprocessor data transfer instruction");
1499 }1499 }
1500}1500}
1501 1501
@@ -1503,7 +1503,7 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *S, 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 *S, int token)1506static void asm_floating_point_single_data_transfer_opcode(TCCState *s1, 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 *S, int toke · 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(S, &ops[0]);1516 parse_operand(s1, &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 *S, int toke · 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(S);1525 next();
1526 } else {1526 } else {
1527 expect(S, "floating point register");1527 expect("floating point register");
1528 return;1528 return;
1529 }1529 }
1530 1530
1531 if (S->tccpp_tok == ',')1531 if (tok == ',')
1532 next(S);1532 next();
1533 else1533 else
1534 expect(S, "','");1534 expect("','");
1535 1535
1536 if (S->tccpp_tok != '[')1536 if (tok != '[')
1537 expect(S, "'['");1537 expect("'['");
1538 else1538 else
1539 next(S); // skip '['1539 next(); // skip '['
1540 1540
1541 parse_operand(S, &ops[1]);1541 parse_operand(s1, &ops[1]);
1542 if (ops[1].type != OP_REG32) {1542 if (ops[1].type != OP_REG32) {
1543 expect(S, "(first source operand) register");1543 expect("(first source operand) register");
1544 return;1544 return;
1545 }1545 }
1546 if (S->tccpp_tok == ',') {1546 if (tok == ',') {
1547 next(S); // skip ','1547 next(); // skip ','
1548 parse_operand(S, &ops[2]);1548 parse_operand(s1, &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(S, "immediate offset");1550 expect("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 *S, int toke · 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 (S->tccpp_tok != ']')1558 if (tok != ']')
1559 expect(S, "']'");1559 expect("']'");
1560 else1560 else
1561 next(S); // skip ']'1561 next(); // 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(S, condition_code_of_token(S, token), coprocessor, coprocessor_destination_register, &ops[1], &ops[2], 0, 1, 0, long_transfer, 1);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);
1566 break;1566 break;
1567 case TOK_ASM_vstreq:1567 case TOK_ASM_vstreq:
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);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);
1569 break;1569 break;
1570 default:1570 default:
1571 expect(S, "floating point data transfer instruction");1571 expect("floating point data transfer instruction");
1572 }1572 }
1573}1573}
1574 1574
1575static void asm_floating_point_block_data_transfer_opcode(TCCState *S, int token)1575static void asm_floating_point_block_data_transfer_opcode(TCCState *s1, 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 *S, int token · 13 unmodified lines
1592 op0_exclam = 1;1592 op0_exclam = 1;
1593 break;1593 break;
1594 default:1594 default:
1595 parse_operand(S, &ops[0]);1595 parse_operand(s1, &ops[0]);
1596 if (S->tccpp_tok == '!') {1596 if (tok == '!') {
1597 op0_exclam = 1;1597 op0_exclam = 1;
1598 next(S); // skip '!'1598 next(); // skip '!'
1599 }1599 }
1600 if (S->tccpp_tok == ',')1600 if (tok == ',')
1601 next(S); // skip comma1601 next(); // skip comma
1602 else {1602 else {
1603 expect(S, "','");1603 expect("','");
1604 return;1604 return;
1605 }1605 }
1606 }1606 }
1607 1607
1608 if (S->tccpp_tok != '{') {1608 if (tok != '{') {
1609 expect(S, "'{'");1609 expect("'{'");
1610 return;1610 return;
1611 }1611 }
1612 next(S); // skip '{'1612 next(); // skip '{'
1613 first_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, 1);1613 first_regset_register = asm_parse_vfp_regvar(tok, 1);
1614 if ((first_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, 1)) != -1) {1614 if ((first_regset_register = asm_parse_vfp_regvar(tok, 1)) != -1) {
1615 coprocessor = CP_DOUBLE_PRECISION_FLOAT;1615 coprocessor = CP_DOUBLE_PRECISION_FLOAT;
1616 next(S);1616 next();
1617 } else if ((first_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, 0)) != -1) {1617 } else if ((first_regset_register = asm_parse_vfp_regvar(tok, 0)) != -1) {
1618 coprocessor = CP_SINGLE_PRECISION_FLOAT;1618 coprocessor = CP_SINGLE_PRECISION_FLOAT;
1619 next(S);1619 next();
1620 } else {1620 } else {
1621 expect(S, "floating-point register");1621 expect("floating-point register");
1622 return;1622 return;
1623 }1623 }
1624 1624
1625 if (S->tccpp_tok == '-') {1625 if (tok == '-') {
1626 next(S);1626 next();
1627 if ((last_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, coprocessor == CP_DOUBLE_PRECISION_FLOAT)) != -1)1627 if ((last_regset_register = asm_parse_vfp_regvar(tok, coprocessor == CP_DOUBLE_PRECISION_FLOAT)) != -1)
1628 next(S);1628 next();
1629 else {1629 else {
1630 expect(S, "floating-point register");1630 expect("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(S, "registers will be processed in ascending order by hardware--but are not specified in ascending order here");1637 tcc_error("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 (S->tccpp_tok != '}') {1640 if (tok != '}') {
1641 expect(S, "'}'");1641 expect("'}'");
1642 return;1642 return;
1643 }1643 }
1644 next(S); // skip '}'1644 next(); // 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 *S, int token · 24 unmodified lines
1672 preincrement = 1;1672 preincrement = 1;
1673 break;1673 break;
1674 default:1674 default:
1675 expect(S, "floating point block data transfer instruction");1675 expect("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(S, "(first operand) register");1679 expect("(first operand) register");
1680 else if (ops[0].reg == 15)1680 else if (ops[0].reg == 15)
1681 tcc_error(S, "'%s' does not support 'pc' as operand", get_tok_str(S, token, NULL));1681 tcc_error("'%s' does not support 'pc' as operand", get_tok_str(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(S, "first operand of '%s' should have an exclamation mark", get_tok_str(S, token, NULL));1683 tcc_error("first operand of '%s' should have an exclamation mark", get_tok_str(token, NULL));
1684 else1684 else
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);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);
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(TCCState* S, const char* s)1691static uint32_t vmov_parse_fractional_part(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(TCCState* S, const char* s) · 6 unmodified lines
1701 }1701 }
1702 }1702 }
1703 if (*s)1703 if (*s)
1704 expect(S, "decimal numeral");1704 expect("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(TCCState* S) {1723static uint32_t vmov_parse_immediate_value() {
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 (S->tccpp_tok != TOK_PPNUM) {1728 if (tok != TOK_PPNUM) {
1729 expect(S, "immediate value");1729 expect("immediate value");
1730 return 0;1730 return 0;
1731 }1731 }
1732 p = S->tccpp_tokc.str.data;1732 p = 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(S, "invalid floating-point immediate value");1737 tcc_error("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(S, p);1744 value += vmov_parse_fractional_part(p);
1745 }1745 }
1746 next(S);1746 next();
1747 return value;1747 return value;
1748}1748}
1749 1749
1750static uint8_t vmov_encode_immediate_value(TCCState* S, uint32_t value)1750static uint8_t vmov_encode_immediate_value(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(TCCState* S, 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(S, "invalid decimal number for vmov: %d", value);1770 tcc_error("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(TCCState* S, 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 *S, int token, uint8_t coprocessor, uint8_t CRd) {1778static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *s1, 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 (S->tccpp_tok == '#' || S->tccpp_tok == '$') {1788 if (tok == '#' || tok == '$') {
1789 next(S);1789 next();
1790 }1790 }
1791 if (S->tccpp_tok == '-') {1791 if (tok == '-') {
1792 op_minus = 1;1792 op_minus = 1;
1793 next(S);1793 next();
1794 }1794 }
1795 immediate_value = vmov_parse_immediate_value(S);1795 immediate_value = vmov_parse_immediate_value();
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(S, "Immediate value 0");1804 expect("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(S, "Immediate value 0");1813 expect("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(S, immediate_value);1824 code = vmov_encode_immediate_value(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(S, "known floating point with immediate instruction");1829 expect("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(S, condition_code_of_token(S, token), coprocessor, opcode1, operands[0], operands[1], operands[2], opcode2, 0);1839 asm_emit_coprocessor_opcode(condition_code_of_token(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 *S, 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 *s1, 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(S, "vmov.f32 only implemented for one VFP register operand and one ARM register operands");1849 tcc_error("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 *S, int · 16 unmodified lines
1869 ops[0].reg >>= 1;1869 ops[0].reg >>= 1;
1870 }1870 }
1871 1871
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);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);
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(S, "vmov.f32 only implemented for one VFP register operand and two ARM register operands");1876 tcc_error("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 *S, int · 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(S, "vmov.f64 only implemented for one VFP register operand and two ARM register operands");1889 tcc_error("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(S, "vmov.f64 only implemented for one VFP register operand and two ARM register operands");1893 tcc_error("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(S, condition_code_of_token(S, token), coprocessor, ops[0].reg, &ops[1], &ops[2], 0, 0, 0, 1, opcode1);1898 asm_emit_coprocessor_data_transfer(condition_code_of_token(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(S, "unknown coprocessor");1901 tcc_internal_error("unknown coprocessor");
1902 }1902 }
1903}1903}
1904 1904
1905static void asm_floating_point_vcvt_data_processing_opcode(TCCState *S, int token) {1905static void asm_floating_point_vcvt_data_processing_opcode(TCCState *s1, 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 *S, int toke · 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(S, "Unknown coprocessor for instruction '%s'", get_tok_str(S, token, NULL));1931 tcc_error("Unknown coprocessor for instruction '%s'", get_tok_str(token, NULL));
1932 return;1932 return;
1933 }1933 }
1934 1934
1935 parse_operand(S, &ops[0]);1935 parse_operand(s1, &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 *S, int toke · 17 unmodified lines
1956 break;1956 break;
1957 }1957 }
1958 1958
1959 if (S->tccpp_tok == ',')1959 if (tok == ',')
1960 next(S);1960 next();
1961 else1961 else
1962 expect(S, "','");1962 expect("','");
1963 parse_operand(S, &ops[2]);1963 parse_operand(s1, &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 *S, int toke · 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(S, "d<number>, s<number>");1993 expect("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 *S, int toke · 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, "s<number>, s<number>");2001 expect("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, "s<number>, d<number>");2007 expect("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 *S, int toke · 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(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);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);
2024}2024}
2025 2025
2026static void asm_floating_point_data_processing_opcode(TCCState *S, int token) {2026static void asm_floating_point_data_processing_opcode(TCCState *s1, 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 *S, 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 && (S->tccpp_tok == '#' || S->tccpp_tok == '$' || S->tccpp_tok == TOK_PPNUM || S->tccpp_tok == '-')) {2081 if (nb_ops == 1 && (tok == '#' || tok == '$' || tok == TOK_PPNUM || tok == '-')) {
2082 asm_floating_point_immediate_data_processing_opcode_tail(S, token, coprocessor, ops[0].reg);2082 asm_floating_point_immediate_data_processing_opcode_tail(s1, token, coprocessor, ops[0].reg);
2083 return;2083 return;
2084 }2084 }
2085 parse_operand(S, &ops[nb_ops]);2085 parse_operand(s1, &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, "'s<number>'");2090 expect("'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(S, "'d<number>'");2095 expect("'d<number>'");
2096 return;2096 return;
2097 }2097 }
2098 } else {2098 } else {
2099 expect(S, "floating point register");2099 expect("floating point register");
2100 return;2100 return;
2101 }2101 }
2102 ++nb_ops;2102 ++nb_ops;
2103 if (S->tccpp_tok == ',')2103 if (tok == ',')
2104 next(S);2104 next();
2105 else2105 else
2106 break;2106 break;
2107 }2107 }
@@ -2113,7 +2113,7 @@ static void asm_floating_point_data_processing_opcode(TCCState *S, 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(S, "Not enough operands for '%s' (%u)", get_tok_str(S, token, NULL), nb_ops);2116 tcc_error("Not enough operands for '%s' (%u)", get_tok_str(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 *S, 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(S, token, coprocessor, nb_arm_regs, nb_ops, ops);2205 asm_floating_point_reg_arm_reg_transfer_opcode_tail(s1, 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 *S, int token) { · 3 unmodified lines
2212 }2212 }
2213 break;2213 break;
2214 default:2214 default:
2215 expect(S, "known floating point instruction");2215 expect("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 *S, int token) { · 17 unmodified lines
2236 }2236 }
2237 }2237 }
2238 2238
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);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);
2240}2240}
2241 2241
2242static void asm_floating_point_status_register_opcode(TCCState* S, int token)2242static void asm_floating_point_status_register_opcode(TCCState* s1, 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* S, 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 (S->tccpp_tok == TOK_ASM_apsr_nzcv) {2251 if (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(S); // skip apsr_nzcv2254 next(); // skip apsr_nzcv
2255 } else {2255 } else {
2256 parse_operand(S, &arm_operand);2256 parse_operand(s1, &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, "'%s' does not support 'pc' as operand", get_tok_str(S, token, NULL));2258 tcc_error("'%s' does not support 'pc' as operand", get_tok_str(token, NULL));
2259 return;2259 return;
2260 }2260 }
2261 }2261 }
2262 2262
2263 if (S->tccpp_tok != ',')2263 if (tok != ',')
2264 expect(S, "','");2264 expect("','");
2265 else2265 else
2266 next(S); // skip ','2266 next(); // skip ','
2267 vfp_sys_reg = asm_parse_vfp_status_regvar(S->tccpp_tok);2267 vfp_sys_reg = asm_parse_vfp_status_regvar(tok);
2268 next(S); // skip vfp sys reg2268 next(); // 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, "'%s' only supports the variant 'vmrs apsr_nzcv, fpscr' here", get_tok_str(S, token, NULL));2270 tcc_error("'%s' only supports the variant 'vmrs apsr_nzcv, fpscr' here", get_tok_str(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(S->tccpp_tok);2276 vfp_sys_reg = asm_parse_vfp_status_regvar(tok);
2277 next(S); // skip vfp sys reg2277 next(); // skip vfp sys reg
2278 if (S->tccpp_tok != ',')2278 if (tok != ',')
2279 expect(S, "','");2279 expect("','");
2280 else2280 else
2281 next(S); // skip ','2281 next(); // skip ','
2282 parse_operand(S, &arm_operand);2282 parse_operand(s1, &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, "'%s' does not support 'pc' as operand", get_tok_str(S, token, NULL));2284 tcc_error("'%s' does not support 'pc' as operand", get_tok_str(token, NULL));
2285 return;2285 return;
2286 }2286 }
2287 break;2287 break;
2288 default:2288 default:
2289 expect(S, "floating point status register instruction");2289 expect("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(S, "VFP system register");2293 expect("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(S, "ARM register");2297 expect("ARM register");
2298 return;2298 return;
2299 }2299 }
2300 asm_emit_coprocessor_opcode(S, condition_code_of_token(S, token), coprocessor, opcode, arm_operand.reg, vfp_sys_reg, 0x10, 0, 0);2300 asm_emit_coprocessor_opcode(condition_code_of_token(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 *S, int token)2305static void asm_misc_single_data_transfer_opcode(TCCState *s1, 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 *S, 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(S, &ops[0]);2325 parse_operand(s1, &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(S, "(destination operand) register");2329 expect("(destination operand) register");
2330 return;2330 return;
2331 }2331 }
2332 if (S->tccpp_tok != ',')2332 if (tok != ',')
2333 expect(S, "at least two arguments");2333 expect("at least two arguments");
2334 else2334 else
2335 next(S); // skip ','2335 next(); // skip ','
2336 2336
2337 if (S->tccpp_tok != '[')2337 if (tok != '[')
2338 expect(S, "'['");2338 expect("'['");
2339 else2339 else
2340 next(S); // skip '['2340 next(); // skip '['
2341 2341
2342 parse_operand(S, &ops[1]);2342 parse_operand(s1, &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(S, "(first source operand) register");2346 expect("(first source operand) register");
2347 return;2347 return;
2348 }2348 }
2349 if (S->tccpp_tok == ']') {2349 if (tok == ']') {
2350 next(S);2350 next();
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 (S->tccpp_tok == ',') {2354 if (tok == ',') {
2355 next(S); // skip ','2355 next(); // skip ','
2356 if (S->tccpp_tok == '-') {2356 if (tok == '-') {
2357 op2_minus = 1;2357 op2_minus = 1;
2358 next(S);2358 next();
2359 }2359 }
2360 parse_operand(S, &ops[2]);2360 parse_operand(s1, &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 *S, 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 (S->tccpp_tok != ']')2368 if (tok != ']')
2369 expect(S, "']'");2369 expect("']'");
2370 else2370 else
2371 next(S); // skip ']'2371 next(); // skip ']'
2372 opcode |= 1 << 24; // add offset before transfer2372 opcode |= 1 << 24; // add offset before transfer
2373 if (S->tccpp_tok == '!') {2373 if (tok == '!') {
2374 exclam = 1;2374 exclam = 1;
2375 next(S); // skip '!'2375 next(); // 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(S, "result of '%s' would be unpredictable here", get_tok_str(S, token, NULL));2381 tcc_error("result of '%s' would be unpredictable here", get_tok_str(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 *S, 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(S, "minus before '#' not supported for immediate values");2390 tcc_error("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(S, "offset out of range for '%s'", get_tok_str(S, token, NULL));2394 tcc_error("offset out of range for '%s'", get_tok_str(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 *S, int token) · 2 unmodified lines
2400 }2400 }
2401 } else { // down2401 } else { // down
2402 if (v <= -0x100)2402 if (v <= -0x100)
2403 tcc_error(S, "offset out of range for '%s'", get_tok_str(S, token, NULL));2403 tcc_error("offset out of range for '%s'", get_tok_str(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 *S, 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(S, "register");2418 expect("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 *S, 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(S, token, opcode);2427 asm_emit_opcode(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(S, token, opcode);2432 asm_emit_opcode(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(S, token, opcode);2436 asm_emit_opcode(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(TCCState* S, int pos, int addr, int fail)2442static uint32_t encbranchoffset(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(S, "branch offset is too far");2448 tcc_error("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 *S, int token)2454static void asm_branch_opcode(TCCState *s1, 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 *S, 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(S, &e);2464 asm_expr(s1, &e);
2465 esym = elfsym(S, e.sym);2465 esym = elfsym(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(S, "invalid branch target");2467 tcc_error("invalid branch target");
2468 return;2468 return;
2469 }2469 }
2470 jmp_disp = encbranchoffset(S, S->tccgen_ind, e.v + esym->st_value, 1);2470 jmp_disp = encbranchoffset(ind, e.v + esym->st_value, 1);
2471 break;2471 break;
2472 default:2472 default:
2473 parse_operand(S, &op);2473 parse_operand(s1, &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(S, token, (0xa << 24) | (jmp_disp & 0xffffff));2478 asm_emit_opcode(token, (0xa << 24) | (jmp_disp & 0xffffff));
2479 break;2479 break;
2480 case TOK_ASM_bleq:2480 case TOK_ASM_bleq:
2481 asm_emit_opcode(S, token, (0xb << 24) | (jmp_disp & 0xffffff));2481 asm_emit_opcode(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(S, "register");2485 expect("register");
2486 else2486 else
2487 asm_emit_opcode(S, token, (0x12fff1 << 4) | op.reg);2487 asm_emit_opcode(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(S, "register");2491 expect("register");
2492 else2492 else
2493 asm_emit_opcode(S, token, (0x12fff3 << 4) | op.reg);2493 asm_emit_opcode(token, (0x12fff3 << 4) | op.reg);
2494 break;2494 break;
2495 default:2495 default:
2496 expect(S, "branch instruction");2496 expect("branch instruction");
2497 }2497 }
2498}2498}
2499 2499
2500ST_FUNC void asm_opcode(TCCState *S, int token)2500ST_FUNC void asm_opcode(TCCState *s1, int token)
2501{2501{
2502 while (token == TOK_LINEFEED) {2502 while (token == TOK_LINEFEED) {
2503 next(S);2503 next();
2504 token = S->tccpp_tok;2504 token = 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(S, token);2511 asm_coprocessor_opcode(s1, 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(S, token);2517 asm_coprocessor_data_transfer_opcode(s1, token);
2518 return;2518 return;
2519 default:2519 default:
2520 expect(S, "instruction");2520 expect("instruction");
2521 return;2521 return;
2522 }2522 }
2523 }2523 }
@@ -2535,22 +2535,22 @@ ST_FUNC void asm_opcode(TCCState *S, 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(S, token);2538 asm_block_data_transfer_opcode(s1, 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(S, token);2543 asm_nullary_opcode(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(S, token);2547 asm_unary_opcode(s1, 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(S, token);2553 asm_branch_opcode(s1, 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 *S, 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(S, token);2562 asm_binary_opcode(s1, 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 *S, 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(S, token);2573 asm_single_data_transfer_opcode(s1, 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(S, token);2580 asm_misc_single_data_transfer_opcode(s1, 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 *S, 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(S, token);2615 asm_data_processing_opcode(s1, 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 *S, 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(S, token);2628 asm_shift_opcode(s1, 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(S, token);2635 asm_multiplication_opcode(s1, 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 *S, 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(S, token);2646 asm_long_multiplication_opcode(s1, 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(S, token);2652 asm_coprocessor_opcode(s1, 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(S, token);2659 asm_coprocessor_data_transfer_opcode(s1, 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(S, token);2665 asm_floating_point_single_data_transfer_opcode(s1, 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 *S, 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(S, token);2698 asm_floating_point_data_processing_opcode(s1, 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 *S, 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(S, token);2715 asm_floating_point_vcvt_data_processing_opcode(s1, 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 *S, 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(S, token);2726 asm_floating_point_block_data_transfer_opcode(s1, 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(S, token);2731 asm_floating_point_status_register_opcode(s1, token);
2732 return;2732 return;
2733#endif2733#endif
2734 2734
2735 default:2735 default:
2736 expect(S, "known instruction");2736 expect("known instruction");
2737 }2737 }
2738}2738}
2739 2739
2740ST_FUNC void subst_asm_operand(TCCState* S, CString *add_str, SValue *sv, int modifier)2740ST_FUNC void subst_asm_operand(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(TCCState* S, CString *add_str, SValue *sv, int mo · 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(S, add_str, '#');2749 cstr_ccat(add_str, '#');
2750 if (r & VT_SYM) {2750 if (r & VT_SYM) {
2751 const char *name = get_tok_str(S, sv->sym->v, NULL);2751 const char *name = get_tok_str(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(S, tok_alloc(S, name, strlen(name))->tok, sv->sym);2758 get_asm_sym(tok_alloc(name, strlen(name))->tok, sv->sym);
2759 }2759 }
2760 if (S->leading_underscore)2760 if (tcc_state->leading_underscore)
2761 cstr_ccat(S, add_str, '_');2761 cstr_ccat(add_str, '_');
2762 cstr_cat(S, add_str, name, -1);2762 cstr_cat(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(S, add_str, '+');2765 cstr_ccat(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(S, add_str, buf, -1);2771 cstr_cat(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(S, add_str, buf, -1);2775 cstr_cat(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(S, "");2779 tcc_internal_error("");
2780 snprintf(buf, sizeof(buf), "[%s]",2780 snprintf(buf, sizeof(buf), "[%s]",
2781 get_tok_str(S, TOK_ASM_r0 + reg, NULL));2781 get_tok_str(TOK_ASM_r0 + reg, NULL));
2782 cstr_cat(S, add_str, buf, -1);2782 cstr_cat(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(S, "");2787 tcc_internal_error("");
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(TCCState* S, CString *add_str, SValue *sv, int mo · 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(S, reg, NULL));2811 snprintf(buf, sizeof(buf), "%s", get_tok_str(reg, NULL));
2812 cstr_cat(S, add_str, buf, -1);2812 cstr_cat(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(TCCState* S, ASMOperand *operands, int nb_operands,2817ST_FUNC void asm_gen_code(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(TCCState* S, 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(S, 0xe92d0000 | saved_regset); // push {...}2847 gen_le32(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(TCCState* S, 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(S, op->reg, &sv);2861 load(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(S, op->reg, op->vt);2864 load(op->reg, op->vt);
2865 if (op->is_llong)2865 if (op->is_llong)
2866 tcc_error(S, "long long not implemented");2866 tcc_error("long long not implemented");
2867 }2867 }
2868 }2868 }
2869 }2869 }
@@ -2878,29 +2878,29 @@ ST_FUNC void asm_gen_code(TCCState* S, 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(S, out_reg, &sv);2881 load(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(S, op->reg, &sv);2885 store(op->reg, &sv);
2886 }2886 }
2887 } else {2887 } else {
2888 store(S, op->reg, op->vt);2888 store(op->reg, op->vt);
2889 if (op->is_llong)2889 if (op->is_llong)
2890 tcc_error(S, "long long not implemented");2890 tcc_error("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(S, 0xe8bd0000 | saved_regset); // pop {...}2897 gen_le32(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(TCCState* S, const char *str)2903static inline int constraint_priority(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(TCCState* S, const char *str) · 20 unmodified lines
2927 pr = 4;2927 pr = 4;
2928 break;2928 break;
2929 default:2929 default:
2930 tcc_error(S, "unknown constraint '%c'", c);2930 tcc_error("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(TCCState* S, ASMOperand *operands,2959ST_FUNC void asm_compute_constraints(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(TCCState* S, 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(S, operands, nb_operands, str, NULL);3012 k = find_constraint(operands, nb_operands, str, NULL);
3013 if ((unsigned) k >= i || i < nb_outputs)3013 if ((unsigned) k >= i || i < nb_outputs)
3014 tcc_error(S, "invalid reference in constraint %d ('%s')",3014 tcc_error("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(S, "cannot reference twice the same operand");3018 tcc_error("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(TCCState* S, 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(S, str);3027 op->priority = constraint_priority(str);
3028 }3028 }
3029 }3029 }
3030 3030
@@ -3073,7 +3073,7 @@ ST_FUNC void asm_compute_constraints(TCCState* S, 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 (S, "asm regvar requests register that's taken already");3076 ("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(TCCState* S, 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(S, "'%c' modifier can only be applied to outputs",3090 tcc_error("'%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(TCCState* S, ASMOperand *operands, · 53 unmodified lines
3147 }3147 }
3148 break;3148 break;
3149 default:3149 default:
3150 tcc_error(S, "asm constraint %d ('%s') could not be satisfied",3150 tcc_error("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(TCCState* S, 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(S, "could not find free output register for reloading");3172 tcc_error("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(TCCState* S, 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(S, op->id, NULL) : "",3186 op->id ? get_tok_str(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(TCCState* S, ASMOperand *operands, · 1 unmodified line
3191#endif3191#endif
3192}3192}
3193 3193
3194ST_FUNC void asm_clobber(TCCState* S, uint8_t *clobber_regs, const char *str)3194ST_FUNC void asm_clobber(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(TCCState* S, 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(S, str, strlen(str));3203 ts = tok_alloc(str, strlen(str));
3204 reg = asm_parse_regvar(S, ts->tok);3204 reg = asm_parse_regvar(ts->tok);
3205 if (reg == -1) {3205 if (reg == -1) {
3206 tcc_error(S, "invalid clobber register '%s'", str);3206 tcc_error("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 (TCCState *S, int t)3213ST_FUNC int asm_parse_regvar (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+570−563
@@ -179,17 +179,24 @@ 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
182#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)188#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
183ST_FUNC void arm_init(TCCState *S)189static CType float_type, double_type, func_float_type, func_double_type;
190ST_FUNC void arm_init(struct TCCState *s)
184{191{
185 S->armgen_float_type.t = VT_FLOAT;192 float_type.t = VT_FLOAT;
186 S->armgen_double_type.t = VT_DOUBLE;193 double_type.t = VT_DOUBLE;
187 S->armgen_func_float_type.t = VT_FUNC;194 func_float_type.t = VT_FUNC;
188 S->armgen_func_float_type.ref = sym_push(S, SYM_FIELD, &S->armgen_float_type, FUNC_CDECL, FUNC_OLD);195 func_float_type.ref = sym_push(SYM_FIELD, &float_type, FUNC_CDECL, FUNC_OLD);
189 S->armgen_func_double_type.t = VT_FUNC;196 func_double_type.t = VT_FUNC;
190 S->armgen_func_double_type.ref = sym_push(S, SYM_FIELD, &S->armgen_double_type, FUNC_CDECL, FUNC_OLD);197 func_double_type.ref = sym_push(SYM_FIELD, &double_type, FUNC_CDECL, FUNC_OLD);
191 198
192 float_abi = S->float_abi;199 float_abi = s->float_abi;
193#ifndef TCC_ARM_HARDFLOAT200#ifndef TCC_ARM_HARDFLOAT
194// XXX: Works on OpenBSD201// XXX: Works on OpenBSD
195// # warning "soft float ABI currently not supported: default to softfp"202// # warning "soft float ABI currently not supported: default to softfp"
@@ -216,15 +223,15 @@ ST_FUNC void arm_init(struct TCCState *s) · 20 unmodified lines
216 223
217#define CHECK_R(r) ((r) >= TREG_R0 && (r) <= TREG_LR)224#define CHECK_R(r) ((r) >= TREG_R0 && (r) <= TREG_LR)
218 225
219static int two2mask(TCCState* S, int a,int b) {226static int two2mask(int a,int b) {
220 if (!CHECK_R(a) || !CHECK_R(b))227 if (!CHECK_R(a) || !CHECK_R(b))
221 tcc_error(S, "compiler error! registers %i,%i is not valid",a,b);228 tcc_error("compiler error! registers %i,%i is not valid",a,b);
222 return (reg_classes[a]|reg_classes[b])&~(RC_INT|RC_FLOAT);229 return (reg_classes[a]|reg_classes[b])&~(RC_INT|RC_FLOAT);
223}230}
224 231
225static int regmask(TCCState* S, int r) {232static int regmask(int r) {
226 if (!CHECK_R(r))233 if (!CHECK_R(r))
227 tcc_error(S, "compiler error! register %i is not valid",r);234 tcc_error("compiler error! register %i is not valid",r);
228 return reg_classes[r]&~(RC_INT|RC_FLOAT);235 return reg_classes[r]&~(RC_INT|RC_FLOAT);
229}236}
230 237
@@ -240,25 +247,25 @@ const char *default_elfinterp(struct TCCState *s) · 9 unmodified lines
240}247}
241#endif248#endif
242 249
243void o(TCCState* S, uint32_t i)250void o(uint32_t i)
244{251{
245 /* this is a good place to start adding big-endian support*/252 /* this is a good place to start adding big-endian support*/
246 int ind1;253 int ind1;
247 if (S->tccgen_nocode_wanted)254 if (nocode_wanted)
248 return;255 return;
249 ind1 = S->tccgen_ind + 4;256 ind1 = ind + 4;
250 if (!cur_text_section)257 if (!cur_text_section)
251 tcc_error(S, "compiler error! This happens f.ex. if the compiler\n"258 tcc_error("compiler error! This happens f.ex. if the compiler\n"
252 "can't evaluate constant expressions outside of a function.");259 "can't evaluate constant expressions outside of a function.");
253 if (ind1 > cur_text_section->data_allocated)260 if (ind1 > cur_text_section->data_allocated)
254 section_realloc(S, cur_text_section, ind1);261 section_realloc(cur_text_section, ind1);
255 cur_text_section->data[S->tccgen_ind++] = i&255;262 cur_text_section->data[ind++] = i&255;
256 i>>=8;263 i>>=8;
257 cur_text_section->data[S->tccgen_ind++] = i&255;264 cur_text_section->data[ind++] = i&255;
258 i>>=8;265 i>>=8;
259 cur_text_section->data[S->tccgen_ind++] = i&255;266 cur_text_section->data[ind++] = i&255;
260 i>>=8;267 i>>=8;
261 cur_text_section->data[S->tccgen_ind++] = i;268 cur_text_section->data[ind++] = i;
262}269}
263 270
264static uint32_t stuff_const(uint32_t op, uint32_t c)271static uint32_t stuff_const(uint32_t op, uint32_t c)
@@ -315,11 +322,11 @@ static uint32_t stuff_const(uint32_t op, uint32_t c) · 50 unmodified lines
315 322
316 323
317//only add,sub324//only add,sub
318void stuff_const_harder(TCCState* S, uint32_t op, uint32_t v) {325void stuff_const_harder(uint32_t op, uint32_t v) {
319 uint32_t x;326 uint32_t x;
320 x=stuff_const(op,v);327 x=stuff_const(op,v);
321 if(x)328 if(x)
322 o(S, x);329 o(x);
323 else {330 else {
324 uint32_t a[16], nv, no, o2, n2;331 uint32_t a[16], nv, no, o2, n2;
325 int i,j,k;332 int i,j,k;
@@ -330,8 +337,8 @@ void stuff_const_harder(TCCState* S, uint32_t op, uint32_t v) { · 4 unmodified lines
330 for(i=0;i<12;i++)337 for(i=0;i<12;i++)
331 for(j=i<4?i+12:15;j>=i+4;j--)338 for(j=i<4?i+12:15;j>=i+4;j--)
332 if((v&(a[i]|a[j]))==v) {339 if((v&(a[i]|a[j]))==v) {
333 o(S, stuff_const(op,v&a[i]));340 o(stuff_const(op,v&a[i]));
334 o(S, stuff_const(o2,v&a[j]));341 o(stuff_const(o2,v&a[j]));
335 return;342 return;
336 }343 }
337 no=op^0xC00000;344 no=op^0xC00000;
@@ -340,17 +347,17 @@ void stuff_const_harder(TCCState* S, uint32_t op, uint32_t v) { · 2 unmodified lines
340 for(i=0;i<12;i++)347 for(i=0;i<12;i++)
341 for(j=i<4?i+12:15;j>=i+4;j--)348 for(j=i<4?i+12:15;j>=i+4;j--)
342 if((nv&(a[i]|a[j]))==nv) {349 if((nv&(a[i]|a[j]))==nv) {
343 o(S, stuff_const(no,nv&a[i]));350 o(stuff_const(no,nv&a[i]));
344 o(S, stuff_const(n2,nv&a[j]));351 o(stuff_const(n2,nv&a[j]));
345 return;352 return;
346 }353 }
347 for(i=0;i<8;i++)354 for(i=0;i<8;i++)
348 for(j=i+4;j<12;j++)355 for(j=i+4;j<12;j++)
349 for(k=i<4?i+12:15;k>=j+4;k--)356 for(k=i<4?i+12:15;k>=j+4;k--)
350 if((v&(a[i]|a[j]|a[k]))==v) {357 if((v&(a[i]|a[j]|a[k]))==v) {
351 o(S, stuff_const(op,v&a[i]));358 o(stuff_const(op,v&a[i]));
352 o(S, stuff_const(o2,v&a[j]));359 o(stuff_const(o2,v&a[j]));
353 o(S, stuff_const(o2,v&a[k]));360 o(stuff_const(o2,v&a[k]));
354 return;361 return;
355 }362 }
356 no=op^0xC00000;363 no=op^0xC00000;
@@ -359,31 +366,31 @@ void stuff_const_harder(TCCState* S, uint32_t op, uint32_t v) { · 2 unmodified lines
359 for(j=i+4;j<12;j++)366 for(j=i+4;j<12;j++)
360 for(k=i<4?i+12:15;k>=j+4;k--)367 for(k=i<4?i+12:15;k>=j+4;k--)
361 if((nv&(a[i]|a[j]|a[k]))==nv) {368 if((nv&(a[i]|a[j]|a[k]))==nv) {
362 o(S, stuff_const(no,nv&a[i]));369 o(stuff_const(no,nv&a[i]));
363 o(S, stuff_const(n2,nv&a[j]));370 o(stuff_const(n2,nv&a[j]));
364 o(S, stuff_const(n2,nv&a[k]));371 o(stuff_const(n2,nv&a[k]));
365 return;372 return;
366 }373 }
367 o(S, stuff_const(op,v&a[0]));374 o(stuff_const(op,v&a[0]));
368 o(S, stuff_const(o2,v&a[4]));375 o(stuff_const(o2,v&a[4]));
369 o(S, stuff_const(o2,v&a[8]));376 o(stuff_const(o2,v&a[8]));
370 o(S, stuff_const(o2,v&a[12]));377 o(stuff_const(o2,v&a[12]));
371 }378 }
372}379}
373 380
374uint32_t encbranch(TCCState* S, int pos, int addr, int fail)381uint32_t encbranch(int pos, int addr, int fail)
375{382{
376 addr-=pos+8;383 addr-=pos+8;
377 addr/=4;384 addr/=4;
378 if(addr>=0x1000000 || addr<-0x1000000) {385 if(addr>=0x1000000 || addr<-0x1000000) {
379 if(fail)386 if(fail)
380 tcc_error(S, "FIXME: function bigger than 32MB");387 tcc_error("FIXME: function bigger than 32MB");
381 return 0;388 return 0;
382 }389 }
383 return 0x0A000000|(addr&0xffffff);390 return 0x0A000000|(addr&0xffffff);
384}391}
385 392
386int decbranch(TCCState* S, int pos)393int decbranch(int pos)
387{394{
388 int x;395 int x;
389 x=*(uint32_t *)(cur_text_section->data + pos);396 x=*(uint32_t *)(cur_text_section->data + pos);
@@ -394,50 +401,50 @@ int decbranch(TCCState* S, int pos) · 4 unmodified lines
394}401}
395 402
396/* output a symbol and patch all calls to it */403/* output a symbol and patch all calls to it */
397void gsym_addr(TCCState* S, int t, int a)404void gsym_addr(int t, int a)
398{405{
399 uint32_t *x;406 uint32_t *x;
400 int lt;407 int lt;
401 while(t) {408 while(t) {
402 x=(uint32_t *)(cur_text_section->data + t);409 x=(uint32_t *)(cur_text_section->data + t);
403 t=decbranch(S, lt=t);410 t=decbranch(lt=t);
404 if(a==lt+4)411 if(a==lt+4)
405 *x=0xE1A00000; // nop412 *x=0xE1A00000; // nop
406 else {413 else {
407 *x &= 0xff000000;414 *x &= 0xff000000;
408 *x |= encbranch(S, lt,a,1);415 *x |= encbranch(lt,a,1);
409 }416 }
410 }417 }
411}418}
412 419
413#ifdef TCC_ARM_VFP420#ifdef TCC_ARM_VFP
414static uint32_t vfpr(TCCState* S, int r)421static uint32_t vfpr(int r)
415{422{
416 if(r<TREG_F0 || r>TREG_F7)423 if(r<TREG_F0 || r>TREG_F7)
417 tcc_error(S, "compiler error! register %i is no vfp register",r);424 tcc_error("compiler error! register %i is no vfp register",r);
418 return r - TREG_F0;425 return r - TREG_F0;
419}426}
420#else427#else
421static uint32_t fpr(TCCState* S, int r)428static uint32_t fpr(int r)
422{429{
423 if(r<TREG_F0 || r>TREG_F3)430 if(r<TREG_F0 || r>TREG_F3)
424 tcc_error(S, "compiler error! register %i is no fpa register",r);431 tcc_error("compiler error! register %i is no fpa register",r);
425 return r - TREG_F0;432 return r - TREG_F0;
426}433}
427#endif434#endif
428 435
429static uint32_t intr(TCCState* S, int r)436static uint32_t intr(int r)
430{437{
431 if(r == TREG_R12)438 if(r == TREG_R12)
432 return 12;439 return 12;
433 if(r >= TREG_R0 && r <= TREG_R3)440 if(r >= TREG_R0 && r <= TREG_R3)
434 return r - TREG_R0;441 return r - TREG_R0;
435 if (!(r >= TREG_SP && r <= TREG_LR))442 if (!(r >= TREG_SP && r <= TREG_LR))
436 tcc_error(S, "compiler error! register %i is no int register",r);443 tcc_error("compiler error! register %i is no int register",r);
437 return r + (13 - TREG_SP);444 return r + (13 - TREG_SP);
438}445}
439 446
440static void calcaddr(TCCState* S, uint32_t *base, int *off, int *sgn, int maxoff, unsigned shift)447static void calcaddr(uint32_t *base, int *off, int *sgn, int maxoff, unsigned shift)
441{448{
442 if(*off>maxoff || *off&((1<<shift)-1)) {449 if(*off>maxoff || *off&((1<<shift)-1)) {
443 uint32_t x, y;450 uint32_t x, y;
@@ -448,23 +455,23 @@ static void calcaddr(TCCState* S, uint32_t *base, int *off, int *sgn, int maxoff · 4 unmodified lines
448 *base=14; // lr455 *base=14; // lr
449 y=stuff_const(x,*off&~maxoff);456 y=stuff_const(x,*off&~maxoff);
450 if(y) {457 if(y) {
451 o(S, y);458 o(y);
452 *off&=maxoff;459 *off&=maxoff;
453 return;460 return;
454 }461 }
455 y=stuff_const(x,(*off+maxoff)&~maxoff);462 y=stuff_const(x,(*off+maxoff)&~maxoff);
456 if(y) {463 if(y) {
457 o(S, y);464 o(y);
458 *sgn=!*sgn;465 *sgn=!*sgn;
459 *off=((*off+maxoff)&~maxoff)-*off;466 *off=((*off+maxoff)&~maxoff)-*off;
460 return;467 return;
461 }468 }
462 stuff_const_harder(S, x,*off&~maxoff);469 stuff_const_harder(x,*off&~maxoff);
463 *off&=maxoff;470 *off&=maxoff;
464 }471 }
465}472}
466 473
467static uint32_t mapcc(TCCState* S, int cc)474static uint32_t mapcc(int cc)
468{475{
469 switch(cc)476 switch(cc)
470 {477 {
@@ -493,11 +500,11 @@ static uint32_t mapcc(TCCState* S, int cc) · 22 unmodified lines
493 case TOK_GT:500 case TOK_GT:
494 return 0xC0000000; /* GT */501 return 0xC0000000; /* GT */
495 }502 }
496 tcc_error(S, "unexpected condition code");503 tcc_error("unexpected condition code");
497 return 0xE0000000; /* AL */504 return 0xE0000000; /* AL */
498}505}
499 506
500static int negcc(TCCState* S, int cc)507static int negcc(int cc)
501{508{
502 switch(cc)509 switch(cc)
503 {510 {
@@ -526,44 +533,44 @@ static int negcc(TCCState* S, int cc) · 22 unmodified lines
526 case TOK_GT:533 case TOK_GT:
527 return TOK_LE;534 return TOK_LE;
528 }535 }
529 tcc_error(S, "unexpected condition code");536 tcc_error("unexpected condition code");
530 return TOK_NE;537 return TOK_NE;
531}538}
532 539
533/* Load value into register r.540/* Load value into register r.
534 Use relative/got addressing to avoid setting DT_TEXTREL */541 Use relative/got addressing to avoid setting DT_TEXTREL */
535static void load_value(TCCState* S, SValue *sv, int r)542static void load_value(SValue *sv, int r)
536{543{
537 o(S, 0xE59F0000|(intr(S, r)<<12)); /* ldr r, [pc] */544 o(0xE59F0000|(intr(r)<<12)); /* ldr r, [pc] */
538 o(S, 0xEA000000); /* b $+4 */545 o(0xEA000000); /* b $+4 */
539#ifndef CONFIG_TCC_PIE546#ifndef CONFIG_TCC_PIE
540 if(sv->r & VT_SYM)547 if(sv->r & VT_SYM)
541 greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_ARM_ABS32);548 greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32);
542 o(S, sv->c.i);549 o(sv->c.i);
543#else550#else
544 if(sv->r & VT_SYM) {551 if(sv->r & VT_SYM) {
545 if (sv->sym->type.t & VT_STATIC) {552 if (sv->sym->type.t & VT_STATIC) {
546 greloc(cur_text_section, sv->sym, ind, R_ARM_REL32);553 greloc(cur_text_section, sv->sym, ind, R_ARM_REL32);
547 o(S, sv->c.i - 12);554 o(sv->c.i - 12);
548 o(S, 0xe080000f | (intr(S, r)<<12) | (intr(S, r)<<16)); // add rx,rx,pc555 o(0xe080000f | (intr(r)<<12) | (intr(r)<<16)); // add rx,rx,pc
549 }556 }
550 else {557 else {
551 greloc(cur_text_section, sv->sym, ind, R_ARM_GOT_PREL);558 greloc(cur_text_section, sv->sym, ind, R_ARM_GOT_PREL);
552 o(S, -12);559 o(-12);
553 o(S, 0xe080000f | (intr(S, r)<<12) | (intr(S, r)<<16)); // add rx,rx,pc560 o(0xe080000f | (intr(r)<<12) | (intr(r)<<16)); // add rx,rx,pc
554 o(S, 0xe5900000 | (intr(S, r)<<12) | (intr(S, r)<<16)); // ldr rx,[rx]561 o(0xe5900000 | (intr(r)<<12) | (intr(r)<<16)); // ldr rx,[rx]
555 if (sv->c.i)562 if (sv->c.i)
556 stuff_const_harder(S, 0xe2800000 | (intr(S, r)<<12) | (intr(S, r)<<16),563 stuff_const_harder(0xe2800000 | (intr(r)<<12) | (intr(r)<<16),
557 sv->c.i);564 sv->c.i);
558 }565 }
559 }566 }
560 else567 else
561 o(S, sv->c.i);568 o(sv->c.i);
562#endif569#endif
563}570}
564 571
565/* load 'r' from value 'sv' */572/* load 'r' from value 'sv' */
566void load(TCCState* S, int r, SValue *sv)573void load(int r, SValue *sv)
567{574{
568 int v, ft, fc, fr, sign;575 int v, ft, fc, fr, sign;
569 uint32_t op;576 uint32_t op;
@@ -587,7 +594,7 @@ void load(TCCState* S, int r, SValue *sv) · 17 unmodified lines
587 v1.type.t = VT_PTR;594 v1.type.t = VT_PTR;
588 v1.r = VT_LOCAL | VT_LVAL;595 v1.r = VT_LOCAL | VT_LVAL;
589 v1.c.i = sv->c.i;596 v1.c.i = sv->c.i;
590 load(S, TREG_LR, &v1);597 load(TREG_LR, &v1);
591 base = 14; /* lr */598 base = 14; /* lr */
592 fc=sign=0;599 fc=sign=0;
593 v=VT_LOCAL;600 v=VT_LOCAL;
@@ -596,25 +603,25 @@ void load(TCCState* S, int r, SValue *sv) · 2 unmodified lines
596 v1.r = fr&~VT_LVAL;603 v1.r = fr&~VT_LVAL;
597 v1.c.i = sv->c.i;604 v1.c.i = sv->c.i;
598 v1.sym=sv->sym;605 v1.sym=sv->sym;
599 load(S, TREG_LR, &v1);606 load(TREG_LR, &v1);
600 base = 14; /* lr */607 base = 14; /* lr */
601 fc=sign=0;608 fc=sign=0;
602 v=VT_LOCAL;609 v=VT_LOCAL;
603 } else if(v < VT_CONST) {610 } else if(v < VT_CONST) {
604 base=intr(S, v);611 base=intr(v);
605 fc=sign=0;612 fc=sign=0;
606 v=VT_LOCAL;613 v=VT_LOCAL;
607 }614 }
608 if(v == VT_LOCAL) {615 if(v == VT_LOCAL) {
609 if(is_float(ft)) {616 if(is_float(ft)) {
610 calcaddr(S, &base,&fc,&sign,1020,2);617 calcaddr(&base,&fc,&sign,1020,2);
611#ifdef TCC_ARM_VFP618#ifdef TCC_ARM_VFP
612 op=0xED100A00; /* flds */619 op=0xED100A00; /* flds */
613 if(!sign)620 if(!sign)
614 op|=0x800000;621 op|=0x800000;
615 if ((ft & VT_BTYPE) != VT_FLOAT)622 if ((ft & VT_BTYPE) != VT_FLOAT)
616 op|=0x100; /* flds -> fldd */623 op|=0x100; /* flds -> fldd */
617 o(S, op|(vfpr(S, r)<<12)|(fc>>2)|(base<<16));624 o(op|(vfpr(r)<<12)|(fc>>2)|(base<<16));
618#else625#else
619 op=0xED100100;626 op=0xED100100;
620 if(!sign)627 if(!sign)
@@ -628,11 +635,11 @@ void load(TCCState* S, int r, SValue *sv) · 7 unmodified lines
628 else if ((ft & VT_BTYPE) == VT_LDOUBLE)635 else if ((ft & VT_BTYPE) == VT_LDOUBLE)
629 op|=0x400000;636 op|=0x400000;
630#endif637#endif
631 o(S, op|(fpr(S, r)<<12)|(fc>>2)|(base<<16));638 o(op|(fpr(r)<<12)|(fc>>2)|(base<<16));
632#endif639#endif
633 } else if((ft & (VT_BTYPE|VT_UNSIGNED)) == VT_BYTE640 } else if((ft & (VT_BTYPE|VT_UNSIGNED)) == VT_BYTE
634 || (ft & VT_BTYPE) == VT_SHORT) {641 || (ft & VT_BTYPE) == VT_SHORT) {
635 calcaddr(S, &base,&fc,&sign,255,0);642 calcaddr(&base,&fc,&sign,255,0);
636 op=0xE1500090;643 op=0xE1500090;
637 if ((ft & VT_BTYPE) == VT_SHORT)644 if ((ft & VT_BTYPE) == VT_SHORT)
638 op|=0x20;645 op|=0x20;
@@ -640,63 +647,63 @@ void load(TCCState* S, int r, SValue *sv) · 1 unmodified line
640 op|=0x40;647 op|=0x40;
641 if(!sign)648 if(!sign)
642 op|=0x800000;649 op|=0x800000;
643 o(S, op|(intr(S, r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf));650 o(op|(intr(r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf));
644 } else {651 } else {
645 calcaddr(S, &base,&fc,&sign,4095,0);652 calcaddr(&base,&fc,&sign,4095,0);
646 op=0xE5100000;653 op=0xE5100000;
647 if(!sign)654 if(!sign)
648 op|=0x800000;655 op|=0x800000;
649 if ((ft & VT_BTYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_BOOL)656 if ((ft & VT_BTYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_BOOL)
650 op|=0x400000;657 op|=0x400000;
651 o(S, op|(intr(S, r)<<12)|fc|(base<<16));658 o(op|(intr(r)<<12)|fc|(base<<16));
652 }659 }
653 return;660 return;
654 }661 }
655 } else {662 } else {
656 if (v == VT_CONST) {663 if (v == VT_CONST) {
657 op=stuff_const(0xE3A00000|(intr(S, r)<<12),sv->c.i);664 op=stuff_const(0xE3A00000|(intr(r)<<12),sv->c.i);
658 if (fr & VT_SYM || !op)665 if (fr & VT_SYM || !op)
659 load_value(S, sv, r);666 load_value(sv, r);
660 else667 else
661 o(S, op);668 o(op);
662 return;669 return;
663 } else if (v == VT_LOCAL) {670 } else if (v == VT_LOCAL) {
664 op=stuff_const(0xE28B0000|(intr(S, r)<<12),sv->c.i);671 op=stuff_const(0xE28B0000|(intr(r)<<12),sv->c.i);
665 if (fr & VT_SYM || !op) {672 if (fr & VT_SYM || !op) {
666 load_value(S, sv, r);673 load_value(sv, r);
667 o(S, 0xE08B0000|(intr(S, r)<<12)|intr(S, r));674 o(0xE08B0000|(intr(r)<<12)|intr(r));
668 } else675 } else
669 o(S, op);676 o(op);
670 return;677 return;
671 } else if(v == VT_CMP) {678 } else if(v == VT_CMP) {
672 o(S, mapcc(S, sv->c.i)|0x3A00001|(intr(S, r)<<12));679 o(mapcc(sv->c.i)|0x3A00001|(intr(r)<<12));
673 o(S, mapcc(S, negcc(S, sv->c.i))|0x3A00000|(intr(S, r)<<12));680 o(mapcc(negcc(sv->c.i))|0x3A00000|(intr(r)<<12));
674 return;681 return;
675 } else if (v == VT_JMP || v == VT_JMPI) {682 } else if (v == VT_JMP || v == VT_JMPI) {
676 int t;683 int t;
677 t = v & 1;684 t = v & 1;
678 o(S, 0xE3A00000|(intr(S, r)<<12)|t);685 o(0xE3A00000|(intr(r)<<12)|t);
679 o(S, 0xEA000000);686 o(0xEA000000);
680 gsym(S, sv->c.i);687 gsym(sv->c.i);
681 o(S, 0xE3A00000|(intr(S, r)<<12)|(t^1));688 o(0xE3A00000|(intr(r)<<12)|(t^1));
682 return;689 return;
683 } else if (v < VT_CONST) {690 } else if (v < VT_CONST) {
684 if(is_float(ft))691 if(is_float(ft))
685#ifdef TCC_ARM_VFP692#ifdef TCC_ARM_VFP
686 o(S, 0xEEB00A40|(vfpr(S, r)<<12)|vfpr(S, v)|T2CPR(ft)); /* fcpyX */693 o(0xEEB00A40|(vfpr(r)<<12)|vfpr(v)|T2CPR(ft)); /* fcpyX */
687#else694#else
688 o(S, 0xEE008180|(fpr(S, r)<<12)|fpr(S, v));695 o(0xEE008180|(fpr(r)<<12)|fpr(v));
689#endif696#endif
690 else697 else
691 o(S, 0xE1A00000|(intr(S, r)<<12)|intr(S, v));698 o(0xE1A00000|(intr(r)<<12)|intr(v));
692 return;699 return;
693 }700 }
694 }701 }
695 tcc_error(S, "load unimplemented!");702 tcc_error("load unimplemented!");
696}703}
697 704
698/* store register 'r' in lvalue 'v' */705/* store register 'r' in lvalue 'v' */
699void store(TCCState* S, int r, SValue *sv)706void store(int r, SValue *sv)
700{707{
701 SValue v1;708 SValue v1;
702 int v, ft, fc, fr, sign;709 int v, ft, fc, fr, sign;
@@ -717,7 +724,7 @@ void store(TCCState* S, int r, SValue *sv) · 14 unmodified lines
717 if (fr & VT_LVAL || fr == VT_LOCAL) {724 if (fr & VT_LVAL || fr == VT_LOCAL) {
718 uint32_t base = 0xb; /* fp */725 uint32_t base = 0xb; /* fp */
719 if(v < VT_CONST) {726 if(v < VT_CONST) {
720 base=intr(S, v);727 base=intr(v);
721 v=VT_LOCAL;728 v=VT_LOCAL;
722 fc=sign=0;729 fc=sign=0;
723 } else if(v == VT_CONST) {730 } else if(v == VT_CONST) {
@@ -725,21 +732,21 @@ void store(TCCState* S, int r, SValue *sv) · 1 unmodified line
725 v1.r = fr&~VT_LVAL;732 v1.r = fr&~VT_LVAL;
726 v1.c.i = sv->c.i;733 v1.c.i = sv->c.i;
727 v1.sym=sv->sym;734 v1.sym=sv->sym;
728 load(S, TREG_LR, &v1);735 load(TREG_LR, &v1);
729 base = 14; /* lr */736 base = 14; /* lr */
730 fc=sign=0;737 fc=sign=0;
731 v=VT_LOCAL;738 v=VT_LOCAL;
732 }739 }
733 if(v == VT_LOCAL) {740 if(v == VT_LOCAL) {
734 if(is_float(ft)) {741 if(is_float(ft)) {
735 calcaddr(S, &base,&fc,&sign,1020,2);742 calcaddr(&base,&fc,&sign,1020,2);
736#ifdef TCC_ARM_VFP743#ifdef TCC_ARM_VFP
737 op=0xED000A00; /* fsts */744 op=0xED000A00; /* fsts */
738 if(!sign)745 if(!sign)
739 op|=0x800000;746 op|=0x800000;
740 if ((ft & VT_BTYPE) != VT_FLOAT)747 if ((ft & VT_BTYPE) != VT_FLOAT)
741 op|=0x100; /* fsts -> fstd */748 op|=0x100; /* fsts -> fstd */
742 o(S, op|(vfpr(S, r)<<12)|(fc>>2)|(base<<16));749 o(op|(vfpr(r)<<12)|(fc>>2)|(base<<16));
743#else750#else
744 op=0xED000100;751 op=0xED000100;
745 if(!sign)752 if(!sign)
@@ -753,138 +760,138 @@ void store(TCCState* S, int r, SValue *sv) · 7 unmodified lines
753 if ((ft & VT_BTYPE) == VT_LDOUBLE)760 if ((ft & VT_BTYPE) == VT_LDOUBLE)
754 op|=0x400000;761 op|=0x400000;
755#endif762#endif
756 o(S, op|(fpr(S, r)<<12)|(fc>>2)|(base<<16));763 o(op|(fpr(r)<<12)|(fc>>2)|(base<<16));
757#endif764#endif
758 return;765 return;
759 } else if((ft & VT_BTYPE) == VT_SHORT) {766 } else if((ft & VT_BTYPE) == VT_SHORT) {
760 calcaddr(S, &base,&fc,&sign,255,0);767 calcaddr(&base,&fc,&sign,255,0);
761 op=0xE14000B0;768 op=0xE14000B0;
762 if(!sign)769 if(!sign)
763 op|=0x800000;770 op|=0x800000;
764 o(S, op|(intr(S, r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf));771 o(op|(intr(r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf));
765 } else {772 } else {
766 calcaddr(S, &base,&fc,&sign,4095,0);773 calcaddr(&base,&fc,&sign,4095,0);
767 op=0xE5000000;774 op=0xE5000000;
768 if(!sign)775 if(!sign)
769 op|=0x800000;776 op|=0x800000;
770 if ((ft & VT_BTYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_BOOL)777 if ((ft & VT_BTYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_BOOL)
771 op|=0x400000;778 op|=0x400000;
772 o(S, op|(intr(S, r)<<12)|fc|(base<<16));779 o(op|(intr(r)<<12)|fc|(base<<16));
773 }780 }
774 return;781 return;
775 }782 }
776 }783 }
777 tcc_error(S, "store unimplemented");784 tcc_error("store unimplemented");
778}785}
779 786
780static void gadd_sp(TCCState* S, int val)787static void gadd_sp(int val)
781{788{
782 stuff_const_harder(S, 0xE28DD000,val);789 stuff_const_harder(0xE28DD000,val);
783}790}
784 791
785/* 'is_jmp' is '1' if it is a jump */792/* 'is_jmp' is '1' if it is a jump */
786static void gcall_or_jmp(TCCState* S, int is_jmp)793static void gcall_or_jmp(int is_jmp)
787{794{
788 int r;795 int r;
789 uint32_t x;796 uint32_t x;
790 if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {797 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
791 /* constant case */798 /* constant case */
792 if(S->tccgen_vtop->r & VT_SYM){799 if(vtop->r & VT_SYM){
793 x=encbranch(S, S->tccgen_ind, S->tccgen_ind+S->tccgen_vtop->c.i,0);800 x=encbranch(ind,ind+vtop->c.i,0);
794 if(x) {801 if(x) {
795 /* relocation case */802 /* relocation case */
796 greloc(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind, R_ARM_PC24);803 greloc(cur_text_section, vtop->sym, ind, R_ARM_PC24);
797 o(S, x|(is_jmp?0xE0000000:0xE1000000));804 o(x|(is_jmp?0xE0000000:0xE1000000));
798 } else {805 } else {
799 r = TREG_LR;806 r = TREG_LR;
800 load_value(S, S->tccgen_vtop, r);807 load_value(vtop, r);
801 if(is_jmp)808 if(is_jmp)
802 o(S, 0xE1A0F000 | intr(S, r)); // mov pc, r809 o(0xE1A0F000 | intr(r)); // mov pc, r
803 else810 else
804 o(S, 0xe12fff30 | intr(S, r)); // blx r811 o(0xe12fff30 | intr(r)); // blx r
805 }812 }
806 }else{813 }else{
807 if(!is_jmp)814 if(!is_jmp)
808 o(S, 0xE28FE004); // add lr,pc,#4815 o(0xE28FE004); // add lr,pc,#4
809 o(S, 0xE51FF004); // ldr pc,[pc,#-4]816 o(0xE51FF004); // ldr pc,[pc,#-4]
810 o(S, S->tccgen_vtop->c.i);817 o(vtop->c.i);
811 }818 }
812 } else {819 } else {
813 /* otherwise, indirect call */820 /* otherwise, indirect call */
814#ifdef CONFIG_TCC_BCHECK821#ifdef CONFIG_TCC_BCHECK
815 S->tccgen_vtop->r &= ~VT_MUSTBOUND;822 vtop->r &= ~VT_MUSTBOUND;
816#endif823#endif
817 r = gv(S, RC_INT);824 r = gv(RC_INT);
818 if(!is_jmp)825 if(!is_jmp)
819 o(S, 0xE1A0E00F); // mov lr,pc826 o(0xE1A0E00F); // mov lr,pc
820 o(S, 0xE1A0F000|intr(S, r)); // mov pc,r827 o(0xE1A0F000|intr(r)); // mov pc,r
821 }828 }
822}829}
823 830
824#if defined(CONFIG_TCC_BCHECK)831#if defined(CONFIG_TCC_BCHECK)
825 832
826static void gen_bounds_call(TCCState* S, int v)833static void gen_bounds_call(int v)
827{834{
828 Sym *sym = external_helper_sym(S, v);835 Sym *sym = external_helper_sym(v);
829 836
830 greloc(S, cur_text_section, sym, S->tccgen_ind, R_ARM_PC24);837 greloc(cur_text_section, sym, ind, R_ARM_PC24);
831 o(S, 0xebfffffe);838 o(0xebfffffe);
832}839}
833 840
834static void gen_bounds_prolog(TCCState* S)841static void gen_bounds_prolog(void)
835{842{
836 /* leave some room for bound checking code */843 /* leave some room for bound checking code */
837 S->func_bound_offset = lbounds_section->data_offset;844 func_bound_offset = lbounds_section->data_offset;
838 S->func_bound_ind = S->tccgen_ind;845 func_bound_ind = ind;
839 S->func_bound_add_epilog = 0;846 func_bound_add_epilog = 0;
840 o(S, 0xe1a00000); /* ld r0,lbounds_section->data_offset */847 o(0xe1a00000); /* ld r0,lbounds_section->data_offset */
841 o(S, 0xe1a00000);848 o(0xe1a00000);
842 o(S, 0xe1a00000);849 o(0xe1a00000);
843 o(S, 0xe1a00000);850 o(0xe1a00000);
844 o(S, 0xe1a00000); /* call __bound_local_new */851 o(0xe1a00000); /* call __bound_local_new */
845}852}
846 853
847static void gen_bounds_epilog(TCCState* S)854static void gen_bounds_epilog(void)
848{855{
849 addr_t saved_ind;856 addr_t saved_ind;
850 addr_t *bounds_ptr;857 addr_t *bounds_ptr;
851 Sym *sym_data;858 Sym *sym_data;
852 int offset_modified = S->func_bound_offset != lbounds_section->data_offset;859 int offset_modified = func_bound_offset != lbounds_section->data_offset;
853 860
854 if (!offset_modified && !S->func_bound_add_epilog)861 if (!offset_modified && !func_bound_add_epilog)
855 return;862 return;
856 863
857 /* add end of table info */864 /* add end of table info */
858 bounds_ptr = section_ptr_add(S, lbounds_section, sizeof(addr_t));865 bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));
859 *bounds_ptr = 0;866 *bounds_ptr = 0;
860 867
861 sym_data = get_sym_ref(S, &S->tccgen_char_pointer_type, lbounds_section,868 sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
862 S->func_bound_offset, lbounds_section->data_offset);869 func_bound_offset, lbounds_section->data_offset);
863 870
864 /* generate bound local allocation */871 /* generate bound local allocation */
865 if (offset_modified) {872 if (offset_modified) {
866 saved_ind = S->tccgen_ind;873 saved_ind = ind;
867 S->tccgen_ind = S->func_bound_ind;874 ind = func_bound_ind;
868 o(S, 0xe59f0000); /* ldr r0, [pc] */875 o(0xe59f0000); /* ldr r0, [pc] */
869 o(S, 0xea000000); /* b $+4 */876 o(0xea000000); /* b $+4 */
870 greloc(S, cur_text_section, sym_data, S->tccgen_ind, R_ARM_REL32);877 greloc(cur_text_section, sym_data, ind, R_ARM_REL32);
871 o(S, -12); /* lbounds_section->data_offset */878 o(-12); /* lbounds_section->data_offset */
872 o(S, 0xe080000f); /* add r0,r0,pc */879 o(0xe080000f); /* add r0,r0,pc */
873 gen_bounds_call(S, TOK___bound_local_new);880 gen_bounds_call(TOK___bound_local_new);
874 S->tccgen_ind = saved_ind;881 ind = saved_ind;
875 }882 }
876 883
877 /* generate bound check local freeing */884 /* generate bound check local freeing */
878 o(S, 0xe92d0003); /* push {r0,r1} */885 o(0xe92d0003); /* push {r0,r1} */
879 o(S, 0xed2d0b02); /* vpush {d0} */886 o(0xed2d0b02); /* vpush {d0} */
880 o(S, 0xe59f0000); /* ldr r0, [pc] */887 o(0xe59f0000); /* ldr r0, [pc] */
881 o(S, 0xea000000); /* b $+4 */888 o(0xea000000); /* b $+4 */
882 greloc(S, cur_text_section, sym_data, S->tccgen_ind, R_ARM_REL32);889 greloc(cur_text_section, sym_data, ind, R_ARM_REL32);
883 o(S, -12); /* lbounds_section->data_offset */890 o(-12); /* lbounds_section->data_offset */
884 o(S, 0xe080000f); /* add r0,r0,pc */891 o(0xe080000f); /* add r0,r0,pc */
885 gen_bounds_call(S, TOK___bound_local_delete);892 gen_bounds_call(TOK___bound_local_delete);
886 o(S, 0xecbd0b02); /* vpop {d0} */893 o(0xecbd0b02); /* vpop {d0} */
887 o(S, 0xe8bd0003); /* pop {r0,r1} */894 o(0xe8bd0003); /* pop {r0,r1} */
888}895}
889#endif896#endif
890 897
@@ -1070,7 +1077,7 @@ static void add_param_plan(struct plan* plan, int cls, int start, int end, SValu · 179 unmodified lines
1070 Note: this function allocated an array in plan->pplans with tcc_malloc. It1077 Note: this function allocated an array in plan->pplans with tcc_malloc. It
1071 is the responsibility of the caller to free this array once used (ie not1078 is the responsibility of the caller to free this array once used (ie not
1072 before copy_params). */1079 before copy_params). */
1073static int assign_regs(TCCState *S, int nb_args, int float_abi, struct plan *plan, int *todo)1080static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo)
1074{1081{
1075 int i, size, align;1082 int i, size, align;
1076 int ncrn /* next core register number */, nsaa /* next stacked argument address*/;1083 int ncrn /* next core register number */, nsaa /* next stacked argument address*/;
@@ -1081,12 +1088,12 @@ static int assign_regs(TCCState *S, int nb_args, int float_abi, struct plan *pla · 4 unmodified lines
1081 1088
1082 for(i = nb_args; i-- ;) {1089 for(i = nb_args; i-- ;) {
1083 int j, start_vfpreg = 0;1090 int j, start_vfpreg = 0;
1084 CType type = S->tccgen_vtop[-i].type;1091 CType type = vtop[-i].type;
1085 type.t &= ~VT_ARRAY;1092 type.t &= ~VT_ARRAY;
1086 size = type_size(&type, &align);1093 size = type_size(&type, &align);
1087 size = (size + 3) & ~3;1094 size = (size + 3) & ~3;
1088 align = (align + 3) & ~3;1095 align = (align + 3) & ~3;
1089 switch(S->tccgen_vtop[-i].type.t & VT_BTYPE) {1096 switch(vtop[-i].type.t & VT_BTYPE) {
1090 case VT_STRUCT:1097 case VT_STRUCT:
1091 case VT_FLOAT:1098 case VT_FLOAT:
1092 case VT_DOUBLE:1099 case VT_DOUBLE:
@@ -1094,15 +1101,15 @@ static int assign_regs(TCCState *S, int nb_args, int float_abi, struct plan *pla · 1 unmodified line
1094 if (float_abi == ARM_HARD_FLOAT) {1101 if (float_abi == ARM_HARD_FLOAT) {
1095 int is_hfa = 0; /* Homogeneous float aggregate */1102 int is_hfa = 0; /* Homogeneous float aggregate */
1096 1103
1097 if (is_float(S->tccgen_vtop[-i].type.t)1104 if (is_float(vtop[-i].type.t)
1098 || (is_hfa = is_hgen_float_aggr(&S->tccgen_vtop[-i].type))) {1105 || (is_hfa = is_hgen_float_aggr(&vtop[-i].type))) {
1099 int end_vfpreg;1106 int end_vfpreg;
1100 1107
1101 start_vfpreg = assign_vfpreg(&avregs, align, size);1108 start_vfpreg = assign_vfpreg(&avregs, align, size);
1102 end_vfpreg = start_vfpreg + ((size - 1) >> 2);1109 end_vfpreg = start_vfpreg + ((size - 1) >> 2);
1103 if (start_vfpreg >= 0) {1110 if (start_vfpreg >= 0) {
1104 add_param_plan(plan, is_hfa ? VFP_STRUCT_CLASS : VFP_CLASS,1111 add_param_plan(plan, is_hfa ? VFP_STRUCT_CLASS : VFP_CLASS,
1105 start_vfpreg, end_vfpreg, &S->tccgen_vtop[-i]);1112 start_vfpreg, end_vfpreg, &vtop[-i]);
1106 continue;1113 continue;
1107 } else1114 } else
1108 break;1115 break;
@@ -1115,7 +1122,7 @@ static int assign_regs(TCCState *S, int nb_args, int float_abi, struct plan *pla · 6 unmodified lines
1115 * CORE_STRUCT_CLASS or the first of STACK_CLASS. */1122 * CORE_STRUCT_CLASS or the first of STACK_CLASS. */
1116 for (j = ncrn; j < 4 && j < ncrn + size / 4; j++)1123 for (j = ncrn; j < 4 && j < ncrn + size / 4; j++)
1117 *todo|=(1<<j);1124 *todo|=(1<<j);
1118 add_param_plan(plan, CORE_STRUCT_CLASS, ncrn, j, &S->tccgen_vtop[-i]);1125 add_param_plan(plan, CORE_STRUCT_CLASS, ncrn, j, &vtop[-i]);
1119 ncrn += size/4;1126 ncrn += size/4;
1120 if (ncrn > 4)1127 if (ncrn > 4)
1121 nsaa = (ncrn - 4) * 4;1128 nsaa = (ncrn - 4) * 4;
@@ -1126,20 +1133,20 @@ static int assign_regs(TCCState *S, int nb_args, int float_abi, struct plan *pla · 4 unmodified lines
1126 continue;1133 continue;
1127 default:1134 default:
1128 if (ncrn < 4) {1135 if (ncrn < 4) {
1129 int is_long = (S->tccgen_vtop[-i].type.t & VT_BTYPE) == VT_LLONG;1136 int is_long = (vtop[-i].type.t & VT_BTYPE) == VT_LLONG;
1130 1137
1131 if (is_long) {1138 if (is_long) {
1132 ncrn = (ncrn + 1) & -2;1139 ncrn = (ncrn + 1) & -2;
1133 if (ncrn == 4)1140 if (ncrn == 4)
1134 break;1141 break;
1135 }1142 }
1136 add_param_plan(plan, CORE_CLASS, ncrn, ncrn + is_long, &S->tccgen_vtop[-i]);1143 add_param_plan(plan, CORE_CLASS, ncrn, ncrn + is_long, &vtop[-i]);
1137 ncrn += 1 + is_long;1144 ncrn += 1 + is_long;
1138 continue;1145 continue;
1139 }1146 }
1140 }1147 }
1141 nsaa = (nsaa + (align - 1)) & ~(align - 1);1148 nsaa = (nsaa + (align - 1)) & ~(align - 1);
1142 add_param_plan(plan, STACK_CLASS, nsaa, nsaa + size, &S->tccgen_vtop[-i]);1149 add_param_plan(plan, STACK_CLASS, nsaa, nsaa + size, &vtop[-i]);
1143 nsaa += size; /* size already rounded up before */1150 nsaa += size; /* size already rounded up before */
1144 }1151 }
1145 return nsaa;1152 return nsaa;
@@ -1153,7 +1160,7 @@ static int assign_regs(TCCState *S, int nb_args, int float_abi, struct plan *pla · 7 unmodified lines
1153 todo: a bitmap indicating what core reg will hold a parameter1160 todo: a bitmap indicating what core reg will hold a parameter
1154 1161
1155 Returns the number of SValue added by this function on the value stack */1162 Returns the number of SValue added by this function on the value stack */
1156static int copy_params(TCCState* S, int nb_args, struct plan *plan, int todo)1163static int copy_params(int nb_args, struct plan *plan, int todo)
1157{1164{
1158 int size, align, r, i, nb_extra_sval = 0;1165 int size, align, r, i, nb_extra_sval = 0;
1159 struct param_plan *pplan;1166 struct param_plan *pplan;
@@ -1182,7 +1189,7 @@ again: · 22 unmodified lines
1182 && (i != CORE_CLASS || pplan->sval->r < VT_CONST))1189 && (i != CORE_CLASS || pplan->sval->r < VT_CONST))
1183 continue;1190 continue;
1184 1191
1185 vpushv(S, pplan->sval);1192 vpushv(pplan->sval);
1186 pplan->sval->r = pplan->sval->r2 = VT_CONST; /* disable entry */1193 pplan->sval->r = pplan->sval->r2 = VT_CONST; /* disable entry */
1187 switch(i) {1194 switch(i) {
1188 case STACK_CLASS:1195 case STACK_CLASS:
@@ -1197,16 +1204,16 @@ again: · 8 unmodified lines
1197 padding = pplan->start - pplan->prev->end;1204 padding = pplan->start - pplan->prev->end;
1198 size += padding; /* Add padding if any */1205 size += padding; /* Add padding if any */
1199 /* allocate the necessary size on stack */1206 /* allocate the necessary size on stack */
1200 gadd_sp(S, -size);1207 gadd_sp(-size);
1201 /* generate structure store */1208 /* generate structure store */
1202 r = get_reg(S, RC_INT);1209 r = get_reg(RC_INT);
1203 o(S, 0xE28D0000|(intr(S, r)<<12)|padding); /* add r, sp, padding */1210 o(0xE28D0000|(intr(r)<<12)|padding); /* add r, sp, padding */
1204 vset(S, &S->tccgen_vtop->type, r | VT_LVAL, 0);1211 vset(&vtop->type, r | VT_LVAL, 0);
1205 vswap(S);1212 vswap();
1206 /* XXX: optimize. Save all register because memcpy can use them */1213 /* XXX: optimize. Save all register because memcpy can use them */
1207 o(S, 0xED2D0A00|(0&1)<<22|(0>>1)<<12|16); /* vpush {s0-s15} */1214 o(0xED2D0A00|(0&1)<<22|(0>>1)<<12|16); /* vpush {s0-s15} */
1208 vstore(S); /* memcpy to current sp + potential padding */1215 vstore(); /* memcpy to current sp + potential padding */
1209 o(S, 0xECBD0A00|(0&1)<<22|(0>>1)<<12|16); /* vpop {s0-s15} */1216 o(0xECBD0A00|(0&1)<<22|(0>>1)<<12|16); /* vpop {s0-s15} */
1210 1217
1211 /* Homogeneous float aggregate are loaded to VFP registers1218 /* Homogeneous float aggregate are loaded to VFP registers
1212 immediately since there is no way of loading data in multiple1219 immediately since there is no way of loading data in multiple
@@ -1215,23 +1222,23 @@ again: · 2 unmodified lines
1215 if (i == VFP_STRUCT_CLASS) {1222 if (i == VFP_STRUCT_CLASS) {
1216 int first = pplan->start, nb = pplan->end - first + 1;1223 int first = pplan->start, nb = pplan->end - first + 1;
1217 /* vpop.32 {pplan->start, ..., pplan->end} */1224 /* vpop.32 {pplan->start, ..., pplan->end} */
1218 o(S, 0xECBD0A00|(first&1)<<22|(first>>1)<<12|nb);1225 o(0xECBD0A00|(first&1)<<22|(first>>1)<<12|nb);
1219 /* No need to write the register used to a SValue since VFP regs1226 /* No need to write the register used to a SValue since VFP regs
1220 cannot be used for gcall_or_jmp */1227 cannot be used for gcall_or_jmp */
1221 }1228 }
1222 } else {1229 } else {
1223 if (is_float(pplan->sval->type.t)) {1230 if (is_float(pplan->sval->type.t)) {
1224#ifdef TCC_ARM_VFP1231#ifdef TCC_ARM_VFP
1225 r = vfpr(S, gv(S, RC_FLOAT)) << 12;1232 r = vfpr(gv(RC_FLOAT)) << 12;
1226 if ((pplan->sval->type.t & VT_BTYPE) == VT_FLOAT)1233 if ((pplan->sval->type.t & VT_BTYPE) == VT_FLOAT)
1227 size = 4;1234 size = 4;
1228 else {1235 else {
1229 size = 8;1236 size = 8;
1230 r |= 0x101; /* vpush.32 -> vpush.64 */1237 r |= 0x101; /* vpush.32 -> vpush.64 */
1231 }1238 }
1232 o(S, 0xED2D0A01 + r); /* vpush */1239 o(0xED2D0A01 + r); /* vpush */
1233#else1240#else
1234 r = fpr(S, gv(S, RC_FLOAT)) << 12;1241 r = fpr(gv(RC_FLOAT)) << 12;
1235 if ((pplan->sval->type.t & VT_BTYPE) == VT_FLOAT)1242 if ((pplan->sval->type.t & VT_BTYPE) == VT_FLOAT)
1236 size = 4;1243 size = 4;
1237 else if ((pplan->sval->type.t & VT_BTYPE) == VT_DOUBLE)1244 else if ((pplan->sval->type.t & VT_BTYPE) == VT_DOUBLE)
@@ -1244,49 +1251,49 @@ again: · 6 unmodified lines
1244 else if(size == 8)1251 else if(size == 8)
1245 r|=0x8000;1252 r|=0x8000;
1246 1253
1247 o(S, 0xED2D0100|r|(size>>2)); /* some kind of vpush for FPA */1254 o(0xED2D0100|r|(size>>2)); /* some kind of vpush for FPA */
1248#endif1255#endif
1249 } else {1256 } else {
1250 /* simple type (currently always same size) */1257 /* simple type (currently always same size) */
1251 /* XXX: implicit cast ? */1258 /* XXX: implicit cast ? */
1252 size=4;1259 size=4;
1253 if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) {1260 if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) {
1254 lexpand(S);1261 lexpand();
1255 size = 8;1262 size = 8;
1256 r = gv(S, RC_INT);1263 r = gv(RC_INT);
1257 o(S, 0xE52D0004|(intr(S, r)<<12)); /* push r */1264 o(0xE52D0004|(intr(r)<<12)); /* push r */
1258 S->tccgen_vtop--;1265 vtop--;
1259 }1266 }
1260 r = gv(S, RC_INT);1267 r = gv(RC_INT);
1261 o(S, 0xE52D0004|(intr(S, r)<<12)); /* push r */1268 o(0xE52D0004|(intr(r)<<12)); /* push r */
1262 }1269 }
1263 if (i == STACK_CLASS && pplan->prev)1270 if (i == STACK_CLASS && pplan->prev)
1264 gadd_sp(S, pplan->prev->end - pplan->start); /* Add padding if any */1271 gadd_sp(pplan->prev->end - pplan->start); /* Add padding if any */
1265 }1272 }
1266 break;1273 break;
1267 1274
1268 case VFP_CLASS:1275 case VFP_CLASS:
1269 gv(S, regmask(S, TREG_F0 + (pplan->start >> 1)));1276 gv(regmask(TREG_F0 + (pplan->start >> 1)));
1270 if (pplan->start & 1) { /* Must be in upper part of double register */1277 if (pplan->start & 1) { /* Must be in upper part of double register */
1271 o(S, 0xEEF00A40|((pplan->start>>1)<<12)|(pplan->start>>1)); /* vmov.f32 s(n+1), sn */1278 o(0xEEF00A40|((pplan->start>>1)<<12)|(pplan->start>>1)); /* vmov.f32 s(n+1), sn */
1272 S->tccgen_vtop->r = VT_CONST; /* avoid being saved on stack by gv for next float */1279 vtop->r = VT_CONST; /* avoid being saved on stack by gv for next float */
1273 }1280 }
1274 break;1281 break;
1275 1282
1276 case CORE_CLASS:1283 case CORE_CLASS:
1277 if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) {1284 if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) {
1278 lexpand(S);1285 lexpand();
1279 gv(S, regmask(S, pplan->end));1286 gv(regmask(pplan->end));
1280 pplan->sval->r2 = S->tccgen_vtop->r;1287 pplan->sval->r2 = vtop->r;
1281 S->tccgen_vtop--;1288 vtop--;
1282 }1289 }
1283 gv(S, regmask(S, pplan->start));1290 gv(regmask(pplan->start));
1284 /* Mark register as used so that gcall_or_jmp use another one1291 /* Mark register as used so that gcall_or_jmp use another one
1285 (regs >=4 are free as never used to pass parameters) */1292 (regs >=4 are free as never used to pass parameters) */
1286 pplan->sval->r = S->tccgen_vtop->r;1293 pplan->sval->r = vtop->r;
1287 break;1294 break;
1288 }1295 }
1289 S->tccgen_vtop--;1296 vtop--;
1290 }1297 }
1291 }1298 }
1292 1299
@@ -1297,10 +1304,10 @@ again: · 4 unmodified lines
1297 1304
1298 /* Manually free remaining registers since next parameters are loaded1305 /* Manually free remaining registers since next parameters are loaded
1299 * manually, without the help of gv(int). */1306 * manually, without the help of gv(int). */
1300 save_regs(S, nb_args);1307 save_regs(nb_args);
1301 1308
1302 if(todo) {1309 if(todo) {
1303 o(S, 0xE8BD0000|todo); /* pop {todo} */1310 o(0xE8BD0000|todo); /* pop {todo} */
1304 for(pplan = plan->clsplans[CORE_STRUCT_CLASS]; pplan; pplan = pplan->prev) {1311 for(pplan = plan->clsplans[CORE_STRUCT_CLASS]; pplan; pplan = pplan->prev) {
1305 int r;1312 int r;
1306 pplan->sval->r = pplan->start;1313 pplan->sval->r = pplan->start;
@@ -1311,8 +1318,8 @@ again: · 4 unmodified lines
1311 for (r = pplan->start + 1; r <= pplan->end; r++) {1318 for (r = pplan->start + 1; r <= pplan->end; r++) {
1312 if (todo & (1 << r)) {1319 if (todo & (1 << r)) {
1313 nb_extra_sval++;1320 nb_extra_sval++;
1314 vpushi(S, 0);1321 vpushi(0);
1315 S->tccgen_vtop->r = r;1322 vtop->r = r;
1316 }1323 }
1317 }1324 }
1318 }1325 }
@@ -1323,7 +1330,7 @@ again: · 4 unmodified lines
1323/* Generate function call. The function address is pushed first, then1330/* Generate function call. The function address is pushed first, then
1324 all the parameters in call order. This functions pops all the1331 all the parameters in call order. This functions pops all the
1325 parameters and the function address. */1332 parameters and the function address. */
1326void gfunc_call(TCCState* S, int nb_args)1333void gfunc_call(int nb_args)
1327{1334{
1328 int r, args_size;1335 int r, args_size;
1329 int def_float_abi = float_abi;1336 int def_float_abi = float_abi;
@@ -1334,62 +1341,62 @@ void gfunc_call(TCCState* S, int nb_args) · 4 unmodified lines
1334#endif1341#endif
1335 1342
1336#ifdef CONFIG_TCC_BCHECK1343#ifdef CONFIG_TCC_BCHECK
1337 if (S->do_bounds_check)1344 if (tcc_state->do_bounds_check)
1338 gbound_args(S, nb_args);1345 gbound_args(nb_args);
1339#endif1346#endif
1340 1347
1341#ifdef TCC_ARM_EABI1348#ifdef TCC_ARM_EABI
1342 if (float_abi == ARM_HARD_FLOAT) {1349 if (float_abi == ARM_HARD_FLOAT) {
1343 variadic = (S->tccgen_vtop[-nb_args].type.ref->f.func_type == FUNC_ELLIPSIS);1350 variadic = (vtop[-nb_args].type.ref->f.func_type == FUNC_ELLIPSIS);
1344 if (variadic || floats_in_core_regs(&S->tccgen_vtop[-nb_args]))1351 if (variadic || floats_in_core_regs(&vtop[-nb_args]))
1345 float_abi = ARM_SOFTFP_FLOAT;1352 float_abi = ARM_SOFTFP_FLOAT;
1346 }1353 }
1347#endif1354#endif
1348 /* cannot let cpu flags if other instruction are generated. Also avoid leaving1355 /* cannot let cpu flags if other instruction are generated. Also avoid leaving
1349 VT_JMP anywhere except on the top of the stack because it would complicate1356 VT_JMP anywhere except on the top of the stack because it would complicate
1350 the code generator. */1357 the code generator. */
1351 r = S->tccgen_vtop->r & VT_VALMASK;1358 r = vtop->r & VT_VALMASK;
1352 if (r == VT_CMP || (r & ~1) == VT_JMP)1359 if (r == VT_CMP || (r & ~1) == VT_JMP)
1353 gv(S, RC_INT);1360 gv(RC_INT);
1354 1361
1355 memset(&plan, 0, sizeof plan);1362 memset(&plan, 0, sizeof plan);
1356 if (nb_args)1363 if (nb_args)
1357 plan.pplans = tcc_malloc(S, nb_args * sizeof(*plan.pplans));1364 plan.pplans = tcc_malloc(nb_args * sizeof(*plan.pplans));
1358 1365
1359 args_size = assign_regs(S, nb_args, float_abi, &plan, &todo);1366 args_size = assign_regs(nb_args, float_abi, &plan, &todo);
1360 1367
1361#ifdef TCC_ARM_EABI1368#ifdef TCC_ARM_EABI
1362 if (args_size & 7) { /* Stack must be 8 byte aligned at fct call for EABI */1369 if (args_size & 7) { /* Stack must be 8 byte aligned at fct call for EABI */
1363 args_size = (args_size + 7) & ~7;1370 args_size = (args_size + 7) & ~7;
1364 o(S, 0xE24DD004); /* sub sp, sp, #4 */1371 o(0xE24DD004); /* sub sp, sp, #4 */
1365 }1372 }
1366#endif1373#endif
1367 1374
1368 nb_args += copy_params(S, nb_args, &plan, todo);1375 nb_args += copy_params(nb_args, &plan, todo);
1369 tcc_free(S, plan.pplans);1376 tcc_free(plan.pplans);
1370 1377
1371 /* Move fct SValue on top as required by gcall_or_jmp */1378 /* Move fct SValue on top as required by gcall_or_jmp */
1372 vrotb(S, nb_args + 1);1379 vrotb(nb_args + 1);
1373 gcall_or_jmp(S, 0);1380 gcall_or_jmp(0);
1374 if (args_size)1381 if (args_size)
1375 gadd_sp(S, args_size); /* pop all parameters passed on the stack */1382 gadd_sp(args_size); /* pop all parameters passed on the stack */
1376#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)1383#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
1377 if(float_abi == ARM_SOFTFP_FLOAT && is_float(S->tccgen_vtop->type.ref->type.t)) {1384 if(float_abi == ARM_SOFTFP_FLOAT && is_float(vtop->type.ref->type.t)) {
1378 if((S->tccgen_vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) {1385 if((vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) {
1379 o(S, 0xEE000A10); /*vmov s0, r0 */1386 o(0xEE000A10); /*vmov s0, r0 */
1380 } else {1387 } else {
1381 o(S, 0xEE000B10); /* vmov.32 d0[0], r0 */1388 o(0xEE000B10); /* vmov.32 d0[0], r0 */
1382 o(S, 0xEE201B10); /* vmov.32 d0[1], r1 */1389 o(0xEE201B10); /* vmov.32 d0[1], r1 */
1383 }1390 }
1384 }1391 }
1385#endif1392#endif
1386 S->tccgen_vtop -= nb_args + 1; /* Pop all params and fct address from value stack */1393 vtop -= nb_args + 1; /* Pop all params and fct address from value stack */
1387 leaffunc = 0; /* we are calling a function, so we aren't in a leaf function */1394 leaffunc = 0; /* we are calling a function, so we aren't in a leaf function */
1388 float_abi = def_float_abi;1395 float_abi = def_float_abi;
1389}1396}
1390 1397
1391/* generate function prolog of type 't' */1398/* generate function prolog of type 't' */
1392void gfunc_prolog(TCCState* S, Sym *func_sym)1399void gfunc_prolog(Sym *func_sym)
1393{1400{
1394 CType *func_type = &func_sym->type;1401 CType *func_type = &func_sym->type;
1395 Sym *sym,*sym2;1402 Sym *sym,*sym2;
@@ -1404,17 +1411,17 @@ void gfunc_prolog(TCCState* S, Sym *func_sym) · 8 unmodified lines
1404 sym = func_type->ref;1411 sym = func_type->ref;
1405 1412
1406 n = nf = 0;1413 n = nf = 0;
1407 if ((S->tccgen_func_vt.t & VT_BTYPE) == VT_STRUCT &&1414 if ((func_vt.t & VT_BTYPE) == VT_STRUCT &&
1408 !gfunc_sret(&S->tccgen_func_vt, S->tccgen_func_var, &ret_type, &align, &rs))1415 !gfunc_sret(&func_vt, func_var, &ret_type, &align, &rs))
1409 {1416 {
1410 n++;1417 n++;
1411 struct_ret = 1;1418 struct_ret = 1;
1412 S->tccgen_func_vc = 12; /* Offset from fp of the place to store the result */1419 func_vc = 12; /* Offset from fp of the place to store the result */
1413 }1420 }
1414 for(sym2 = sym->next; sym2 && (n < 4 || nf < 16); sym2 = sym2->next) {1421 for(sym2 = sym->next; sym2 && (n < 4 || nf < 16); sym2 = sym2->next) {
1415 size = type_size(&sym2->type, &align);1422 size = type_size(&sym2->type, &align);
1416#ifdef TCC_ARM_EABI1423#ifdef TCC_ARM_EABI
1417 if (float_abi == ARM_HARD_FLOAT && !S->tccgen_func_var &&1424 if (float_abi == ARM_HARD_FLOAT && !func_var &&
1418 (is_float(sym2->type.t) || is_hgen_float_aggr(&sym2->type))) {1425 (is_float(sym2->type.t) || is_hgen_float_aggr(&sym2->type))) {
1419 int tmpnf = assign_vfpreg(&avregs, align, size);1426 int tmpnf = assign_vfpreg(&avregs, align, size);
1420 tmpnf += (size + 3) / 4;1427 tmpnf += (size + 3) / 4;
@@ -1424,8 +1431,8 @@ void gfunc_prolog(TCCState* S, Sym *func_sym) · 3 unmodified lines
1424 if (n < 4)1431 if (n < 4)
1425 n += (size + 3) / 4;1432 n += (size + 3) / 4;
1426 }1433 }
1427 o(S, 0xE1A0C00D); /* mov ip,sp */1434 o(0xE1A0C00D); /* mov ip,sp */
1428 if (S->tccgen_func_var)1435 if (func_var)
1429 n=4;1436 n=4;
1430 if (n) {1437 if (n) {
1431 if(n>4)1438 if(n>4)
@@ -1433,22 +1440,22 @@ void gfunc_prolog(TCCState* S, Sym *func_sym) · 1 unmodified line
1433#ifdef TCC_ARM_EABI1440#ifdef TCC_ARM_EABI
1434 n=(n+1)&-2;1441 n=(n+1)&-2;
1435#endif1442#endif
1436 o(S, 0xE92D0000|((1<<n)-1)); /* save r0-r4 on stack if needed */1443 o(0xE92D0000|((1<<n)-1)); /* save r0-r4 on stack if needed */
1437 }1444 }
1438 if (nf) {1445 if (nf) {
1439 if (nf>16)1446 if (nf>16)
1440 nf=16;1447 nf=16;
1441 nf=(nf+1)&-2; /* nf => HARDFLOAT => EABI */1448 nf=(nf+1)&-2; /* nf => HARDFLOAT => EABI */
1442 o(S, 0xED2D0A00|nf); /* save s0-s15 on stack if needed */1449 o(0xED2D0A00|nf); /* save s0-s15 on stack if needed */
1443 }1450 }
1444 o(S, 0xE92D5800); /* save fp, ip, lr */1451 o(0xE92D5800); /* save fp, ip, lr */
1445 o(S, 0xE1A0B00D); /* mov fp, sp */1452 o(0xE1A0B00D); /* mov fp, sp */
1446 func_sub_sp_offset = S->tccgen_ind;1453 func_sub_sp_offset = ind;
1447 o(S, 0xE1A00000); /* nop, leave space for stack adjustment in epilog */1454 o(0xE1A00000); /* nop, leave space for stack adjustment in epilog */
1448 1455
1449#ifdef TCC_ARM_EABI1456#ifdef TCC_ARM_EABI
1450 if (float_abi == ARM_HARD_FLOAT) {1457 if (float_abi == ARM_HARD_FLOAT) {
1451 S->tccgen_func_vc += nf * 4;1458 func_vc += nf * 4;
1452 memset(&avregs, 0, sizeof avregs);1459 memset(&avregs, 0, sizeof avregs);
1453 }1460 }
1454#endif1461#endif
@@ -1460,7 +1467,7 @@ void gfunc_prolog(TCCState* S, Sym *func_sym) · 5 unmodified lines
1460 size = (size + 3) >> 2;1467 size = (size + 3) >> 2;
1461 align = (align + 3) & ~3;1468 align = (align + 3) & ~3;
1462#ifdef TCC_ARM_EABI1469#ifdef TCC_ARM_EABI
1463 if (float_abi == ARM_HARD_FLOAT && !S->tccgen_func_var && (is_float(sym->type.t)1470 if (float_abi == ARM_HARD_FLOAT && !func_var && (is_float(sym->type.t)
1464 || is_hgen_float_aggr(&sym->type))) {1471 || is_hgen_float_aggr(&sym->type))) {
1465 int fpn = assign_vfpreg(&avregs, align, size << 2);1472 int fpn = assign_vfpreg(&avregs, align, size << 2);
1466 if (fpn >= 0)1473 if (fpn >= 0)
@@ -1485,42 +1492,42 @@ from_stack: · 18 unmodified lines
1485 addr = (n + nf + sn) * 4;1492 addr = (n + nf + sn) * 4;
1486 sn += size;1493 sn += size;
1487 }1494 }
1488 sym_push(S, sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL,1495 sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL,
1489 addr + 12);1496 addr + 12);
1490 }1497 }
1491 last_itod_magic=0;1498 last_itod_magic=0;
1492 leaffunc = 1;1499 leaffunc = 1;
1493 S->tccgen_loc = 0;1500 loc = 0;
1494#ifdef CONFIG_TCC_BCHECK1501#ifdef CONFIG_TCC_BCHECK
1495 if (S->do_bounds_check)1502 if (tcc_state->do_bounds_check)
1496 gen_bounds_prolog(S);1503 gen_bounds_prolog();
1497#endif1504#endif
1498}1505}
1499 1506
1500/* generate function epilog */1507/* generate function epilog */
1501void gfunc_epilog(TCCState* S)1508void gfunc_epilog(void)
1502{1509{
1503 uint32_t x;1510 uint32_t x;
1504 int diff;1511 int diff;
1505 1512
1506#ifdef CONFIG_TCC_BCHECK1513#ifdef CONFIG_TCC_BCHECK
1507 if (S->do_bounds_check)1514 if (tcc_state->do_bounds_check)
1508 gen_bounds_epilog(S);1515 gen_bounds_epilog();
1509#endif1516#endif
1510 /* Copy float return value to core register if base standard is used and1517 /* Copy float return value to core register if base standard is used and
1511 float computation is made with VFP */1518 float computation is made with VFP */
1512#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)1519#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
1513 if ((float_abi == ARM_SOFTFP_FLOAT || S->tccgen_func_var) && is_float(S->tccgen_func_vt.t)) {1520 if ((float_abi == ARM_SOFTFP_FLOAT || func_var) && is_float(func_vt.t)) {
1514 if((S->tccgen_func_vt.t & VT_BTYPE) == VT_FLOAT)1521 if((func_vt.t & VT_BTYPE) == VT_FLOAT)
1515 o(S, 0xEE100A10); /* fmrs r0, s0 */1522 o(0xEE100A10); /* fmrs r0, s0 */
1516 else {1523 else {
1517 o(S, 0xEE100B10); /* fmrdl r0, d0 */1524 o(0xEE100B10); /* fmrdl r0, d0 */
1518 o(S, 0xEE301B10); /* fmrdh r1, d0 */1525 o(0xEE301B10); /* fmrdh r1, d0 */
1519 }1526 }
1520 }1527 }
1521#endif1528#endif
1522 o(S, 0xE89BA800); /* restore fp, sp, pc */1529 o(0xE89BA800); /* restore fp, sp, pc */
1523 diff = (-S->tccgen_loc + 3) & -4;1530 diff = (-loc + 3) & -4;
1524#ifdef TCC_ARM_EABI1531#ifdef TCC_ARM_EABI
1525 if(!leaffunc)1532 if(!leaffunc)
1526 diff = ((diff + 11) & -8) - 4;1533 diff = ((diff + 11) & -8) - 4;
@@ -1531,74 +1538,74 @@ void gfunc_epilog(TCCState* S) · 4 unmodified lines
1531 *(uint32_t *)(cur_text_section->data + func_sub_sp_offset) = x;1538 *(uint32_t *)(cur_text_section->data + func_sub_sp_offset) = x;
1532 else {1539 else {
1533 int addr;1540 int addr;
1534 addr=S->tccgen_ind;1541 addr=ind;
1535 o(S, 0xE59FC004); /* ldr ip,[pc+4] */1542 o(0xE59FC004); /* ldr ip,[pc+4] */
1536 o(S, 0xE04BD00C); /* sub sp,fp,ip */1543 o(0xE04BD00C); /* sub sp,fp,ip */
1537 o(S, 0xE1A0F00E); /* mov pc,lr */1544 o(0xE1A0F00E); /* mov pc,lr */
1538 o(S, diff);1545 o(diff);
1539 *(uint32_t *)(cur_text_section->data + func_sub_sp_offset) = 0xE1000000|encbranch(S, func_sub_sp_offset,addr,1);1546 *(uint32_t *)(cur_text_section->data + func_sub_sp_offset) = 0xE1000000|encbranch(func_sub_sp_offset,addr,1);
1540 }1547 }
1541 }1548 }
1542}1549}
1543 1550
1544ST_FUNC void gen_fill_nops(TCCState* S, int bytes)1551ST_FUNC void gen_fill_nops(int bytes)
1545{1552{
1546 if ((bytes & 3))1553 if ((bytes & 3))
1547 tcc_error(S, "alignment of code section not multiple of 4");1554 tcc_error("alignment of code section not multiple of 4");
1548 while (bytes > 0) {1555 while (bytes > 0) {
1549 o(S, 0xE1A00000);1556 o(0xE1A00000);
1550 bytes -= 4;1557 bytes -= 4;
1551 }1558 }
1552}1559}
1553 1560
1554/* generate a jump to a label */1561/* generate a jump to a label */
1555ST_FUNC int gjmp(TCCState* S, int t)1562ST_FUNC int gjmp(int t)
1556{1563{
1557 int r;1564 int r;
1558 if (S->tccgen_nocode_wanted)1565 if (nocode_wanted)
1559 return t;1566 return t;
1560 r=S->tccgen_ind;1567 r=ind;
1561 o(S, 0xE0000000|encbranch(S, r,t,1));1568 o(0xE0000000|encbranch(r,t,1));
1562 return r;1569 return r;
1563}1570}
1564 1571
1565/* generate a jump to a fixed address */1572/* generate a jump to a fixed address */
1566ST_FUNC void gjmp_addr(TCCState* S, int a)1573ST_FUNC void gjmp_addr(int a)
1567{1574{
1568 gjmp(S, a);1575 gjmp(a);
1569}1576}
1570 1577
1571ST_FUNC int gjmp_cond(TCCState* S, int op, int t)1578ST_FUNC int gjmp_cond(int op, int t)
1572{1579{
1573 int r;1580 int r;
1574 if (S->tccgen_nocode_wanted)1581 if (nocode_wanted)
1575 return t;1582 return t;
1576 r=S->tccgen_ind;1583 r=ind;
1577 op=mapcc(S, op);1584 op=mapcc(op);
1578 op|=encbranch(S, r,t,1);1585 op|=encbranch(r,t,1);
1579 o(S, op);1586 o(op);
1580 return r;1587 return r;
1581}1588}
1582 1589
1583ST_FUNC int gjmp_append(TCCState* S, int n, int t)1590ST_FUNC int gjmp_append(int n, int t)
1584{1591{
1585 uint32_t *x;1592 uint32_t *x;
1586 int p,lp;1593 int p,lp;
1587 if(n) {1594 if(n) {
1588 p = n;1595 p = n;
1589 do {1596 do {
1590 p = decbranch(S, lp=p);1597 p = decbranch(lp=p);
1591 } while(p);1598 } while(p);
1592 x = (uint32_t *)(cur_text_section->data + lp);1599 x = (uint32_t *)(cur_text_section->data + lp);
1593 *x &= 0xff000000;1600 *x &= 0xff000000;
1594 *x |= encbranch(S, lp,t,1);1601 *x |= encbranch(lp,t,1);
1595 t = n;1602 t = n;
1596 }1603 }
1597 return t;1604 return t;
1598}1605}
1599 1606
1600/* generate an integer binary operation */1607/* generate an integer binary operation */
1601void gen_opi(TCCState* S, int op)1608void gen_opi(int op)
1602{1609{
1603 int c, func = 0;1610 int c, func = 0;
1604 uint32_t opc = 0, r, fr;1611 uint32_t opc = 0, r, fr;
@@ -1643,11 +1650,11 @@ void gen_opi(TCCState* S, int op) · 38 unmodified lines
1643 c=1;1650 c=1;
1644 break;1651 break;
1645 case '*':1652 case '*':
1646 gv2(S, RC_INT, RC_INT);1653 gv2(RC_INT, RC_INT);
1647 r = S->tccgen_vtop[-1].r;1654 r = vtop[-1].r;
1648 fr = S->tccgen_vtop[0].r;1655 fr = vtop[0].r;
1649 S->tccgen_vtop--;1656 vtop--;
1650 o(S, 0xE0000090|(intr(S, r)<<16)|(intr(S, r)<<8)|intr(S, fr));1657 o(0xE0000090|(intr(r)<<16)|(intr(r)<<8)|intr(fr));
1651 return;1658 return;
1652 case TOK_SHL:1659 case TOK_SHL:
1653 opc = 0;1660 opc = 0;
@@ -1689,12 +1696,12 @@ void gen_opi(TCCState* S, int op) · 35 unmodified lines
1689 c=3;1696 c=3;
1690 break;1697 break;
1691 case TOK_UMULL:1698 case TOK_UMULL:
1692 gv2(S, RC_INT, RC_INT);1699 gv2(RC_INT, RC_INT);
1693 r=intr(S, S->tccgen_vtop[-1].r2=get_reg(S, RC_INT));1700 r=intr(vtop[-1].r2=get_reg(RC_INT));
1694 c=S->tccgen_vtop[-1].r;1701 c=vtop[-1].r;
1695 S->tccgen_vtop[-1].r=get_reg_ex(S, RC_INT,regmask(S, c));1702 vtop[-1].r=get_reg_ex(RC_INT,regmask(c));
1696 S->tccgen_vtop--;1703 vtop--;
1697 o(S, 0xE0800090|(r<<16)|(intr(S, S->tccgen_vtop->r)<<12)|(intr(S, c)<<8)|intr(S, S->tccgen_vtop[1].r));1704 o(0xE0800090|(r<<16)|(intr(vtop->r)<<12)|(intr(c)<<8)|intr(vtop[1].r));
1698 return;1705 return;
1699 default:1706 default:
1700 opc = 0x15;1707 opc = 0x15;
@@ -1703,128 +1710,128 @@ void gen_opi(TCCState* S, int op) · 2 unmodified lines
1703 }1710 }
1704 switch(c) {1711 switch(c) {
1705 case 1:1712 case 1:
1706 if((S->tccgen_vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {1713 if((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1707 if(opc == 4 || opc == 5 || opc == 0xc) {1714 if(opc == 4 || opc == 5 || opc == 0xc) {
1708 vswap(S);1715 vswap();
1709 opc|=2; // sub -> rsb1716 opc|=2; // sub -> rsb
1710 }1717 }
1711 }1718 }
1712 if ((S->tccgen_vtop->r & VT_VALMASK) == VT_CMP ||1719 if ((vtop->r & VT_VALMASK) == VT_CMP ||
1713 (S->tccgen_vtop->r & (VT_VALMASK & ~1)) == VT_JMP)1720 (vtop->r & (VT_VALMASK & ~1)) == VT_JMP)
1714 gv(S, RC_INT);1721 gv(RC_INT);
1715 vswap(S);1722 vswap();
1716 c=intr(S, gv(S, RC_INT));1723 c=intr(gv(RC_INT));
1717 vswap(S);1724 vswap();
1718 opc=0xE0000000|(opc<<20);1725 opc=0xE0000000|(opc<<20);
1719 if((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {1726 if((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1720 uint32_t x;1727 uint32_t x;
1721 x=stuff_const(opc|0x2000000|(c<<16),S->tccgen_vtop->c.i);1728 x=stuff_const(opc|0x2000000|(c<<16),vtop->c.i);
1722 if(x) {1729 if(x) {
1723 if ((x & 0xfff00000) == 0xe3500000) // cmp rx,#c1730 if ((x & 0xfff00000) == 0xe3500000) // cmp rx,#c
1724 o(S, x);1731 o(x);
1725 else {1732 else {
1726 r=intr(S, S->tccgen_vtop[-1].r=get_reg_ex(S, RC_INT,regmask(S, S->tccgen_vtop[-1].r)));1733 r=intr(vtop[-1].r=get_reg_ex(RC_INT,regmask(vtop[-1].r)));
1727 o(S, x|(r<<12));1734 o(x|(r<<12));
1728 }1735 }
1729 goto done;1736 goto done;
1730 }1737 }
1731 }1738 }
1732 fr=intr(S, gv(S, RC_INT));1739 fr=intr(gv(RC_INT));
1733#ifdef CONFIG_TCC_BCHECK1740#ifdef CONFIG_TCC_BCHECK
1734 if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {1741 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
1735 vswap(S);1742 vswap();
1736 c=intr(S, gv(S, RC_INT));1743 c=intr(gv(RC_INT));
1737 vswap(S);1744 vswap();
1738 }1745 }
1739#endif1746#endif
1740 if ((opc & 0xfff00000) == 0xe1500000) // cmp rx,ry1747 if ((opc & 0xfff00000) == 0xe1500000) // cmp rx,ry
1741 o(S, opc|(c<<16)|fr);1748 o(opc|(c<<16)|fr);
1742 else {1749 else {
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)));1750 r=intr(vtop[-1].r=get_reg_ex(RC_INT,two2mask(vtop->r,vtop[-1].r)));
1744 o(S, opc|(c<<16)|(r<<12)|fr);1751 o(opc|(c<<16)|(r<<12)|fr);
1745 }1752 }
1746done:1753done:
1747 S->tccgen_vtop--;1754 vtop--;
1748 if (op >= TOK_ULT && op <= TOK_GT)1755 if (op >= TOK_ULT && op <= TOK_GT)
1749 vset_VT_CMP(S, op);1756 vset_VT_CMP(op);
1750 break;1757 break;
1751 case 2:1758 case 2:
1752 opc=0xE1A00000|(opc<<5);1759 opc=0xE1A00000|(opc<<5);
1753 if ((S->tccgen_vtop->r & VT_VALMASK) == VT_CMP ||1760 if ((vtop->r & VT_VALMASK) == VT_CMP ||
1754 (S->tccgen_vtop->r & (VT_VALMASK & ~1)) == VT_JMP)1761 (vtop->r & (VT_VALMASK & ~1)) == VT_JMP)
1755 gv(S, RC_INT);1762 gv(RC_INT);
1756 vswap(S);1763 vswap();
1757 r=intr(S, gv(S, RC_INT));1764 r=intr(gv(RC_INT));
1758 vswap(S);1765 vswap();
1759 if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {1766 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1760 fr=intr(S, S->tccgen_vtop[-1].r=get_reg_ex(S, RC_INT,regmask(S, S->tccgen_vtop[-1].r)));1767 fr=intr(vtop[-1].r=get_reg_ex(RC_INT,regmask(vtop[-1].r)));
1761 c = S->tccgen_vtop->c.i & 0x1f;1768 c = vtop->c.i & 0x1f;
1762 o(S, opc|r|(c<<7)|(fr<<12));1769 o(opc|r|(c<<7)|(fr<<12));
1763 } else {1770 } else {
1764 fr=intr(S, gv(S, RC_INT));1771 fr=intr(gv(RC_INT));
1765#ifdef CONFIG_TCC_BCHECK1772#ifdef CONFIG_TCC_BCHECK
1766 if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {1773 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
1767 vswap(S);1774 vswap();
1768 r=intr(S, gv(S, RC_INT));1775 r=intr(gv(RC_INT));
1769 vswap(S);1776 vswap();
1770 }1777 }
1771#endif1778#endif
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)));1779 c=intr(vtop[-1].r=get_reg_ex(RC_INT,two2mask(vtop->r,vtop[-1].r)));
1773 o(S, opc|r|(c<<12)|(fr<<8)|0x10);1780 o(opc|r|(c<<12)|(fr<<8)|0x10);
1774 }1781 }
1775 S->tccgen_vtop--;1782 vtop--;
1776 break;1783 break;
1777 case 3:1784 case 3:
1778 vpush_helper_func(S, func);1785 vpush_helper_func(func);
1779 vrott(S, 3);1786 vrott(3);
1780 gfunc_call(S, 2);1787 gfunc_call(2);
1781 vpushi(S, 0);1788 vpushi(0);
1782 S->tccgen_vtop->r = retreg;1789 vtop->r = retreg;
1783 break;1790 break;
1784 default:1791 default:
1785 tcc_error(S, "gen_opi %i unimplemented!",op);1792 tcc_error("gen_opi %i unimplemented!",op);
1786 }1793 }
1787}1794}
1788 1795
1789#ifdef TCC_ARM_VFP1796#ifdef TCC_ARM_VFP
1790static int is_zero(TCCState* S, int i)1797static int is_zero(int i)
1791{1798{
1792 if((S->tccgen_vtop[i].r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)1799 if((vtop[i].r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1793 return 0;1800 return 0;
1794 if (S->tccgen_vtop[i].type.t == VT_FLOAT)1801 if (vtop[i].type.t == VT_FLOAT)
1795 return (S->tccgen_vtop[i].c.f == 0.f);1802 return (vtop[i].c.f == 0.f);
1796 else if (S->tccgen_vtop[i].type.t == VT_DOUBLE)1803 else if (vtop[i].type.t == VT_DOUBLE)
1797 return (S->tccgen_vtop[i].c.d == 0.0);1804 return (vtop[i].c.d == 0.0);
1798 return (S->tccgen_vtop[i].c.ld == 0.l);1805 return (vtop[i].c.ld == 0.l);
1799}1806}
1800 1807
1801/* generate a floating point operation 'v = t1 op t2' instruction. The1808/* generate a floating point operation 'v = t1 op t2' instruction. The
1802 * two operands are guaranteed to have the same floating point type */1809 * two operands are guaranteed to have the same floating point type */
1803void gen_opf(TCCState* S, int op)1810void gen_opf(int op)
1804{1811{
1805 uint32_t x;1812 uint32_t x;
1806 int fneg=0,r;1813 int fneg=0,r;
1807 x=0xEE000A00|T2CPR(S->tccgen_vtop->type.t);1814 x=0xEE000A00|T2CPR(vtop->type.t);
1808 switch(op) {1815 switch(op) {
1809 case '+':1816 case '+':
1810 if(is_zero(S, -1))1817 if(is_zero(-1))
1811 vswap(S);1818 vswap();
1812 if(is_zero(S, 0)) {1819 if(is_zero(0)) {
1813 S->tccgen_vtop--;1820 vtop--;
1814 return;1821 return;
1815 }1822 }
1816 x|=0x300000;1823 x|=0x300000;
1817 break;1824 break;
1818 case '-':1825 case '-':
1819 x|=0x300040;1826 x|=0x300040;
1820 if(is_zero(S, 0)) {1827 if(is_zero(0)) {
1821 S->tccgen_vtop--;1828 vtop--;
1822 return;1829 return;
1823 }1830 }
1824 if(is_zero(S, -1)) {1831 if(is_zero(-1)) {
1825 x|=0x810000; /* fsubX -> fnegX */1832 x|=0x810000; /* fsubX -> fnegX */
1826 vswap(S);1833 vswap();
1827 S->tccgen_vtop--;1834 vtop--;
1828 fneg=1;1835 fneg=1;
1829 }1836 }
1830 break;1837 break;
@@ -1836,11 +1843,11 @@ void gen_opf(TCCState* S, int op) · 5 unmodified lines
1836 break;1843 break;
1837 default:1844 default:
1838 if(op < TOK_ULT || op > TOK_GT) {1845 if(op < TOK_ULT || op > TOK_GT) {
1839 tcc_error(S, "unknown fp op %x!",op);1846 tcc_error("unknown fp op %x!",op);
1840 return;1847 return;
1841 }1848 }
1842 if(is_zero(S, -1)) {1849 if(is_zero(-1)) {
1843 vswap(S);1850 vswap();
1844 switch(op) {1851 switch(op) {
1845 case TOK_LT: op=TOK_GT; break;1852 case TOK_LT: op=TOK_GT; break;
1846 case TOK_GE: op=TOK_ULE; break;1853 case TOK_GE: op=TOK_ULE; break;
@@ -1851,16 +1858,16 @@ void gen_opf(TCCState* S, int op) · 4 unmodified lines
1851 x|=0xB40040; /* fcmpX */1858 x|=0xB40040; /* fcmpX */
1852 if(op!=TOK_EQ && op!=TOK_NE)1859 if(op!=TOK_EQ && op!=TOK_NE)
1853 x|=0x80; /* fcmpX -> fcmpeX */1860 x|=0x80; /* fcmpX -> fcmpeX */
1854 if(is_zero(S, 0)) {1861 if(is_zero(0)) {
1855 S->tccgen_vtop--;1862 vtop--;
1856 o(S, x|0x10000|(vfpr(S, gv(S, RC_FLOAT))<<12)); /* fcmp(e)X -> fcmp(e)zX */1863 o(x|0x10000|(vfpr(gv(RC_FLOAT))<<12)); /* fcmp(e)X -> fcmp(e)zX */
1857 } else {1864 } else {
1858 gv2(S, RC_FLOAT,RC_FLOAT);1865 gv2(RC_FLOAT,RC_FLOAT);
1859 x|=vfpr(S, S->tccgen_vtop[0].r);1866 x|=vfpr(vtop[0].r);
1860 o(S, x|(vfpr(S, S->tccgen_vtop[-1].r) << 12));1867 o(x|(vfpr(vtop[-1].r) << 12));
1861 S->tccgen_vtop--;1868 vtop--;
1862 }1869 }
1863 o(S, 0xEEF1FA10); /* fmstat */1870 o(0xEEF1FA10); /* fmstat */
1864 1871
1865 switch(op) {1872 switch(op) {
1866 case TOK_LE: op=TOK_ULE; break;1873 case TOK_LE: op=TOK_ULE; break;
@@ -1868,46 +1875,46 @@ void gen_opf(TCCState* S, int op) · 1 unmodified line
1868 case TOK_UGE: op=TOK_GE; break;1875 case TOK_UGE: op=TOK_GE; break;
1869 case TOK_UGT: op=TOK_GT; break;1876 case TOK_UGT: op=TOK_GT; break;
1870 }1877 }
1871 vset_VT_CMP(S, op);1878 vset_VT_CMP(op);
1872 return;1879 return;
1873 }1880 }
1874 r=gv(S, RC_FLOAT);1881 r=gv(RC_FLOAT);
1875 x|=vfpr(S, r);1882 x|=vfpr(r);
1876 r=regmask(S, r);1883 r=regmask(r);
1877 if(!fneg) {1884 if(!fneg) {
1878 int r2;1885 int r2;
1879 vswap(S);1886 vswap();
1880 r2=gv(S, RC_FLOAT);1887 r2=gv(RC_FLOAT);
1881 x|=vfpr(S, r2)<<16;1888 x|=vfpr(r2)<<16;
1882 r|=regmask(S, r2);1889 r|=regmask(r2);
1883#ifdef CONFIG_TCC_BCHECK1890#ifdef CONFIG_TCC_BCHECK
1884 if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {1891 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
1885 vswap(S);1892 vswap();
1886 r=gv(S, RC_FLOAT);1893 r=gv(RC_FLOAT);
1887 vswap(S);1894 vswap();
1888 x=(x&~0xf)|vfpr(S, r);1895 x=(x&~0xf)|vfpr(r);
1889 }1896 }
1890#endif1897#endif
1891 }1898 }
1892 S->tccgen_vtop->r=get_reg_ex(S, RC_FLOAT,r);1899 vtop->r=get_reg_ex(RC_FLOAT,r);
1893 if(!fneg)1900 if(!fneg)
1894 S->tccgen_vtop--;1901 vtop--;
1895 o(S, x|(vfpr(S, S->tccgen_vtop->r)<<12));1902 o(x|(vfpr(vtop->r)<<12));
1896}1903}
1897 1904
1898#else1905#else
1899static uint32_t is_fconst(TCCState* S)1906static uint32_t is_fconst()
1900{1907{
1901 long double f;1908 long double f;
1902 uint32_t r;1909 uint32_t r;
1903 if((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)1910 if((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
1904 return 0;1911 return 0;
1905 if (S->tccgen_vtop->type.t == VT_FLOAT)1912 if (vtop->type.t == VT_FLOAT)
1906 f = S->tccgen_vtop->c.f;1913 f = vtop->c.f;
1907 else if (S->tccgen_vtop->type.t == VT_DOUBLE)1914 else if (vtop->type.t == VT_DOUBLE)
1908 f = S->tccgen_vtop->c.d;1915 f = vtop->c.d;
1909 else1916 else
1910 f = S->tccgen_vtop->c.ld;1917 f = vtop->c.ld;
1911 if(!ieee_finite(f))1918 if(!ieee_finite(f))
1912 return 0;1919 return 0;
1913 r=0x8;1920 r=0x8;
@@ -1936,45 +1943,45 @@ static uint32_t is_fconst(TCCState* S) · 22 unmodified lines
1936 1943
1937/* generate a floating point operation 'v = t1 op t2' instruction. The1944/* generate a floating point operation 'v = t1 op t2' instruction. The
1938 two operands are guaranteed to have the same floating point type */1945 two operands are guaranteed to have the same floating point type */
1939void gen_opf(TCCState* S, int op)1946void gen_opf(int op)
1940{1947{
1941 uint32_t x, r, r2, c1, c2;1948 uint32_t x, r, r2, c1, c2;
1942 //fputs("gen_opf\n",stderr);1949 //fputs("gen_opf\n",stderr);
1943 vswap(S);1950 vswap();
1944 c1 = is_fconst(S);1951 c1 = is_fconst();
1945 vswap(S);1952 vswap();
1946 c2 = is_fconst(S);1953 c2 = is_fconst();
1947 x=0xEE000100;1954 x=0xEE000100;
1948#if LDOUBLE_SIZE == 81955#if LDOUBLE_SIZE == 8
1949 if ((S->tccgen_vtop->type.t & VT_BTYPE) != VT_FLOAT)1956 if ((vtop->type.t & VT_BTYPE) != VT_FLOAT)
1950 x|=0x80;1957 x|=0x80;
1951#else1958#else
1952 if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_DOUBLE)1959 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
1953 x|=0x80;1960 x|=0x80;
1954 else if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LDOUBLE)1961 else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE)
1955 x|=0x80000;1962 x|=0x80000;
1956#endif1963#endif
1957 switch(op)1964 switch(op)
1958 {1965 {
1959 case '+':1966 case '+':
1960 if(!c2) {1967 if(!c2) {
1961 vswap(S);1968 vswap();
1962 c2=c1;1969 c2=c1;
1963 }1970 }
1964 vswap(S);1971 vswap();
1965 r=fpr(S, gv(S, RC_FLOAT));1972 r=fpr(gv(RC_FLOAT));
1966 vswap(S);1973 vswap();
1967 if(c2) {1974 if(c2) {
1968 if(c2>0xf)1975 if(c2>0xf)
1969 x|=0x200000; // suf1976 x|=0x200000; // suf
1970 r2=c2&0xf;1977 r2=c2&0xf;
1971 } else {1978 } else {
1972 r2=fpr(S, gv(S, RC_FLOAT));1979 r2=fpr(gv(RC_FLOAT));
1973#ifdef CONFIG_TCC_BCHECK1980#ifdef CONFIG_TCC_BCHECK
1974 if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {1981 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
1975 vswap(S);1982 vswap();
1976 r=fpr(S, gv(S, RC_FLOAT));1983 r=fpr(gv(RC_FLOAT));
1977 vswap(S);1984 vswap();
1978 }1985 }
1979#endif1986#endif
1980 }1987 }
@@ -1984,46 +1991,46 @@ void gen_opf(TCCState* S, int op) · 3 unmodified lines
1984 if(c2<=0xf)1991 if(c2<=0xf)
1985 x|=0x200000; // suf1992 x|=0x200000; // suf
1986 r2=c2&0xf;1993 r2=c2&0xf;
1987 vswap(S);1994 vswap();
1988 r=fpr(S, gv(S, RC_FLOAT));1995 r=fpr(gv(RC_FLOAT));
1989 vswap(S);1996 vswap();
1990 } else if(c1 && c1<=0xf) {1997 } else if(c1 && c1<=0xf) {
1991 x|=0x300000; // rsf1998 x|=0x300000; // rsf
1992 r2=c1;1999 r2=c1;
1993 r=fpr(S, gv(S, RC_FLOAT));2000 r=fpr(gv(RC_FLOAT));
1994 vswap(S);2001 vswap();
1995 } else {2002 } else {
1996 x|=0x200000; // suf2003 x|=0x200000; // suf
1997 vswap(S);2004 vswap();
1998 r=fpr(S, gv(S, RC_FLOAT));2005 r=fpr(gv(RC_FLOAT));
1999 vswap(S);2006 vswap();
2000 r2=fpr(S, gv(S, RC_FLOAT));2007 r2=fpr(gv(RC_FLOAT));
2001#ifdef CONFIG_TCC_BCHECK2008#ifdef CONFIG_TCC_BCHECK
2002 if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {2009 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
2003 vswap(S);2010 vswap();
2004 r=fpr(S, gv(S, RC_FLOAT));2011 r=fpr(gv(RC_FLOAT));
2005 vswap(S);2012 vswap();
2006 }2013 }
2007#endif2014#endif
2008 }2015 }
2009 break;2016 break;
2010 case '*':2017 case '*':
2011 if(!c2 || c2>0xf) {2018 if(!c2 || c2>0xf) {
2012 vswap(S);2019 vswap();
2013 c2=c1;2020 c2=c1;
2014 }2021 }
2015 vswap(S);2022 vswap();
2016 r=fpr(S, gv(S, RC_FLOAT));2023 r=fpr(gv(RC_FLOAT));
2017 vswap(S);2024 vswap();
2018 if(c2 && c2<=0xf)2025 if(c2 && c2<=0xf)
2019 r2=c2;2026 r2=c2;
2020 else {2027 else {
2021 r2=fpr(S, gv(S, RC_FLOAT));2028 r2=fpr(gv(RC_FLOAT));
2022#ifdef CONFIG_TCC_BCHECK2029#ifdef CONFIG_TCC_BCHECK
2023 if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {2030 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
2024 vswap(S);2031 vswap();
2025 r=fpr(S, gv(S, RC_FLOAT));2032 r=fpr(gv(RC_FLOAT));
2026 vswap(S);2033 vswap();
2027 }2034 }
2028#endif2035#endif
2029 }2036 }
@@ -2033,25 +2040,25 @@ void gen_opf(TCCState* S, int op) · 3 unmodified lines
2033 if(c2 && c2<=0xf) {2040 if(c2 && c2<=0xf) {
2034 x|=0x400000; // dvf2041 x|=0x400000; // dvf
2035 r2=c2;2042 r2=c2;
2036 vswap(S);2043 vswap();
2037 r=fpr(S, gv(S, RC_FLOAT));2044 r=fpr(gv(RC_FLOAT));
2038 vswap(S);2045 vswap();
2039 } else if(c1 && c1<=0xf) {2046 } else if(c1 && c1<=0xf) {
2040 x|=0x500000; // rdf2047 x|=0x500000; // rdf
2041 r2=c1;2048 r2=c1;
2042 r=fpr(S, gv(S, RC_FLOAT));2049 r=fpr(gv(RC_FLOAT));
2043 vswap(S);2050 vswap();
2044 } else {2051 } else {
2045 x|=0x400000; // dvf2052 x|=0x400000; // dvf
2046 vswap(S);2053 vswap();
2047 r=fpr(S, gv(S, RC_FLOAT));2054 r=fpr(gv(RC_FLOAT));
2048 vswap(S);2055 vswap();
2049 r2=fpr(S, gv(S, RC_FLOAT));2056 r2=fpr(gv(RC_FLOAT));
2050#ifdef CONFIG_TCC_BCHECK2057#ifdef CONFIG_TCC_BCHECK
2051 if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {2058 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
2052 vswap(S);2059 vswap();
2053 r=fpr(S, gv(S, RC_FLOAT));2060 r=fpr(gv(RC_FLOAT));
2054 vswap(S);2061 vswap();
2055 }2062 }
2056#endif2063#endif
2057 }2064 }
@@ -2066,7 +2073,7 @@ void gen_opf(TCCState* S, int op) · 8 unmodified lines
2066 case TOK_UGE:2073 case TOK_UGE:
2067 case TOK_ULE:2074 case TOK_ULE:
2068 case TOK_UGT:2075 case TOK_UGT:
2069 tcc_error(S, "unsigned comparison on floats?");2076 tcc_error("unsigned comparison on floats?");
2070 break;2077 break;
2071 case TOK_LT:2078 case TOK_LT:
2072 op=TOK_Nset;2079 op=TOK_Nset;
@@ -2081,7 +2088,7 @@ void gen_opf(TCCState* S, int op) · 8 unmodified lines
2081 }2088 }
2082 if(c1 && !c2) {2089 if(c1 && !c2) {
2083 c2=c1;2090 c2=c1;
2084 vswap(S);2091 vswap();
2085 switch(op) {2092 switch(op) {
2086 case TOK_Nset:2093 case TOK_Nset:
2087 op=TOK_GT;2094 op=TOK_GT;
@@ -2097,86 +2104,86 @@ void gen_opf(TCCState* S, int op) · 9 unmodified lines
2097 break;2104 break;
2098 }2105 }
2099 }2106 }
2100 vswap(S);2107 vswap();
2101 r=fpr(S, gv(S, RC_FLOAT));2108 r=fpr(gv(RC_FLOAT));
2102 vswap(S);2109 vswap();
2103 if(c2) {2110 if(c2) {
2104 if(c2>0xf)2111 if(c2>0xf)
2105 x|=0x200000;2112 x|=0x200000;
2106 r2=c2&0xf;2113 r2=c2&0xf;
2107 } else {2114 } else {
2108 r2=fpr(S, gv(S, RC_FLOAT));2115 r2=fpr(gv(RC_FLOAT));
2109#ifdef CONFIG_TCC_BCHECK2116#ifdef CONFIG_TCC_BCHECK
2110 if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {2117 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
2111 vswap(S);2118 vswap();
2112 r=fpr(S, gv(S, RC_FLOAT));2119 r=fpr(gv(RC_FLOAT));
2113 vswap(S);2120 vswap();
2114 }2121 }
2115#endif2122#endif
2116 }2123 }
2117 --S->tccgen_vtop;2124 --vtop;
2118 vset_VT_CMP(S, op);2125 vset_VT_CMP(op);
2119 ++S->tccgen_vtop;2126 ++vtop;
2120 } else {2127 } else {
2121 tcc_error(S, "unknown fp op %x!",op);2128 tcc_error("unknown fp op %x!",op);
2122 return;2129 return;
2123 }2130 }
2124 }2131 }
2125 if(S->tccgen_vtop[-1].r == VT_CMP)2132 if(vtop[-1].r == VT_CMP)
2126 c1=15;2133 c1=15;
2127 else {2134 else {
2128 c1=S->tccgen_vtop->r;2135 c1=vtop->r;
2129 if(r2&0x8)2136 if(r2&0x8)
2130 c1=S->tccgen_vtop[-1].r;2137 c1=vtop[-1].r;
2131 S->tccgen_vtop[-1].r=get_reg_ex(S, RC_FLOAT,two2mask(S, S->tccgen_vtop[-1].r,c1));2138 vtop[-1].r=get_reg_ex(RC_FLOAT,two2mask(vtop[-1].r,c1));
2132 c1=fpr(S, S->tccgen_vtop[-1].r);2139 c1=fpr(vtop[-1].r);
2133 }2140 }
2134 S->tccgen_vtop--;2141 vtop--;
2135 o(S, x|(r<<16)|(c1<<12)|r2);2142 o(x|(r<<16)|(c1<<12)|r2);
2136}2143}
2137#endif2144#endif
2138 2145
2139/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'2146/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
2140 and 'long long' cases. */2147 and 'long long' cases. */
2141ST_FUNC void gen_cvt_itof(TCCState* S, int t)2148ST_FUNC void gen_cvt_itof(int t)
2142{2149{
2143 uint32_t r, r2;2150 uint32_t r, r2;
2144 int bt;2151 int bt;
2145 bt=S->tccgen_vtop->type.t & VT_BTYPE;2152 bt=vtop->type.t & VT_BTYPE;
2146 if(bt == VT_INT || bt == VT_SHORT || bt == VT_BYTE) {2153 if(bt == VT_INT || bt == VT_SHORT || bt == VT_BYTE) {
2147#ifndef TCC_ARM_VFP2154#ifndef TCC_ARM_VFP
2148 uint32_t dsize = 0;2155 uint32_t dsize = 0;
2149#endif2156#endif
2150 r=intr(S, gv(S, RC_INT));2157 r=intr(gv(RC_INT));
2151#ifdef TCC_ARM_VFP2158#ifdef TCC_ARM_VFP
2152 r2=vfpr(S, S->tccgen_vtop->r=get_reg(S, RC_FLOAT));2159 r2=vfpr(vtop->r=get_reg(RC_FLOAT));
2153 o(S, 0xEE000A10|(r<<12)|(r2<<16)); /* fmsr */2160 o(0xEE000A10|(r<<12)|(r2<<16)); /* fmsr */
2154 r2|=r2<<12;2161 r2|=r2<<12;
2155 if(!(S->tccgen_vtop->type.t & VT_UNSIGNED))2162 if(!(vtop->type.t & VT_UNSIGNED))
2156 r2|=0x80; /* fuitoX -> fsituX */2163 r2|=0x80; /* fuitoX -> fsituX */
2157 o(S, 0xEEB80A40|r2|T2CPR(t)); /* fYitoX*/2164 o(0xEEB80A40|r2|T2CPR(t)); /* fYitoX*/
2158#else2165#else
2159 r2=fpr(S, S->tccgen_vtop->r=get_reg(S, RC_FLOAT));2166 r2=fpr(vtop->r=get_reg(RC_FLOAT));
2160 if((t & VT_BTYPE) != VT_FLOAT)2167 if((t & VT_BTYPE) != VT_FLOAT)
2161 dsize=0x80; /* flts -> fltd */2168 dsize=0x80; /* flts -> fltd */
2162 o(S, 0xEE000110|dsize|(r2<<16)|(r<<12)); /* flts */2169 o(0xEE000110|dsize|(r2<<16)|(r<<12)); /* flts */
2163 if((S->tccgen_vtop->type.t & (VT_UNSIGNED|VT_BTYPE)) == (VT_UNSIGNED|VT_INT)) {2170 if((vtop->type.t & (VT_UNSIGNED|VT_BTYPE)) == (VT_UNSIGNED|VT_INT)) {
2164 uint32_t off = 0;2171 uint32_t off = 0;
2165 o(S, 0xE3500000|(r<<12)); /* cmp */2172 o(0xE3500000|(r<<12)); /* cmp */
2166 r=fpr(S, get_reg(S, RC_FLOAT));2173 r=fpr(get_reg(RC_FLOAT));
2167 if(last_itod_magic) {2174 if(last_itod_magic) {
2168 off=S->tccgen_ind+8-last_itod_magic;2175 off=ind+8-last_itod_magic;
2169 off/=4;2176 off/=4;
2170 if(off>255)2177 if(off>255)
2171 off=0;2178 off=0;
2172 }2179 }
2173 o(S, 0xBD1F0100|(r<<12)|off); /* ldflts */2180 o(0xBD1F0100|(r<<12)|off); /* ldflts */
2174 if(!off) {2181 if(!off) {
2175 o(S, 0xEA000000); /* b */2182 o(0xEA000000); /* b */
2176 last_itod_magic=S->tccgen_ind;2183 last_itod_magic=ind;
2177 o(S, 0x4F800000); /* 4294967296.0f */2184 o(0x4F800000); /* 4294967296.0f */
2178 }2185 }
2179 o(S, 0xBE000100|dsize|(r2<<16)|(r2<<12)|r); /* adflt */2186 o(0xBE000100|dsize|(r2<<16)|(r2<<12)|r); /* adflt */
2180 }2187 }
2181#endif2188#endif
2182 return;2189 return;
@@ -2184,15 +2191,15 @@ ST_FUNC void gen_cvt_itof(TCCState* S, int t) · 1 unmodified line
2184 int func;2191 int func;
2185 CType *func_type = 0;2192 CType *func_type = 0;
2186 if((t & VT_BTYPE) == VT_FLOAT) {2193 if((t & VT_BTYPE) == VT_FLOAT) {
2187 func_type = &S->armgen_func_float_type;2194 func_type = &func_float_type;
2188 if(S->tccgen_vtop->type.t & VT_UNSIGNED)2195 if(vtop->type.t & VT_UNSIGNED)
2189 func=TOK___floatundisf;2196 func=TOK___floatundisf;
2190 else2197 else
2191 func=TOK___floatdisf;2198 func=TOK___floatdisf;
2192#if LDOUBLE_SIZE != 82199#if LDOUBLE_SIZE != 8
2193 } else if((t & VT_BTYPE) == VT_LDOUBLE) {2200 } else if((t & VT_BTYPE) == VT_LDOUBLE) {
2194 func_type = &S->armgen_func_ldouble_type;2201 func_type = &func_ldouble_type;
2195 if(S->tccgen_vtop->type.t & VT_UNSIGNED)2202 if(vtop->type.t & VT_UNSIGNED)
2196 func=TOK___floatundixf;2203 func=TOK___floatundixf;
2197 else2204 else
2198 func=TOK___floatdixf;2205 func=TOK___floatdixf;
@@ -2200,39 +2207,39 @@ ST_FUNC void gen_cvt_itof(TCCState* S, int t) · 1 unmodified line
2200#else2207#else
2201 } else if((t & VT_BTYPE) == VT_DOUBLE || (t & VT_BTYPE) == VT_LDOUBLE) {2208 } else if((t & VT_BTYPE) == VT_DOUBLE || (t & VT_BTYPE) == VT_LDOUBLE) {
2202#endif2209#endif
2203 func_type = &S->armgen_func_double_type;2210 func_type = &func_double_type;
2204 if(S->tccgen_vtop->type.t & VT_UNSIGNED)2211 if(vtop->type.t & VT_UNSIGNED)
2205 func=TOK___floatundidf;2212 func=TOK___floatundidf;
2206 else2213 else
2207 func=TOK___floatdidf;2214 func=TOK___floatdidf;
2208 }2215 }
2209 if(func_type) {2216 if(func_type) {
2210 vpushsym(S, func_type, external_helper_sym(S, func));2217 vpushsym(func_type, external_helper_sym(func));
2211 vswap(S);2218 vswap();
2212 gfunc_call(S, 1);2219 gfunc_call(1);
2213 vpushi(S, 0);2220 vpushi(0);
2214 S->tccgen_vtop->r=TREG_F0;2221 vtop->r=TREG_F0;
2215 return;2222 return;
2216 }2223 }
2217 }2224 }
2218 tcc_error(S, "unimplemented gen_cvt_itof %x!",S->tccgen_vtop->type.t);2225 tcc_error("unimplemented gen_cvt_itof %x!",vtop->type.t);
2219}2226}
2220 2227
2221/* convert fp to int 't' type */2228/* convert fp to int 't' type */
2222void gen_cvt_ftoi(TCCState* S, int t)2229void gen_cvt_ftoi(int t)
2223{2230{
2224 uint32_t r, r2;2231 uint32_t r, r2;
2225 int u, func = 0;2232 int u, func = 0;
2226 u=t&VT_UNSIGNED;2233 u=t&VT_UNSIGNED;
2227 t&=VT_BTYPE;2234 t&=VT_BTYPE;
2228 r2=S->tccgen_vtop->type.t & VT_BTYPE;2235 r2=vtop->type.t & VT_BTYPE;
2229 if(t==VT_INT) {2236 if(t==VT_INT) {
2230#ifdef TCC_ARM_VFP2237#ifdef TCC_ARM_VFP
2231 r=vfpr(S, gv(S, RC_FLOAT));2238 r=vfpr(gv(RC_FLOAT));
2232 u=u?0:0x10000;2239 u=u?0:0x10000;
2233 o(S, 0xEEBC0AC0|(r<<12)|r|T2CPR(r2)|u); /* ftoXizY */2240 o(0xEEBC0AC0|(r<<12)|r|T2CPR(r2)|u); /* ftoXizY */
2234 r2=intr(S, S->tccgen_vtop->r=get_reg(S, RC_INT));2241 r2=intr(vtop->r=get_reg(RC_INT));
2235 o(S, 0xEE100A10|(r<<16)|(r2<<12));2242 o(0xEE100A10|(r<<16)|(r2<<12));
2236 return;2243 return;
2237#else2244#else
2238 if(u) {2245 if(u) {
@@ -2247,9 +2254,9 @@ void gen_cvt_ftoi(TCCState* S, int t) · 8 unmodified lines
2247#endif2254#endif
2248 func=TOK___fixunsdfsi;2255 func=TOK___fixunsdfsi;
2249 } else {2256 } else {
2250 r=fpr(S, gv(S, RC_FLOAT));2257 r=fpr(gv(RC_FLOAT));
2251 r2=intr(S, S->tccgen_vtop->r=get_reg(S, RC_INT));2258 r2=intr(vtop->r=get_reg(RC_INT));
2252 o(S, 0xEE100170|(r2<<12)|r);2259 o(0xEE100170|(r2<<12)|r);
2253 return;2260 return;
2254 }2261 }
2255#endif2262#endif
@@ -2266,93 +2273,93 @@ void gen_cvt_ftoi(TCCState* S, int t) · 10 unmodified lines
2266 func=TOK___fixdfdi;2273 func=TOK___fixdfdi;
2267 }2274 }
2268 if(func) {2275 if(func) {
2269 vpush_helper_func(S, func);2276 vpush_helper_func(func);
2270 vswap(S);2277 vswap();
2271 gfunc_call(S, 1);2278 gfunc_call(1);
2272 vpushi(S, 0);2279 vpushi(0);
2273 if(t == VT_LLONG)2280 if(t == VT_LLONG)
2274 S->tccgen_vtop->r2 = REG_IRE2;2281 vtop->r2 = REG_IRE2;
2275 S->tccgen_vtop->r = REG_IRET;2282 vtop->r = REG_IRET;
2276 return;2283 return;
2277 }2284 }
2278 tcc_error(S, "unimplemented gen_cvt_ftoi!");2285 tcc_error("unimplemented gen_cvt_ftoi!");
2279}2286}
2280 2287
2281/* convert from one floating point type to another */2288/* convert from one floating point type to another */
2282void gen_cvt_ftof(TCCState* S, int t)2289void gen_cvt_ftof(int t)
2283{2290{
2284#ifdef TCC_ARM_VFP2291#ifdef TCC_ARM_VFP
2285 if(((S->tccgen_vtop->type.t & VT_BTYPE) == VT_FLOAT) != ((t & VT_BTYPE) == VT_FLOAT)) {2292 if(((vtop->type.t & VT_BTYPE) == VT_FLOAT) != ((t & VT_BTYPE) == VT_FLOAT)) {
2286 uint32_t r = vfpr(S, gv(S, RC_FLOAT));2293 uint32_t r = vfpr(gv(RC_FLOAT));
2287 o(S, 0xEEB70AC0|(r<<12)|r|T2CPR(S->tccgen_vtop->type.t));2294 o(0xEEB70AC0|(r<<12)|r|T2CPR(vtop->type.t));
2288 }2295 }
2289#else2296#else
2290 /* all we have to do on i386 and FPA ARM is to put the float in a register */2297 /* all we have to do on i386 and FPA ARM is to put the float in a register */
2291 gv(S, RC_FLOAT);2298 gv(RC_FLOAT);
2292#endif2299#endif
2293}2300}
2294 2301
2295/* increment tcov counter */2302/* increment tcov counter */
2296ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv)2303ST_FUNC void gen_increment_tcov (SValue *sv)
2297{2304{
2298 int r1, r2;2305 int r1, r2;
2299 2306
2300 vpushv(S, sv);2307 vpushv(sv);
2301 S->tccgen_vtop->r = r1 = get_reg(S, RC_INT);2308 vtop->r = r1 = get_reg(RC_INT);
2302 r2 = get_reg(S, RC_INT);2309 r2 = get_reg(RC_INT);
2303 o(S, 0xE59F0000 | (intr(S, r1)<<12)); // ldr r1,[pc]2310 o(0xE59F0000 | (intr(r1)<<12)); // ldr r1,[pc]
2304 o(S, 0xEA000000); // b $+42311 o(0xEA000000); // b $+4
2305 greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_ARM_REL32);2312 greloc(cur_text_section, sv->sym, ind, R_ARM_REL32);
2306 o(S, -12);2313 o(-12);
2307 o(S, 0xe080000f | (intr(S, r1)<<16) | (intr(S, r1)<<12)); // add r1,r1,pc2314 o(0xe080000f | (intr(r1)<<16) | (intr(r1)<<12)); // add r1,r1,pc
2308 o(S, 0xe5900000 | (intr(S, r1)<<16) | (intr(S, r2)<<12)); // ldr r2, [r1]2315 o(0xe5900000 | (intr(r1)<<16) | (intr(r2)<<12)); // ldr r2, [r1]
2309 o(S, 0xe2900001 | (intr(S, r2)<<16) | (intr(S, r2)<<12)); // adds r2, r2, #12316 o(0xe2900001 | (intr(r2)<<16) | (intr(r2)<<12)); // adds r2, r2, #1
2310 o(S, 0xe5800000 | (intr(S, r1)<<16) | (intr(S, r2)<<12)); // str r2, [r1]2317 o(0xe5800000 | (intr(r1)<<16) | (intr(r2)<<12)); // str r2, [r1]
2311 o(S, 0xe2800004 | (intr(S, r1)<<16) | (intr(S, r1)<<12)); // add r1, r1, #42318 o(0xe2800004 | (intr(r1)<<16) | (intr(r1)<<12)); // add r1, r1, #4
2312 o(S, 0xe5900000 | (intr(S, r1)<<16) | (intr(S, r2)<<12)); // ldr r2, [r1]2319 o(0xe5900000 | (intr(r1)<<16) | (intr(r2)<<12)); // ldr r2, [r1]
2313 o(S, 0xe2a00000 | (intr(S, r2)<<16) | (intr(S, r2)<<12)); // adc r2, r2, #02320 o(0xe2a00000 | (intr(r2)<<16) | (intr(r2)<<12)); // adc r2, r2, #0
2314 o(S, 0xe5800000 | (intr(S, r1)<<16) | (intr(S, r2)<<12)); // str r2, [r1]2321 o(0xe5800000 | (intr(r1)<<16) | (intr(r2)<<12)); // str r2, [r1]
2315 vpop(S);2322 vpop();
2316}2323}
2317 2324
2318/* computed goto support */2325/* computed goto support */
2319void ggoto(TCCState* S)2326void ggoto(void)
2320{2327{
2321 gcall_or_jmp(S, 1);2328 gcall_or_jmp(1);
2322 S->tccgen_vtop--;2329 vtop--;
2323}2330}
2324 2331
2325/* Save the stack pointer onto the stack and return the location of its address */2332/* Save the stack pointer onto the stack and return the location of its address */
2326ST_FUNC void gen_vla_sp_save(TCCState* S, int addr) {2333ST_FUNC void gen_vla_sp_save(int addr) {
2327 SValue v;2334 SValue v;
2328 v.type.t = VT_PTR;2335 v.type.t = VT_PTR;
2329 v.r = VT_LOCAL | VT_LVAL;2336 v.r = VT_LOCAL | VT_LVAL;
2330 v.c.i = addr;2337 v.c.i = addr;
2331 store(S, TREG_SP, &v);2338 store(TREG_SP, &v);
2332}2339}
2333 2340
2334/* Restore the SP from a location on the stack */2341/* Restore the SP from a location on the stack */
2335ST_FUNC void gen_vla_sp_restore(TCCState* S, int addr) {2342ST_FUNC void gen_vla_sp_restore(int addr) {
2336 SValue v;2343 SValue v;
2337 v.type.t = VT_PTR;2344 v.type.t = VT_PTR;
2338 v.r = VT_LOCAL | VT_LVAL;2345 v.r = VT_LOCAL | VT_LVAL;
2339 v.c.i = addr;2346 v.c.i = addr;
2340 load(S, TREG_SP, &v);2347 load(TREG_SP, &v);
2341}2348}
2342 2349
2343/* Subtract from the stack pointer, and push the resulting value onto the stack */2350/* Subtract from the stack pointer, and push the resulting value onto the stack */
2344ST_FUNC void gen_vla_alloc(TCCState* S, CType *type, int align) {2351ST_FUNC void gen_vla_alloc(CType *type, int align) {
2345 int r;2352 int r;
2346#if defined(CONFIG_TCC_BCHECK)2353#if defined(CONFIG_TCC_BCHECK)
2347 if (S->do_bounds_check)2354 if (tcc_state->do_bounds_check)
2348 vpushv(S, S->tccgen_vtop);2355 vpushv(vtop);
2349#endif2356#endif
2350 r = intr(S, gv(S, RC_INT));2357 r = intr(gv(RC_INT));
2351#if defined(CONFIG_TCC_BCHECK)2358#if defined(CONFIG_TCC_BCHECK)
2352 if (S->do_bounds_check)2359 if (tcc_state->do_bounds_check)
2353 o(S, 0xe2800001 | (r<<16)|(r<<12)); /* add r,r,#1 */2360 o(0xe2800001 | (r<<16)|(r<<12)); /* add r,r,#1 */
2354#endif2361#endif
2355 o(S, 0xE04D0000|(r<<12)|r); /* sub r, sp, r */2362 o(0xE04D0000|(r<<12)|r); /* sub r, sp, r */
2356#ifdef TCC_ARM_EABI2363#ifdef TCC_ARM_EABI
2357 if (align < 8)2364 if (align < 8)
2358 align = 8;2365 align = 8;
@@ -2361,19 +2368,19 @@ ST_FUNC void gen_vla_alloc(TCCState* S, CType *type, int align) { · 2 unmodified lines
2361 align = 4;2368 align = 4;
2362#endif2369#endif
2363 if (align & (align - 1))2370 if (align & (align - 1))
2364 tcc_error(S, "alignment is not a power of 2: %i", align);2371 tcc_error("alignment is not a power of 2: %i", align);
2365 o(S, stuff_const(0xE3C0D000|(r<<16), align - 1)); /* bic sp, r, #align-1 */2372 o(stuff_const(0xE3C0D000|(r<<16), align - 1)); /* bic sp, r, #align-1 */
2366 vpop(S);2373 vpop();
2367#if defined(CONFIG_TCC_BCHECK)2374#if defined(CONFIG_TCC_BCHECK)
2368 if (S->do_bounds_check) {2375 if (tcc_state->do_bounds_check) {
2369 vpushi(S, 0);2376 vpushi(0);
2370 S->tccgen_vtop->r = TREG_R0;2377 vtop->r = TREG_R0;
2371 o(S, 0xe1a0000d | (S->tccgen_vtop->r << 12)); // mov r0,sp2378 o(0xe1a0000d | (vtop->r << 12)); // mov r0,sp
2372 vswap(S);2379 vswap();
2373 vpush_helper_func(S, TOK___bound_new_region);2380 vpush_helper_func(TOK___bound_new_region);
2374 vrott(S, 3);2381 vrott(3);
2375 gfunc_call(S, 2);2382 gfunc_call(2);
2376 S->func_bound_add_epilog = 1;2383 func_bound_add_epilog = 1;
2377 }2384 }
2378#endif2385#endif
2379}2386}
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 *S, unsigned got_offset, struct sym_attr *attr)110ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
111{111{
112 Section *plt = S->plt;112 Section *plt = s1->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 *S, unsigned got_offset, struct sym_a · 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(S, plt, 20);122 p = section_ptr_add(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 *S, unsigned got_offset, struct sym_a · 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(S, plt, 4);132 p = section_ptr_add(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(S, plt, 16);136 p = section_ptr_add(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 *S, unsigned got_offset, struct sym_a · 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 *S)144ST_FUNC void relocate_plt(TCCState *s1)
145{145{
146 uint8_t *p, *p_end;146 uint8_t *p, *p_end;
147 147
148 if (!S->plt)148 if (!s1->plt)
149 return;149 return;
150 150
151 p = S->plt->data;151 p = s1->plt->data;
152 p_end = p + S->plt->data_offset;152 p_end = p + s1->plt->data_offset;
153 153
154 if (p < p_end) {154 if (p < p_end) {
155 int x = S->got->sh_addr - S->plt->sh_addr - 12;155 int x = s1->got->sh_addr - s1->plt->sh_addr - 12;
156 write32le(S->plt->data + 16, x - 4);156 write32le(s1->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) + (S->plt->data - p) + 4;159 unsigned off = x + read32le(p + 4) + (s1->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 *S) · 4 unmodified lines
167 }167 }
168 }168 }
169 169
170 if (S->plt->reloc) {170 if (s1->plt->reloc) {
171 ElfW_Rel *rel;171 ElfW_Rel *rel;
172 p = S->got->data;172 p = s1->got->data;
173 for_each_elem(S->plt->reloc, 0, rel, ElfW_Rel) {173 for_each_elem(s1->plt->reloc, 0, rel, ElfW_Rel) {
174 write32le(p + rel->r_offset, S->plt->sh_addr);174 write32le(p + rel->r_offset, s1->plt->sh_addr);
175 }175 }
176 }176 }
177}177}
178#endif178#endif
179 179
180void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)180void relocate(TCCState *s1, 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 *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a · 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(S, "can't relocate value at %x,%d",addr, type);215 tcc_error("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 *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a · 36 unmodified lines
255 255
256 /* Relocation infos */256 /* Relocation infos */
257 to_thumb = val & 1;257 to_thumb = val & 1;
258 plt = S->plt;258 plt = s1->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 *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a · 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 = S->sections[sym->st_shndx];270 text = s1->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(S, symtab_section,273 index = put_elf_sym(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 *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a · 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(S, text, 8);284 p = section_ptr_add(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 *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a · 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(S, "can't relocate value at %x,%d",addr, type);304 tcc_error("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 *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a · 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(S, "can't relocate value at %x,%d",addr, type);375 tcc_error("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 (S->output_type == TCC_OUTPUT_DLL) {381 if (s1->output_type == TCC_OUTPUT_DLL) {
382 esym_index = get_sym_attr(S, sym_index, 0)->dyn_index;382 esym_index = get_sym_attr(s1, 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 *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a · 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 += S->got->sh_addr - addr;399 *(int *)ptr += s1->got->sh_addr - addr;
400 return;400 return;
401 case R_ARM_GOTOFF:401 case R_ARM_GOTOFF:
402 *(int *)ptr += val - S->got->sh_addr;402 *(int *)ptr += val - s1->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(S, sym_index, 0)->got_offset;406 *(int *)ptr += get_sym_attr(s1, 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 += S->got->sh_addr +410 *(int *)ptr += s1->got->sh_addr +
411 get_sym_attr(S, sym_index, 0)->got_offset -411 get_sym_attr(s1, 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 *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a · 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 - S->pe_imagebase);431 add32le(ptr, val - s1->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(TCCState* S, int c);12ST_FUNC void g(int c);
13ST_FUNC void gen_le16(TCCState* S, int c);13ST_FUNC void gen_le16(int c);
14ST_FUNC void gen_le32(TCCState* S, int c);14ST_FUNC void gen_le32(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(TCCState* S, int c)28ST_FUNC void g(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(TCCState* S, int c) · 5 unmodified lines
37 ind = ind1;37 ind = ind1;
38}38}
39 39
40ST_FUNC void gen_le16 (TCCState* S, int i)40ST_FUNC void gen_le16 (int i)
41{41{
42 g(S, i);42 g(i);
43 g(S, i>>8);43 g(i>>8);
44}44}
45 45
46ST_FUNC void gen_le32 (TCCState* S, int i)46ST_FUNC void gen_le32 (int i)
47{47{
48 gen_le16(S, i);48 gen_le16(i);
49 gen_le16(S, i>>16);49 gen_le16(i>>16);
50}50}
51 51
52ST_FUNC void gen_expr32(TCCState* S, ExprValue *pe)52ST_FUNC void gen_expr32(ExprValue *pe)
53{53{
54 gen_le32(S, pe->v);54 gen_le32(pe->v);
55}55}
56 56
57ST_FUNC void asm_opcode(TCCState *S, int opcode)57ST_FUNC void asm_opcode(TCCState *s1, int opcode)
58{58{
59 asm_error();59 asm_error();
60}60}
arm64-gen.c+647−641
@@ -90,9 +90,15 @@ 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
93#define IS_FREG(x) ((x) >= TREG_F(0))99#define IS_FREG(x) ((x) >= TREG_F(0))
94 100
95static uint32_t intr(TCCState *S, int r)101static uint32_t intr(int r)
96{102{
97 assert(TREG_R(0) <= r && r <= TREG_R30);103 assert(TREG_R(0) <= r && r <= TREG_R30);
98 return r < TREG_R30 ? r : 30;104 return r < TREG_R30 ? r : 30;
@@ -105,15 +111,15 @@ static uint32_t fltr(int r) · 6 unmodified lines
105}111}
106 112
107// Add an instruction to text section:113// Add an instruction to text section:
108ST_FUNC void o(TCCState *S, unsigned int c)114ST_FUNC void o(unsigned int c)
109{115{
110 int ind1 = S->tccgen_ind + 4;116 int ind1 = ind + 4;
111 if (S->tccgen_nocode_wanted)117 if (nocode_wanted)
112 return;118 return;
113 if (ind1 > cur_text_section->data_allocated)119 if (ind1 > cur_text_section->data_allocated)
114 section_realloc(S, cur_text_section, ind1);120 section_realloc(cur_text_section, ind1);
115 write32le(cur_text_section->data + S->tccgen_ind, c);121 write32le(cur_text_section->data + ind, c);
116 S->tccgen_ind = ind1;122 ind = ind1;
117}123}
118 124
119static int arm64_encode_bimm64(uint64_t x)125static int arm64_encode_bimm64(uint64_t x)
@@ -202,11 +208,11 @@ static uint32_t arm64_movi(int r, uint64_t x) · 82 unmodified lines
202 return 0;208 return 0;
203}209}
204 210
205static void arm64_movimm(TCCState *S, int r, uint64_t x)211static void arm64_movimm(int r, uint64_t x)
206{212{
207 uint32_t i;213 uint32_t i;
208 if ((i = arm64_movi(r, x)))214 if ((i = arm64_movi(r, x)))
209 o(S, i); // a single MOV215 o(i); // a single MOV
210 else {216 else {
211 // MOVZ/MOVN and 1-3 MOVKs217 // MOVZ/MOVN and 1-3 MOVKs
212 int z = 0, m = 0;218 int z = 0, m = 0;
@@ -222,19 +228,19 @@ static void arm64_movimm(TCCState *S, int r, uint64_t x) · 9 unmodified lines
222 }228 }
223 for (i = 0; i < 64; i += 16)229 for (i = 0; i < 64; i += 16)
224 if (x1 >> i & 0xffff) {230 if (x1 >> i & 0xffff) {
225 o(S, mov1 | r | (x1 >> i & 0xffff) << 5 | i << 17);231 o(mov1 | r | (x1 >> i & 0xffff) << 5 | i << 17);
226 // movz/movn x(r),#(*),lsl #(i)232 // movz/movn x(r),#(*),lsl #(i)
227 break;233 break;
228 }234 }
229 for (i += 16; i < 64; i += 16)235 for (i += 16; i < 64; i += 16)
230 if (x1 >> i & 0xffff)236 if (x1 >> i & 0xffff)
231 o(S, 0xf2800000 | r | (x >> i & 0xffff) << 5 | i << 17);237 o(0xf2800000 | r | (x >> i & 0xffff) << 5 | i << 17);
232 // movk x(r),#(*),lsl #(i)238 // movk x(r),#(*),lsl #(i)
233 }239 }
234}240}
235 241
236// Patch all branches in list pointed to by t to branch to a:242// Patch all branches in list pointed to by t to branch to a:
237ST_FUNC void gsym_addr(TCCState *S, int t_, int a_)243ST_FUNC void gsym_addr(int t_, int a_)
238{244{
239 uint32_t t = t_;245 uint32_t t = t_;
240 uint32_t a = a_;246 uint32_t a = a_;
@@ -242,7 +248,7 @@ ST_FUNC void gsym_addr(TCCState *S, int t_, int a_) · 1 unmodified line
242 unsigned char *ptr = cur_text_section->data + t;248 unsigned char *ptr = cur_text_section->data + t;
243 uint32_t next = read32le(ptr);249 uint32_t next = read32le(ptr);
244 if (a - t + 0x8000000 >= 0x10000000)250 if (a - t + 0x8000000 >= 0x10000000)
245 tcc_error(S, "branch out of range");251 tcc_error("branch out of range");
246 write32le(ptr, (a - t == 4 ? 0xd503201f : // nop252 write32le(ptr, (a - t == 4 ? 0xd503201f : // nop
247 0x14000000 | ((a - t) >> 2 & 0x3ffffff))); // b253 0x14000000 | ((a - t) >> 2 & 0x3ffffff))); // b
248 t = next;254 t = next;
@@ -272,17 +278,17 @@ static int arm64_type_size(int t) · 23 unmodified lines
272 return 0;278 return 0;
273}279}
274 280
275static void arm64_spoff(TCCState *S, int reg, uint64_t off)281static void arm64_spoff(int reg, uint64_t off)
276{282{
277 uint32_t sub = off >> 63;283 uint32_t sub = off >> 63;
278 if (sub)284 if (sub)
279 off = -off;285 off = -off;
280 if (off < 4096)286 if (off < 4096)
281 o(S, 0x910003e0 | sub << 30 | reg | off << 10);287 o(0x910003e0 | sub << 30 | reg | off << 10);
282 // (add|sub) x(reg),sp,#(off)288 // (add|sub) x(reg),sp,#(off)
283 else {289 else {
284 arm64_movimm(S, 30, off); // use x30 for offset290 arm64_movimm(30, off); // use x30 for offset
285 o(S, 0x8b3e63e0 | sub << 30 | reg); // (add|sub) x(reg),sp,x30291 o(0x8b3e63e0 | sub << 30 | reg); // (add|sub) x(reg),sp,x30
286 }292 }
287}293}
288 294
@@ -303,41 +309,41 @@ static uint64_t arm64_check_offset(int invert, int sz_, uint64_t off) · 14 unmodified lines
303 return invert ? 0ul : off;309 return invert ? 0ul : off;
304}310}
305 311
306static void arm64_ldrx(TCCState *S, int sg, int sz_, int dst, int bas, uint64_t off)312static void arm64_ldrx(int sg, int sz_, int dst, int bas, uint64_t off)
307{313{
308 uint32_t sz = sz_;314 uint32_t sz = sz_;
309 if (sz >= 2)315 if (sz >= 2)
310 sg = 0;316 sg = 0;
311 if (!(off & ~((uint32_t)0xfff << sz)))317 if (!(off & ~((uint32_t)0xfff << sz)))
312 o(S, 0x39400000 | dst | bas << 5 | off << (10 - sz) |318 o(0x39400000 | dst | bas << 5 | off << (10 - sz) |
313 (uint32_t)!!sg << 23 | sz << 30); // ldr(*) x(dst),[x(bas),#(off)]319 (uint32_t)!!sg << 23 | sz << 30); // ldr(*) x(dst),[x(bas),#(off)]
314 else if (off < 256 || -off <= 256)320 else if (off < 256 || -off <= 256)
315 o(S, 0x38400000 | dst | bas << 5 | (off & 511) << 12 |321 o(0x38400000 | dst | bas << 5 | (off & 511) << 12 |
316 (uint32_t)!!sg << 23 | sz << 30); // ldur(*) x(dst),[x(bas),#(off)]322 (uint32_t)!!sg << 23 | sz << 30); // ldur(*) x(dst),[x(bas),#(off)]
317 else {323 else {
318 arm64_movimm(S, 30, off); // use x30 for offset324 arm64_movimm(30, off); // use x30 for offset
319 o(S, 0x38206800 | dst | bas << 5 | (uint32_t)30 << 16 |325 o(0x38206800 | dst | bas << 5 | (uint32_t)30 << 16 |
320 (uint32_t)(!!sg + 1) << 22 | sz << 30); // ldr(*) x(dst),[x(bas),x30]326 (uint32_t)(!!sg + 1) << 22 | sz << 30); // ldr(*) x(dst),[x(bas),x30]
321 }327 }
322}328}
323 329
324static void arm64_ldrv(TCCState *S, int sz_, int dst, int bas, uint64_t off)330static void arm64_ldrv(int sz_, int dst, int bas, uint64_t off)
325{331{
326 uint32_t sz = sz_;332 uint32_t sz = sz_;
327 if (!(off & ~((uint32_t)0xfff << sz)))333 if (!(off & ~((uint32_t)0xfff << sz)))
328 o(S, 0x3d400000 | dst | bas << 5 | off << (10 - sz) |334 o(0x3d400000 | dst | bas << 5 | off << (10 - sz) |
329 (sz & 4) << 21 | (sz & 3) << 30); // ldr (s|d|q)(dst),[x(bas),#(off)]335 (sz & 4) << 21 | (sz & 3) << 30); // ldr (s|d|q)(dst),[x(bas),#(off)]
330 else if (off < 256 || -off <= 256)336 else if (off < 256 || -off <= 256)
331 o(S, 0x3c400000 | dst | bas << 5 | (off & 511) << 12 |337 o(0x3c400000 | dst | bas << 5 | (off & 511) << 12 |
332 (sz & 4) << 21 | (sz & 3) << 30); // ldur (s|d|q)(dst),[x(bas),#(off)]338 (sz & 4) << 21 | (sz & 3) << 30); // ldur (s|d|q)(dst),[x(bas),#(off)]
333 else {339 else {
334 arm64_movimm(S, 30, off); // use x30 for offset340 arm64_movimm(30, off); // use x30 for offset
335 o(S, 0x3c606800 | dst | bas << 5 | (uint32_t)30 << 16 |341 o(0x3c606800 | dst | bas << 5 | (uint32_t)30 << 16 |
336 sz << 30 | (sz & 4) << 21); // ldr (s|d|q)(dst),[x(bas),x30]342 sz << 30 | (sz & 4) << 21); // ldr (s|d|q)(dst),[x(bas),x30]
337 }343 }
338}344}
339 345
340static void arm64_ldrs(TCCState *S, int reg_, int size)346static void arm64_ldrs(int reg_, int size)
341{347{
342 uint32_t reg = reg_;348 uint32_t reg = reg_;
343 // Use x30 for intermediate value in some cases.349 // Use x30 for intermediate value in some cases.
@@ -347,138 +353,138 @@ static void arm64_ldrs(TCCState *S, int reg_, int size) · 3 unmodified lines
347 /* Can happen with zero size structs */353 /* Can happen with zero size structs */
348 break;354 break;
349 case 1:355 case 1:
350 arm64_ldrx(S, 0, 0, reg, reg, 0);356 arm64_ldrx(0, 0, reg, reg, 0);
351 break;357 break;
352 case 2:358 case 2:
353 arm64_ldrx(S, 0, 1, reg, reg, 0);359 arm64_ldrx(0, 1, reg, reg, 0);
354 break;360 break;
355 case 3:361 case 3:
356 arm64_ldrx(S, 0, 1, 30, reg, 0);362 arm64_ldrx(0, 1, 30, reg, 0);
357 arm64_ldrx(S, 0, 0, reg, reg, 2);363 arm64_ldrx(0, 0, reg, reg, 2);
358 o(S, 0x2a0043c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #16364 o(0x2a0043c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #16
359 break;365 break;
360 case 4:366 case 4:
361 arm64_ldrx(S, 0, 2, reg, reg, 0);367 arm64_ldrx(0, 2, reg, reg, 0);
362 break;368 break;
363 case 5:369 case 5:
364 arm64_ldrx(S, 0, 2, 30, reg, 0);370 arm64_ldrx(0, 2, 30, reg, 0);
365 arm64_ldrx(S, 0, 0, reg, reg, 4);371 arm64_ldrx(0, 0, reg, reg, 4);
366 o(S, 0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32372 o(0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32
367 break;373 break;
368 case 6:374 case 6:
369 arm64_ldrx(S, 0, 2, 30, reg, 0);375 arm64_ldrx(0, 2, 30, reg, 0);
370 arm64_ldrx(S, 0, 1, reg, reg, 4);376 arm64_ldrx(0, 1, reg, reg, 4);
371 o(S, 0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32377 o(0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32
372 break;378 break;
373 case 7:379 case 7:
374 arm64_ldrx(S, 0, 2, 30, reg, 0);380 arm64_ldrx(0, 2, 30, reg, 0);
375 arm64_ldrx(S, 0, 2, reg, reg, 3);381 arm64_ldrx(0, 2, reg, reg, 3);
376 o(S, 0x53087c00 | reg | reg << 5); // lsr w(reg), w(reg), #8382 o(0x53087c00 | reg | reg << 5); // lsr w(reg), w(reg), #8
377 o(S, 0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32383 o(0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32
378 break;384 break;
379 case 8:385 case 8:
380 arm64_ldrx(S, 0, 3, reg, reg, 0);386 arm64_ldrx(0, 3, reg, reg, 0);
381 break;387 break;
382 case 9:388 case 9:
383 arm64_ldrx(S, 0, 0, reg + 1, reg, 8);389 arm64_ldrx(0, 0, reg + 1, reg, 8);
384 arm64_ldrx(S, 0, 3, reg, reg, 0);390 arm64_ldrx(0, 3, reg, reg, 0);
385 break;391 break;
386 case 10:392 case 10:
387 arm64_ldrx(S, 0, 1, reg + 1, reg, 8);393 arm64_ldrx(0, 1, reg + 1, reg, 8);
388 arm64_ldrx(S, 0, 3, reg, reg, 0);394 arm64_ldrx(0, 3, reg, reg, 0);
389 break;395 break;
390 case 11:396 case 11:
391 arm64_ldrx(S, 0, 2, reg + 1, reg, 7);397 arm64_ldrx(0, 2, reg + 1, reg, 7);
392 o(S, 0x53087c00 | (reg+1) | (reg+1) << 5); // lsr w(reg+1), w(reg+1), #8398 o(0x53087c00 | (reg+1) | (reg+1) << 5); // lsr w(reg+1), w(reg+1), #8
393 arm64_ldrx(S, 0, 3, reg, reg, 0);399 arm64_ldrx(0, 3, reg, reg, 0);
394 break;400 break;
395 case 12:401 case 12:
396 arm64_ldrx(S, 0, 2, reg + 1, reg, 8);402 arm64_ldrx(0, 2, reg + 1, reg, 8);
397 arm64_ldrx(S, 0, 3, reg, reg, 0);403 arm64_ldrx(0, 3, reg, reg, 0);
398 break;404 break;
399 case 13:405 case 13:
400 arm64_ldrx(S, 0, 3, reg + 1, reg, 5);406 arm64_ldrx(0, 3, reg + 1, reg, 5);
401 o(S, 0xd358fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #24407 o(0xd358fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #24
402 arm64_ldrx(S, 0, 3, reg, reg, 0);408 arm64_ldrx(0, 3, reg, reg, 0);
403 break;409 break;
404 case 14:410 case 14:
405 arm64_ldrx(S, 0, 3, reg + 1, reg, 6);411 arm64_ldrx(0, 3, reg + 1, reg, 6);
406 o(S, 0xd350fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #16412 o(0xd350fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #16
407 arm64_ldrx(S, 0, 3, reg, reg, 0);413 arm64_ldrx(0, 3, reg, reg, 0);
408 break;414 break;
409 case 15:415 case 15:
410 arm64_ldrx(S, 0, 3, reg + 1, reg, 7);416 arm64_ldrx(0, 3, reg + 1, reg, 7);
411 o(S, 0xd348fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #8417 o(0xd348fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #8
412 arm64_ldrx(S, 0, 3, reg, reg, 0);418 arm64_ldrx(0, 3, reg, reg, 0);
413 break;419 break;
414 case 16:420 case 16:
415 o(S, 0xa9400000 | reg | (reg+1) << 10 | reg << 5);421 o(0xa9400000 | reg | (reg+1) << 10 | reg << 5);
416 // ldp x(reg),x(reg+1),[x(reg)]422 // ldp x(reg),x(reg+1),[x(reg)]
417 break;423 break;
418 }424 }
419}425}
420 426
421static void arm64_strx(TCCState *S, int sz_, int dst, int bas, uint64_t off)427static void arm64_strx(int sz_, int dst, int bas, uint64_t off)
422{428{
423 uint32_t sz = sz_;429 uint32_t sz = sz_;
424 if (!(off & ~((uint32_t)0xfff << sz)))430 if (!(off & ~((uint32_t)0xfff << sz)))
425 o(S, 0x39000000 | dst | bas << 5 | off << (10 - sz) | sz << 30);431 o(0x39000000 | dst | bas << 5 | off << (10 - sz) | sz << 30);
426 // str(*) x(dst),[x(bas],#(off)]432 // str(*) x(dst),[x(bas],#(off)]
427 else if (off < 256 || -off <= 256)433 else if (off < 256 || -off <= 256)
428 o(S, 0x38000000 | dst | bas << 5 | (off & 511) << 12 | sz << 30);434 o(0x38000000 | dst | bas << 5 | (off & 511) << 12 | sz << 30);
429 // stur(*) x(dst),[x(bas],#(off)]435 // stur(*) x(dst),[x(bas],#(off)]
430 else {436 else {
431 arm64_movimm(S, 30, off); // use x30 for offset437 arm64_movimm(30, off); // use x30 for offset
432 o(S, 0x38206800 | dst | bas << 5 | (uint32_t)30 << 16 | sz << 30);438 o(0x38206800 | dst | bas << 5 | (uint32_t)30 << 16 | sz << 30);
433 // str(*) x(dst),[x(bas),x30]439 // str(*) x(dst),[x(bas),x30]
434 }440 }
435}441}
436 442
437static void arm64_strv(TCCState *S, int sz_, int dst, int bas, uint64_t off)443static void arm64_strv(int sz_, int dst, int bas, uint64_t off)
438{444{
439 uint32_t sz = sz_;445 uint32_t sz = sz_;
440 if (!(off & ~((uint32_t)0xfff << sz)))446 if (!(off & ~((uint32_t)0xfff << sz)))
441 o(S, 0x3d000000 | dst | bas << 5 | off << (10 - sz) |447 o(0x3d000000 | dst | bas << 5 | off << (10 - sz) |
442 (sz & 4) << 21 | (sz & 3) << 30); // str (s|d|q)(dst),[x(bas),#(off)]448 (sz & 4) << 21 | (sz & 3) << 30); // str (s|d|q)(dst),[x(bas),#(off)]
443 else if (off < 256 || -off <= 256)449 else if (off < 256 || -off <= 256)
444 o(S, 0x3c000000 | dst | bas << 5 | (off & 511) << 12 |450 o(0x3c000000 | dst | bas << 5 | (off & 511) << 12 |
445 (sz & 4) << 21 | (sz & 3) << 30); // stur (s|d|q)(dst),[x(bas),#(off)]451 (sz & 4) << 21 | (sz & 3) << 30); // stur (s|d|q)(dst),[x(bas),#(off)]
446 else {452 else {
447 arm64_movimm(S, 30, off); // use x30 for offset453 arm64_movimm(30, off); // use x30 for offset
448 o(S, 0x3c206800 | dst | bas << 5 | (uint32_t)30 << 16 |454 o(0x3c206800 | dst | bas << 5 | (uint32_t)30 << 16 |
449 sz << 30 | (sz & 4) << 21); // str (s|d|q)(dst),[x(bas),x30]455 sz << 30 | (sz & 4) << 21); // str (s|d|q)(dst),[x(bas),x30]
450 }456 }
451}457}
452 458
453static void arm64_sym(TCCState *S, int r, Sym *sym, unsigned long addend)459static void arm64_sym(int r, Sym *sym, unsigned long addend)
454{460{
455 greloca(S, cur_text_section, sym, S->tccgen_ind, R_AARCH64_ADR_GOT_PAGE, 0);461 greloca(cur_text_section, sym, ind, R_AARCH64_ADR_GOT_PAGE, 0);
456 o(S, 0x90000000 | r); // adrp xr, #sym462 o(0x90000000 | r); // adrp xr, #sym
457 greloca(S, cur_text_section, sym, S->tccgen_ind, R_AARCH64_LD64_GOT_LO12_NC, 0);463 greloca(cur_text_section, sym, ind, R_AARCH64_LD64_GOT_LO12_NC, 0);
458 o(S, 0xf9400000 | r | (r << 5)); // ld xr,[xr, #sym]464 o(0xf9400000 | r | (r << 5)); // ld xr,[xr, #sym]
459 if (addend) {465 if (addend) {
460 // add xr, xr, #addend466 // add xr, xr, #addend
461 if (addend & 0xffful)467 if (addend & 0xffful)
462 o(S, 0x91000000 | r | r << 5 | (addend & 0xfff) << 10);468 o(0x91000000 | r | r << 5 | (addend & 0xfff) << 10);
463 if (addend > 0xffful) {469 if (addend > 0xffful) {
464 // add xr, xr, #addend, lsl #12470 // add xr, xr, #addend, lsl #12
465 if (addend & 0xfff000ul)471 if (addend & 0xfff000ul)
466 o(S, 0x91400000 | r | r << 5 | ((addend >> 12) & 0xfff) << 10);472 o(0x91400000 | r | r << 5 | ((addend >> 12) & 0xfff) << 10);
467 if (addend > 0xfffffful) {473 if (addend > 0xfffffful) {
468 /* very unlikely */474 /* very unlikely */
469 int t = r ? 0 : 1;475 int t = r ? 0 : 1;
470 o(S, 0xf81f0fe0 | t); /* str xt, [sp, #-16]! */476 o(0xf81f0fe0 | t); /* str xt, [sp, #-16]! */
471 arm64_movimm(S, t, addend & ~0xfffffful); // use xt for addent477 arm64_movimm(t, addend & ~0xfffffful); // use xt for addent
472 o(S, 0x91000000 | r | (t << 5)); /* add xr, xt, #0 */478 o(0x91000000 | r | (t << 5)); /* add xr, xt, #0 */
473 o(S, 0xf84107e0 | t); /* ldr xt, [sp], #16 */479 o(0xf84107e0 | t); /* ldr xt, [sp], #16 */
474 }480 }
475 }481 }
476 }482 }
477}483}
478 484
479static void arm64_load_cmp(TCCState *S, int r, SValue *sv);485static void arm64_load_cmp(int r, SValue *sv);
480 486
481ST_FUNC void load(TCCState *S, int r, SValue *sv)487ST_FUNC void load(int r, SValue *sv)
482{488{
483 int svtt = sv->type.t;489 int svtt = sv->type.t;
484 int svr = sv->r & ~VT_BOUNDED;490 int svr = sv->r & ~VT_BOUNDED;
@@ -488,24 +494,24 @@ ST_FUNC void load(TCCState *S, int r, SValue *sv) · 3 unmodified lines
488 494
489 if (svr == (VT_LOCAL | VT_LVAL)) {495 if (svr == (VT_LOCAL | VT_LVAL)) {
490 if (IS_FREG(r))496 if (IS_FREG(r))
491 arm64_ldrv(S, arm64_type_size(svtt), fltr(r), 29, svcul);497 arm64_ldrv(arm64_type_size(svtt), fltr(r), 29, svcul);
492 else498 else
493 arm64_ldrx(S, !(svtt & VT_UNSIGNED), arm64_type_size(svtt),499 arm64_ldrx(!(svtt & VT_UNSIGNED), arm64_type_size(svtt),
494 intr(S, r), 29, svcul);500 intr(r), 29, svcul);
495 return;501 return;
496 }502 }
497 503
498 if (svr == (VT_CONST | VT_LVAL)) {504 if (svr == (VT_CONST | VT_LVAL)) {
499 if (sv->sym)505 if (sv->sym)
500 arm64_sym(S, 30, sv->sym, // use x30 for address506 arm64_sym(30, sv->sym, // use x30 for address
501 arm64_check_offset(0, arm64_type_size(svtt), sv->c.i));507 arm64_check_offset(0, arm64_type_size(svtt), sv->c.i));
502 else508 else
503 arm64_movimm (S, 30, sv->c.i);509 arm64_movimm (30, sv->c.i);
504 if (IS_FREG(r))510 if (IS_FREG(r))
505 arm64_ldrv(S, arm64_type_size(svtt), fltr(r), 30,511 arm64_ldrv(arm64_type_size(svtt), fltr(r), 30,
506 arm64_check_offset(1, arm64_type_size(svtt), sv->c.i));512 arm64_check_offset(1, arm64_type_size(svtt), sv->c.i));
507 else513 else
508 arm64_ldrx(S, !(svtt&VT_UNSIGNED), arm64_type_size(svtt), intr(S, r), 30,514 arm64_ldrx(!(svtt&VT_UNSIGNED), arm64_type_size(svtt), intr(r), 30,
509 arm64_check_offset(1, arm64_type_size(svtt), sv->c.i));515 arm64_check_offset(1, arm64_type_size(svtt), sv->c.i));
510 return;516 return;
511 }517 }
@@ -513,34 +519,34 @@ ST_FUNC void load(TCCState *S, int r, SValue *sv) · 1 unmodified line
513 if ((svr & ~VT_VALMASK) == VT_LVAL && svrv < VT_CONST) {519 if ((svr & ~VT_VALMASK) == VT_LVAL && svrv < VT_CONST) {
514 if ((svtt & VT_BTYPE) != VT_VOID) {520 if ((svtt & VT_BTYPE) != VT_VOID) {
515 if (IS_FREG(r))521 if (IS_FREG(r))
516 arm64_ldrv(S, arm64_type_size(svtt), fltr(r), intr(S, svrv), 0);522 arm64_ldrv(arm64_type_size(svtt), fltr(r), intr(svrv), 0);
517 else523 else
518 arm64_ldrx(S, !(svtt & VT_UNSIGNED), arm64_type_size(svtt),524 arm64_ldrx(!(svtt & VT_UNSIGNED), arm64_type_size(svtt),
519 intr(S, r), intr(S, svrv), 0);525 intr(r), intr(svrv), 0);
520 }526 }
521 return;527 return;
522 }528 }
523 529
524 if (svr == (VT_CONST | VT_LVAL | VT_SYM)) {530 if (svr == (VT_CONST | VT_LVAL | VT_SYM)) {
525 arm64_sym(S, 30, sv->sym, // use x30 for address531 arm64_sym(30, sv->sym, // use x30 for address
526 arm64_check_offset(0, arm64_type_size(svtt), svcul));532 arm64_check_offset(0, arm64_type_size(svtt), svcul));
527 if (IS_FREG(r))533 if (IS_FREG(r))
528 arm64_ldrv(S, arm64_type_size(svtt), fltr(r), 30,534 arm64_ldrv(arm64_type_size(svtt), fltr(r), 30,
529 arm64_check_offset(1, arm64_type_size(svtt), svcul));535 arm64_check_offset(1, arm64_type_size(svtt), svcul));
530 else536 else
531 arm64_ldrx(S, !(svtt&VT_UNSIGNED), arm64_type_size(svtt), intr(S, r), 30,537 arm64_ldrx(!(svtt&VT_UNSIGNED), arm64_type_size(svtt), intr(r), 30,
532 arm64_check_offset(1, arm64_type_size(svtt), svcul));538 arm64_check_offset(1, arm64_type_size(svtt), svcul));
533 return;539 return;
534 }540 }
535 541
536 if (svr == (VT_CONST | VT_SYM)) {542 if (svr == (VT_CONST | VT_SYM)) {
537 arm64_sym(S, intr(S, r), sv->sym, svcul);543 arm64_sym(intr(r), sv->sym, svcul);
538 return;544 return;
539 }545 }
540 546
541 if (svr == VT_CONST) {547 if (svr == VT_CONST) {
542 if ((svtt & VT_BTYPE) != VT_VOID)548 if ((svtt & VT_BTYPE) != VT_VOID)
543 arm64_movimm(S, intr(S, r), arm64_type_size(svtt) == 3 ?549 arm64_movimm(intr(r), arm64_type_size(svtt) == 3 ?
544 sv->c.i : (uint32_t)svcul);550 sv->c.i : (uint32_t)svcul);
545 return;551 return;
546 }552 }
@@ -548,12 +554,12 @@ ST_FUNC void load(TCCState *S, int r, SValue *sv) · 1 unmodified line
548 if (svr < VT_CONST) {554 if (svr < VT_CONST) {
549 if (IS_FREG(r) && IS_FREG(svr))555 if (IS_FREG(r) && IS_FREG(svr))
550 if (svtt == VT_LDOUBLE)556 if (svtt == VT_LDOUBLE)
551 o(S, 0x4ea01c00 | fltr(r) | fltr(svr) << 5);557 o(0x4ea01c00 | fltr(r) | fltr(svr) << 5);
552 // mov v(r).16b,v(svr).16b558 // mov v(r).16b,v(svr).16b
553 else559 else
554 o(S, 0x1e604000 | fltr(r) | fltr(svr) << 5); // fmov d(r),d(svr)560 o(0x1e604000 | fltr(r) | fltr(svr) << 5); // fmov d(r),d(svr)
555 else if (!IS_FREG(r) && !IS_FREG(svr))561 else if (!IS_FREG(r) && !IS_FREG(svr))
556 o(S, 0xaa0003e0 | intr(S, r) | intr(S, svr) << 16); // mov x(r),x(svr)562 o(0xaa0003e0 | intr(r) | intr(svr) << 16); // mov x(r),x(svr)
557 else563 else
558 assert(0);564 assert(0);
559 return;565 return;
@@ -561,35 +567,35 @@ ST_FUNC void load(TCCState *S, int r, SValue *sv) · 1 unmodified line
561 567
562 if (svr == VT_LOCAL) {568 if (svr == VT_LOCAL) {
563 if (-svcul < 0x1000)569 if (-svcul < 0x1000)
564 o(S, 0xd10003a0 | intr(S, r) | -svcul << 10); // sub x(r),x29,#...570 o(0xd10003a0 | intr(r) | -svcul << 10); // sub x(r),x29,#...
565 else {571 else {
566 arm64_movimm(S, 30, -svcul); // use x30 for offset572 arm64_movimm(30, -svcul); // use x30 for offset
567 o(S, 0xcb0003a0 | intr(S, r) | (uint32_t)30 << 16); // sub x(r),x29,x30573 o(0xcb0003a0 | intr(r) | (uint32_t)30 << 16); // sub x(r),x29,x30
568 }574 }
569 return;575 return;
570 }576 }
571 577
572 if (svr == VT_JMP || svr == VT_JMPI) {578 if (svr == VT_JMP || svr == VT_JMPI) {
573 int t = (svr == VT_JMPI);579 int t = (svr == VT_JMPI);
574 arm64_movimm(S, intr(S, r), t);580 arm64_movimm(intr(r), t);
575 o(S, 0x14000002); // b .+8581 o(0x14000002); // b .+8
576 gsym(S, svcul);582 gsym(svcul);
577 arm64_movimm(S, intr(S, r), t ^ 1);583 arm64_movimm(intr(r), t ^ 1);
578 return;584 return;
579 }585 }
580 586
581 if (svr == (VT_LLOCAL | VT_LVAL)) {587 if (svr == (VT_LLOCAL | VT_LVAL)) {
582 arm64_ldrx(S, 0, 3, 30, 29, svcul); // use x30 for offset588 arm64_ldrx(0, 3, 30, 29, svcul); // use x30 for offset
583 if (IS_FREG(r))589 if (IS_FREG(r))
584 arm64_ldrv(S, arm64_type_size(svtt), fltr(r), 30, 0);590 arm64_ldrv(arm64_type_size(svtt), fltr(r), 30, 0);
585 else591 else
586 arm64_ldrx(S, !(svtt & VT_UNSIGNED), arm64_type_size(svtt),592 arm64_ldrx(!(svtt & VT_UNSIGNED), arm64_type_size(svtt),
587 intr(S, r), 30, 0);593 intr(r), 30, 0);
588 return;594 return;
589 }595 }
590 596
591 if (svr == VT_CMP) {597 if (svr == VT_CMP) {
592 arm64_load_cmp(S, r, sv);598 arm64_load_cmp(r, sv);
593 return;599 return;
594 }600 }
595 601
@@ -597,7 +603,7 @@ ST_FUNC void load(TCCState *S, int r, SValue *sv) · 1 unmodified line
597 assert(0);603 assert(0);
598}604}
599 605
600ST_FUNC void store(TCCState *S, int r, SValue *sv)606ST_FUNC void store(int r, SValue *sv)
601{607{
602 int svtt = sv->type.t;608 int svtt = sv->type.t;
603 int svr = sv->r & ~VT_BOUNDED;609 int svr = sv->r & ~VT_BOUNDED;
@@ -607,43 +613,43 @@ ST_FUNC void store(TCCState *S, int r, SValue *sv) · 3 unmodified lines
607 613
608 if (svr == (VT_LOCAL | VT_LVAL)) {614 if (svr == (VT_LOCAL | VT_LVAL)) {
609 if (IS_FREG(r))615 if (IS_FREG(r))
610 arm64_strv(S, arm64_type_size(svtt), fltr(r), 29, svcul);616 arm64_strv(arm64_type_size(svtt), fltr(r), 29, svcul);
611 else617 else
612 arm64_strx(S, arm64_type_size(svtt), intr(S, r), 29, svcul);618 arm64_strx(arm64_type_size(svtt), intr(r), 29, svcul);
613 return;619 return;
614 }620 }
615 621
616 if (svr == (VT_CONST | VT_LVAL)) {622 if (svr == (VT_CONST | VT_LVAL)) {
617 if (sv->sym)623 if (sv->sym)
618 arm64_sym(S, 30, sv->sym, // use x30 for address624 arm64_sym(30, sv->sym, // use x30 for address
619 arm64_check_offset(0, arm64_type_size(svtt), sv->c.i));625 arm64_check_offset(0, arm64_type_size(svtt), sv->c.i));
620 else626 else
621 arm64_movimm(S, 30, sv->c.i);627 arm64_movimm (30, sv->c.i);
622 if (IS_FREG(r))628 if (IS_FREG(r))
623 arm64_strv(S, arm64_type_size(svtt), fltr(r), 30,629 arm64_strv(arm64_type_size(svtt), fltr(r), 30,
624 arm64_check_offset(1, arm64_type_size(svtt), sv->c.i));630 arm64_check_offset(1, arm64_type_size(svtt), sv->c.i));
625 else631 else
626 arm64_strx(S, arm64_type_size(svtt), intr(S, r), 30,632 arm64_strx(arm64_type_size(svtt), intr(r), 30,
627 arm64_check_offset(1, arm64_type_size(svtt), sv->c.i));633 arm64_check_offset(1, arm64_type_size(svtt), sv->c.i));
628 return;634 return;
629 }635 }
630 636
631 if ((svr & ~VT_VALMASK) == VT_LVAL && svrv < VT_CONST) {637 if ((svr & ~VT_VALMASK) == VT_LVAL && svrv < VT_CONST) {
632 if (IS_FREG(r))638 if (IS_FREG(r))
633 arm64_strv(S, arm64_type_size(svtt), fltr(r), intr(S, svrv), 0);639 arm64_strv(arm64_type_size(svtt), fltr(r), intr(svrv), 0);
634 else640 else
635 arm64_strx(S, arm64_type_size(svtt), intr(S, r), intr(S, svrv), 0);641 arm64_strx(arm64_type_size(svtt), intr(r), intr(svrv), 0);
636 return;642 return;
637 }643 }
638 644
639 if (svr == (VT_CONST | VT_LVAL | VT_SYM)) {645 if (svr == (VT_CONST | VT_LVAL | VT_SYM)) {
640 arm64_sym(S, 30, sv->sym, // use x30 for address646 arm64_sym(30, sv->sym, // use x30 for address
641 arm64_check_offset(0, arm64_type_size(svtt), svcul));647 arm64_check_offset(0, arm64_type_size(svtt), svcul));
642 if (IS_FREG(r))648 if (IS_FREG(r))
643 arm64_strv(S, arm64_type_size(svtt), fltr(r), 30,649 arm64_strv(arm64_type_size(svtt), fltr(r), 30,
644 arm64_check_offset(1, arm64_type_size(svtt), svcul));650 arm64_check_offset(1, arm64_type_size(svtt), svcul));
645 else651 else
646 arm64_strx(S, arm64_type_size(svtt), intr(S, r), 30,652 arm64_strx(arm64_type_size(svtt), intr(r), 30,
647 arm64_check_offset(1, arm64_type_size(svtt), svcul));653 arm64_check_offset(1, arm64_type_size(svtt), svcul));
648 return;654 return;
649 }655 }
@@ -652,82 +658,82 @@ ST_FUNC void store(TCCState *S, int r, SValue *sv) · 2 unmodified lines
652 assert(0);658 assert(0);
653}659}
654 660
655static void arm64_gen_bl_or_b(TCCState *S, int b)661static void arm64_gen_bl_or_b(int b)
656{662{
657 if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (S->tccgen_vtop->r & VT_SYM)) {663 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (vtop->r & VT_SYM)) {
658 greloca(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind,664 greloca(cur_text_section, vtop->sym, ind,
659 b ? R_AARCH64_JUMP26 : R_AARCH64_CALL26, 0);665 b ? R_AARCH64_JUMP26 : R_AARCH64_CALL26, 0);
660 o(S, 0x14000000 | (uint32_t)!b << 31); // b/bl .666 o(0x14000000 | (uint32_t)!b << 31); // b/bl .
661 }667 }
662 else {668 else {
663#ifdef CONFIG_TCC_BCHECK669#ifdef CONFIG_TCC_BCHECK
664 S->tccgen_vtop->r &= ~VT_MUSTBOUND;670 vtop->r &= ~VT_MUSTBOUND;
665#endif671#endif
666 o(S, 0xd61f0000 | (uint32_t)!b << 21 | intr(S, gv(S, RC_R30)) << 5); // br/blr672 o(0xd61f0000 | (uint32_t)!b << 21 | intr(gv(RC_R30)) << 5); // br/blr
667 }673 }
668}674}
669 675
670#if defined(CONFIG_TCC_BCHECK)676#if defined(CONFIG_TCC_BCHECK)
671 677
672static void gen_bounds_call(TCCState *S, int v)678static void gen_bounds_call(int v)
673{679{
674 Sym *sym = external_helper_sym(S, v);680 Sym *sym = external_helper_sym(v);
675 681
676 greloca(S, cur_text_section, sym, S->tccgen_ind, R_AARCH64_CALL26, 0);682 greloca(cur_text_section, sym, ind, R_AARCH64_CALL26, 0);
677 o(S, 0x94000000); // bl683 o(0x94000000); // bl
678}684}
679 685
680static void gen_bounds_prolog(TCCState *S)686static void gen_bounds_prolog(void)
681{687{
682 /* leave some room for bound checking code */688 /* leave some room for bound checking code */
683 S->func_bound_offset = lbounds_section->data_offset;689 func_bound_offset = lbounds_section->data_offset;
684 S->func_bound_ind = S->tccgen_ind;690 func_bound_ind = ind;
685 S->func_bound_add_epilog = 0;691 func_bound_add_epilog = 0;
686 o(S, 0xd503201f); /* nop -> mov x0, lbound section pointer */692 o(0xd503201f); /* nop -> mov x0, lbound section pointer */
687 o(S, 0xd503201f);693 o(0xd503201f);
688 o(S, 0xd503201f);694 o(0xd503201f);
689 o(S, 0xd503201f); /* nop -> call __bound_local_new */695 o(0xd503201f); /* nop -> call __bound_local_new */
690}696}
691 697
692static void gen_bounds_epilog(TCCState *S)698static void gen_bounds_epilog(void)
693{699{
694 addr_t saved_ind;700 addr_t saved_ind;
695 addr_t *bounds_ptr;701 addr_t *bounds_ptr;
696 Sym *sym_data;702 Sym *sym_data;
697 int offset_modified = S->func_bound_offset != lbounds_section->data_offset;703 int offset_modified = func_bound_offset != lbounds_section->data_offset;
698 704
699 if (!offset_modified && !S->func_bound_add_epilog)705 if (!offset_modified && !func_bound_add_epilog)
700 return;706 return;
701 707
702 /* add end of table info */708 /* add end of table info */
703 bounds_ptr = section_ptr_add(S, lbounds_section, sizeof(addr_t));709 bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));
704 *bounds_ptr = 0;710 *bounds_ptr = 0;
705 711
706 sym_data = get_sym_ref(S, &S->tccgen_char_pointer_type, lbounds_section,712 sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
707 S->func_bound_offset, lbounds_section->data_offset);713 func_bound_offset, lbounds_section->data_offset);
708 714
709 /* generate bound local allocation */715 /* generate bound local allocation */
710 if (offset_modified) {716 if (offset_modified) {
711 saved_ind = S->tccgen_ind;717 saved_ind = ind;
712 S->tccgen_ind = S->func_bound_ind;718 ind = func_bound_ind;
713 greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_AARCH64_ADR_GOT_PAGE, 0);719 greloca(cur_text_section, sym_data, ind, R_AARCH64_ADR_GOT_PAGE, 0);
714 o(S, 0x90000000 | 0); // adrp x0, #sym_data720 o(0x90000000 | 0); // adrp x0, #sym_data
715 greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_AARCH64_LD64_GOT_LO12_NC, 0);721 greloca(cur_text_section, sym_data, ind, R_AARCH64_LD64_GOT_LO12_NC, 0);
716 o(S, 0xf9400000 | 0 | (0 << 5)); // ld x0,[x0, #sym_data]722 o(0xf9400000 | 0 | (0 << 5)); // ld x0,[x0, #sym_data]
717 gen_bounds_call(S, TOK___bound_local_new);723 gen_bounds_call(TOK___bound_local_new);
718 S->tccgen_ind = saved_ind;724 ind = saved_ind;
719 }725 }
720 726
721 /* generate bound check local freeing */727 /* generate bound check local freeing */
722 o(S, 0xf81f0fe0); /* str x0, [sp, #-16]! */728 o(0xf81f0fe0); /* str x0, [sp, #-16]! */
723 o(S, 0x3c9f0fe0); /* str q0, [sp, #-16]! */729 o(0x3c9f0fe0); /* str q0, [sp, #-16]! */
724 greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_AARCH64_ADR_GOT_PAGE, 0);730 greloca(cur_text_section, sym_data, ind, R_AARCH64_ADR_GOT_PAGE, 0);
725 o(S, 0x90000000 | 0); // adrp x0, #sym_data731 o(0x90000000 | 0); // adrp x0, #sym_data
726 greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_AARCH64_LD64_GOT_LO12_NC, 0);732 greloca(cur_text_section, sym_data, ind, R_AARCH64_LD64_GOT_LO12_NC, 0);
727 o(S, 0xf9400000 | 0 | (0 << 5)); // ld x0,[x0, #sym_data]733 o(0xf9400000 | 0 | (0 << 5)); // ld x0,[x0, #sym_data]
728 gen_bounds_call(S, TOK___bound_local_delete);734 gen_bounds_call(TOK___bound_local_delete);
729 o(S, 0x3cc107e0); /* ldr q0, [sp], #16 */735 o(0x3cc107e0); /* ldr q0, [sp], #16 */
730 o(S, 0xf84107e0); /* ldr x0, [sp], #16 */736 o(0xf84107e0); /* ldr x0, [sp], #16 */
731}737}
732#endif738#endif
733 739
@@ -964,7 +970,7 @@ static unsigned long arm64_pcs(int n, CType **type, unsigned long *a) · 230 unmodified lines
964 return stack;970 return stack;
965}971}
966 972
967ST_FUNC void gfunc_call(TCCState *S, int nb_args)973ST_FUNC void gfunc_call(int nb_args)
968{974{
969 CType *return_type;975 CType *return_type;
970 CType **t;976 CType **t;
@@ -973,28 +979,28 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args) · 2 unmodified lines
973 int i;979 int i;
974 980
975#ifdef CONFIG_TCC_BCHECK981#ifdef CONFIG_TCC_BCHECK
976 if (S->do_bounds_check)982 if (tcc_state->do_bounds_check)
977 gbound_args(S, nb_args);983 gbound_args(nb_args);
978#endif984#endif
979 985
980 return_type = &S->tccgen_vtop[-nb_args].type.ref->type;986 return_type = &vtop[-nb_args].type.ref->type;
981 if ((return_type->t & VT_BTYPE) == VT_STRUCT)987 if ((return_type->t & VT_BTYPE) == VT_STRUCT)
982 --nb_args;988 --nb_args;
983 989
984 t = tcc_malloc(S, (nb_args + 1) * sizeof(*t));990 t = tcc_malloc((nb_args + 1) * sizeof(*t));
985 a = tcc_malloc(S, (nb_args + 1) * sizeof(*a));991 a = tcc_malloc((nb_args + 1) * sizeof(*a));
986 a1 = tcc_malloc(S, (nb_args + 1) * sizeof(*a1));992 a1 = tcc_malloc((nb_args + 1) * sizeof(*a1));
987 993
988 t[0] = return_type;994 t[0] = return_type;
989 for (i = 0; i < nb_args; i++)995 for (i = 0; i < nb_args; i++)
990 t[nb_args - i] = &S->tccgen_vtop[-i].type;996 t[nb_args - i] = &vtop[-i].type;
991 997
992 stack = arm64_pcs(nb_args, t, a);998 stack = arm64_pcs(nb_args, t, a);
993 999
994 // Allocate space for structs replaced by pointer:1000 // Allocate space for structs replaced by pointer:
995 for (i = nb_args; i; i--)1001 for (i = nb_args; i; i--)
996 if (a[i] & 1) {1002 if (a[i] & 1) {
997 SValue *arg = &S->tccgen_vtop[i - nb_args];1003 SValue *arg = &vtop[i - nb_args];
998 int align, size = type_size(&arg->type, &align);1004 int align, size = type_size(&arg->type, &align);
999 assert((arg->type.t & VT_BTYPE) == VT_STRUCT);1005 assert((arg->type.t & VT_BTYPE) == VT_STRUCT);
1000 stack = (stack + align - 1) & -align;1006 stack = (stack + align - 1) & -align;
@@ -1005,134 +1011,134 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args) · 4 unmodified lines
1005 stack = (stack + 15) >> 4 << 4;1011 stack = (stack + 15) >> 4 << 4;
1006 1012
1007 /* fetch cpu flag before generating any code */1013 /* fetch cpu flag before generating any code */
1008 if ((S->tccgen_vtop->r & VT_VALMASK) == VT_CMP)1014 if ((vtop->r & VT_VALMASK) == VT_CMP)
1009 gv(S, RC_INT);1015 gv(RC_INT);
1010 1016
1011 if (stack >= 0x1000000) // 16Mb1017 if (stack >= 0x1000000) // 16Mb
1012 tcc_error(S, "stack size too big %lu", stack);1018 tcc_error("stack size too big %lu", stack);
1013 if (stack & 0xfff)1019 if (stack & 0xfff)
1014 o(S, 0xd10003ff | (stack & 0xfff) << 10); // sub sp,sp,#(n)1020 o(0xd10003ff | (stack & 0xfff) << 10); // sub sp,sp,#(n)
1015 if (stack >> 12)1021 if (stack >> 12)
1016 o(S, 0xd14003ff | (stack >> 12) << 10);1022 o(0xd14003ff | (stack >> 12) << 10);
1017 1023
1018 // First pass: set all values on stack1024 // First pass: set all values on stack
1019 for (i = nb_args; i; i--) {1025 for (i = nb_args; i; i--) {
1020 vpushv(S, S->tccgen_vtop - nb_args + i);1026 vpushv(vtop - nb_args + i);
1021 1027
1022 if (a[i] & 1) {1028 if (a[i] & 1) {
1023 // struct replaced by pointer1029 // struct replaced by pointer
1024 int r = get_reg(S, RC_INT);1030 int r = get_reg(RC_INT);
1025 arm64_spoff(S, intr(S, r), a1[i]);1031 arm64_spoff(intr(r), a1[i]);
1026 vset(S, &S->tccgen_vtop->type, r | VT_LVAL, 0);1032 vset(&vtop->type, r | VT_LVAL, 0);
1027 vswap(S);1033 vswap();
1028 vstore(S);1034 vstore();
1029 if (a[i] >= 32) {1035 if (a[i] >= 32) {
1030 // pointer on stack1036 // pointer on stack
1031 r = get_reg(S, RC_INT);1037 r = get_reg(RC_INT);
1032 arm64_spoff(S, intr(S, r), a1[i]);1038 arm64_spoff(intr(r), a1[i]);
1033 arm64_strx(S, 3, intr(S, r), 31, (a[i] - 32) >> 1 << 1);1039 arm64_strx(3, intr(r), 31, (a[i] - 32) >> 1 << 1);
1034 }1040 }
1035 }1041 }
1036 else if (a[i] >= 32) {1042 else if (a[i] >= 32) {
1037 // value on stack1043 // value on stack
1038 if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_STRUCT) {1044 if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
1039 int r = get_reg(S, RC_INT);1045 int r = get_reg(RC_INT);
1040 arm64_spoff(S, intr(S, r), a[i] - 32);1046 arm64_spoff(intr(r), a[i] - 32);
1041 vset(S, &S->tccgen_vtop->type, r | VT_LVAL, 0);1047 vset(&vtop->type, r | VT_LVAL, 0);
1042 vswap(S);1048 vswap();
1043 vstore(S);1049 vstore();
1044 }1050 }
1045 else if (is_float(S->tccgen_vtop->type.t)) {1051 else if (is_float(vtop->type.t)) {
1046 gv(S, RC_FLOAT);1052 gv(RC_FLOAT);
1047 arm64_strv(S, arm64_type_size(S->tccgen_vtop[0].type.t),1053 arm64_strv(arm64_type_size(vtop[0].type.t),
1048 fltr(S->tccgen_vtop[0].r), 31, a[i] - 32);1054 fltr(vtop[0].r), 31, a[i] - 32);
1049 }1055 }
1050 else {1056 else {
1051 gv(S, RC_INT);1057 gv(RC_INT);
1052 arm64_strx(S, arm64_type_size(S->tccgen_vtop[0].type.t),1058 arm64_strx(arm64_type_size(vtop[0].type.t),
1053 intr(S, S->tccgen_vtop[0].r), 31, a[i] - 32);1059 intr(vtop[0].r), 31, a[i] - 32);
1054 }1060 }
1055 }1061 }
1056 1062
1057 --S->tccgen_vtop;1063 --vtop;
1058 }1064 }
1059 1065
1060 // Second pass: assign values to registers1066 // Second pass: assign values to registers
1061 for (i = nb_args; i; i--, S->tccgen_vtop--) {1067 for (i = nb_args; i; i--, vtop--) {
1062 if (a[i] < 16 && !(a[i] & 1)) {1068 if (a[i] < 16 && !(a[i] & 1)) {
1063 // value in general-purpose registers1069 // value in general-purpose registers
1064 if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_STRUCT) {1070 if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
1065 int align, size = type_size(&S->tccgen_vtop->type, &align);1071 int align, size = type_size(&vtop->type, &align);
1066 if (size) {1072 if (size) {
1067 S->tccgen_vtop->type.t = VT_PTR;1073 vtop->type.t = VT_PTR;
1068 gaddrof(S);1074 gaddrof();
1069 gv(S, RC_R(a[i] / 2));1075 gv(RC_R(a[i] / 2));
1070 arm64_ldrs(S, a[i] / 2, size);1076 arm64_ldrs(a[i] / 2, size);
1071 }1077 }
1072 }1078 }
1073 else1079 else
1074 gv(S, RC_R(a[i] / 2));1080 gv(RC_R(a[i] / 2));
1075 }1081 }
1076 else if (a[i] < 16)1082 else if (a[i] < 16)
1077 // struct replaced by pointer in register1083 // struct replaced by pointer in register
1078 arm64_spoff(S, a[i] / 2, a1[i]);1084 arm64_spoff(a[i] / 2, a1[i]);
1079 else if (a[i] < 32) {1085 else if (a[i] < 32) {
1080 // value in floating-point registers1086 // value in floating-point registers
1081 if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_STRUCT) {1087 if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
1082 uint32_t j, sz, n = arm64_hfa(&S->tccgen_vtop->type, &sz);1088 uint32_t j, sz, n = arm64_hfa(&vtop->type, &sz);
1083 S->tccgen_vtop->type.t = VT_PTR;1089 vtop->type.t = VT_PTR;
1084 gaddrof(S);1090 gaddrof();
1085 gv(S, RC_R30);1091 gv(RC_R30);
1086 for (j = 0; j < n; j++)1092 for (j = 0; j < n; j++)
1087 o(S, 0x3d4003c0 |1093 o(0x3d4003c0 |
1088 (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |1094 (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |
1089 (a[i] / 2 - 8 + j) |1095 (a[i] / 2 - 8 + j) |
1090 j << 10); // ldr ([sdq])(*),[x30,#(j * sz)]1096 j << 10); // ldr ([sdq])(*),[x30,#(j * sz)]
1091 }1097 }
1092 else1098 else
1093 gv(S, RC_F(a[i] / 2 - 8));1099 gv(RC_F(a[i] / 2 - 8));
1094 }1100 }
1095 }1101 }
1096 1102
1097 if ((return_type->t & VT_BTYPE) == VT_STRUCT) {1103 if ((return_type->t & VT_BTYPE) == VT_STRUCT) {
1098 if (a[0] == 1) {1104 if (a[0] == 1) {
1099 // indirect return: set x8 and discard the stack value1105 // indirect return: set x8 and discard the stack value
1100 gv(S, RC_R(8));1106 gv(RC_R(8));
1101 --S->tccgen_vtop;1107 --vtop;
1102 }1108 }
1103 else1109 else
1104 // return in registers: keep the address for after the call1110 // return in registers: keep the address for after the call
1105 vswap(S);1111 vswap();
1106 }1112 }
1107 1113
1108 save_regs(S, 0);1114 save_regs(0);
1109 arm64_gen_bl_or_b(S, 0);1115 arm64_gen_bl_or_b(0);
1110 --S->tccgen_vtop;1116 --vtop;
1111 if (stack & 0xfff)1117 if (stack & 0xfff)
1112 o(S, 0x910003ff | (stack & 0xfff) << 10); // add sp,sp,#(n)1118 o(0x910003ff | (stack & 0xfff) << 10); // add sp,sp,#(n)
1113 if (stack >> 12)1119 if (stack >> 12)
1114 o(S, 0x914003ff | (stack >> 12) << 10);1120 o(0x914003ff | (stack >> 12) << 10);
1115 1121
1116 {1122 {
1117 int rt = return_type->t;1123 int rt = return_type->t;
1118 int bt = rt & VT_BTYPE;1124 int bt = rt & VT_BTYPE;
1119 if (bt == VT_STRUCT && !(a[0] & 1)) {1125 if (bt == VT_STRUCT && !(a[0] & 1)) {
1120 // A struct was returned in registers, so write it out:1126 // A struct was returned in registers, so write it out:
1121 gv(S, RC_R(8));1127 gv(RC_R(8));
1122 --S->tccgen_vtop;1128 --vtop;
1123 if (a[0] == 0) {1129 if (a[0] == 0) {
1124 int align, size = type_size(return_type, &align);1130 int align, size = type_size(return_type, &align);
1125 assert(size <= 16);1131 assert(size <= 16);
1126 if (size > 8)1132 if (size > 8)
1127 o(S, 0xa9000500); // stp x0,x1,[x8]1133 o(0xa9000500); // stp x0,x1,[x8]
1128 else if (size)1134 else if (size)
1129 arm64_strx(S, size > 4 ? 3 : size > 2 ? 2 : size > 1, 0, 8, 0);1135 arm64_strx(size > 4 ? 3 : size > 2 ? 2 : size > 1, 0, 8, 0);
1130 1136
1131 }1137 }
1132 else if (a[0] == 16) {1138 else if (a[0] == 16) {
1133 uint32_t j, sz, n = arm64_hfa(return_type, &sz);1139 uint32_t j, sz, n = arm64_hfa(return_type, &sz);
1134 for (j = 0; j < n; j++)1140 for (j = 0; j < n; j++)
1135 o(S, 0x3d000100 |1141 o(0x3d000100 |
1136 (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |1142 (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |
1137 (a[i] / 2 - 8 + j) |1143 (a[i] / 2 - 8 + j) |
1138 j << 10); // str ([sdq])(*),[x8,#(j * sz)]1144 j << 10); // str ([sdq])(*),[x8,#(j * sz)]
@@ -1140,9 +1146,9 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args) · 1 unmodified line
1140 }1146 }
1141 }1147 }
1142 1148
1143 tcc_free(S, a1);1149 tcc_free(a1);
1144 tcc_free(S, a);1150 tcc_free(a);
1145 tcc_free(S, t);1151 tcc_free(t);
1146}1152}
1147 1153
1148static unsigned long arm64_func_va_list_stack;1154static unsigned long arm64_func_va_list_stack;
@@ -1150,7 +1156,7 @@ static int arm64_func_va_list_gr_offs; · 1 unmodified line
1150static int arm64_func_va_list_vr_offs;1156static int arm64_func_va_list_vr_offs;
1151static int arm64_func_sub_sp_offset;1157static int arm64_func_sub_sp_offset;
1152 1158
1153ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym)1159ST_FUNC void gfunc_prolog(Sym *func_sym)
1154{1160{
1155 CType *func_type = &func_sym->type;1161 CType *func_type = &func_sym->type;
1156 int n = 0;1162 int n = 0;
@@ -1159,28 +1165,28 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym) · 2 unmodified lines
1159 CType **t;1165 CType **t;
1160 unsigned long *a;1166 unsigned long *a;
1161 1167
1162 S->tccgen_func_vc = 144; // offset of where x8 is stored1168 func_vc = 144; // offset of where x8 is stored
1163 1169
1164 for (sym = func_type->ref; sym; sym = sym->next)1170 for (sym = func_type->ref; sym; sym = sym->next)
1165 ++n;1171 ++n;
1166 t = n ? tcc_malloc(S, n * sizeof(*t)) : NULL;1172 t = n ? tcc_malloc(n * sizeof(*t)) : NULL;
1167 a = n ? tcc_malloc(S, n * sizeof(*a)) : NULL;1173 a = n ? tcc_malloc(n * sizeof(*a)) : NULL;
1168 1174
1169 for (sym = func_type->ref; sym; sym = sym->next)1175 for (sym = func_type->ref; sym; sym = sym->next)
1170 t[i++] = &sym->type;1176 t[i++] = &sym->type;
1171 1177
1172 arm64_func_va_list_stack = arm64_pcs(n - 1, t, a);1178 arm64_func_va_list_stack = arm64_pcs(n - 1, t, a);
1173 1179
1174 o(S, 0xa9b27bfd); // stp x29,x30,[sp,#-224]!1180 o(0xa9b27bfd); // stp x29,x30,[sp,#-224]!
1175 o(S, 0xad0087e0); // stp q0,q1,[sp,#16]1181 o(0xad0087e0); // stp q0,q1,[sp,#16]
1176 o(S, 0xad018fe2); // stp q2,q3,[sp,#48]1182 o(0xad018fe2); // stp q2,q3,[sp,#48]
1177 o(S, 0xad0297e4); // stp q4,q5,[sp,#80]1183 o(0xad0297e4); // stp q4,q5,[sp,#80]
1178 o(S, 0xad039fe6); // stp q6,q7,[sp,#112]1184 o(0xad039fe6); // stp q6,q7,[sp,#112]
1179 o(S, 0xa90923e8); // stp x8,x8,[sp,#144]1185 o(0xa90923e8); // stp x8,x8,[sp,#144]
1180 o(S, 0xa90a07e0); // stp x0,x1,[sp,#160]1186 o(0xa90a07e0); // stp x0,x1,[sp,#160]
1181 o(S, 0xa90b0fe2); // stp x2,x3,[sp,#176]1187 o(0xa90b0fe2); // stp x2,x3,[sp,#176]
1182 o(S, 0xa90c17e4); // stp x4,x5,[sp,#192]1188 o(0xa90c17e4); // stp x4,x5,[sp,#192]
1183 o(S, 0xa90d1fe6); // stp x6,x7,[sp,#208]1189 o(0xa90d1fe6); // stp x6,x7,[sp,#208]
1184 1190
1185 arm64_func_va_list_gr_offs = -64;1191 arm64_func_va_list_gr_offs = -64;
1186 arm64_func_va_list_vr_offs = -128;1192 arm64_func_va_list_vr_offs = -128;
@@ -1189,7 +1195,7 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym) · 2 unmodified lines
1189 int off = (a[i] < 16 ? 160 + a[i] / 2 * 8 :1195 int off = (a[i] < 16 ? 160 + a[i] / 2 * 8 :
1190 a[i] < 32 ? 16 + (a[i] - 16) / 2 * 16 :1196 a[i] < 32 ? 16 + (a[i] - 16) / 2 * 16 :
1191 224 + ((a[i] - 32) >> 1 << 1));1197 224 + ((a[i] - 32) >> 1 << 1));
1192 sym_push(S, sym->v & ~SYM_FIELD, &sym->type,1198 sym_push(sym->v & ~SYM_FIELD, &sym->type,
1193 (a[i] & 1 ? VT_LLOCAL : VT_LOCAL) | VT_LVAL,1199 (a[i] & 1 ? VT_LLOCAL : VT_LOCAL) | VT_LVAL,
1194 off);1200 off);
1195 1201
@@ -1209,65 +1215,65 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym) · 13 unmodified lines
1209 uint32_t j, sz, k = arm64_hfa(&sym->type, &sz);1215 uint32_t j, sz, k = arm64_hfa(&sym->type, &sz);
1210 if (sz < 16)1216 if (sz < 16)
1211 for (j = 0; j < k; j++) {1217 for (j = 0; j < k; j++) {
1212 o(S, 0x3d0003e0 | -(sz & 8) << 27 | (sz & 4) << 29 |1218 o(0x3d0003e0 | -(sz & 8) << 27 | (sz & 4) << 29 |
1213 ((a[i] - 16) / 2 + j) | (off / sz + j) << 10);1219 ((a[i] - 16) / 2 + j) | (off / sz + j) << 10);
1214 // str ([sdq])(*),[sp,#(j * sz)]1220 // str ([sdq])(*),[sp,#(j * sz)]
1215 }1221 }
1216 }1222 }
1217 }1223 }
1218 1224
1219 tcc_free(S, a);1225 tcc_free(a);
1220 tcc_free(S, t);1226 tcc_free(t);
1221 1227
1222 o(S, 0x910003fd); // mov x29,sp1228 o(0x910003fd); // mov x29,sp
1223 arm64_func_sub_sp_offset = S->tccgen_ind;1229 arm64_func_sub_sp_offset = ind;
1224 // In gfunc_epilog these will be replaced with code to decrement SP:1230 // In gfunc_epilog these will be replaced with code to decrement SP:
1225 o(S, 0xd503201f); // nop1231 o(0xd503201f); // nop
1226 o(S, 0xd503201f); // nop1232 o(0xd503201f); // nop
1227 S->tccgen_loc = 0;1233 loc = 0;
1228#ifdef CONFIG_TCC_BCHECK1234#ifdef CONFIG_TCC_BCHECK
1229 if (S->do_bounds_check)1235 if (tcc_state->do_bounds_check)
1230 gen_bounds_prolog(S);1236 gen_bounds_prolog();
1231#endif1237#endif
1232}1238}
1233 1239
1234ST_FUNC void gen_va_start(TCCState *S)1240ST_FUNC void gen_va_start(void)
1235{1241{
1236 int r;1242 int r;
1237 --S->tccgen_vtop; // we don't need the "arg"1243 --vtop; // we don't need the "arg"
1238 gaddrof(S);1244 gaddrof();
1239 r = intr(S, gv(S, RC_INT));1245 r = intr(gv(RC_INT));
1240 1246
1241 if (arm64_func_va_list_stack) {1247 if (arm64_func_va_list_stack) {
1242 //xx could use add (immediate) here1248 //xx could use add (immediate) here
1243 arm64_movimm(S, 30, arm64_func_va_list_stack + 224);1249 arm64_movimm(30, arm64_func_va_list_stack + 224);
1244 o(S, 0x8b1e03be); // add x30,x29,x301250 o(0x8b1e03be); // add x30,x29,x30
1245 }1251 }
1246 else1252 else
1247 o(S, 0x910383be); // add x30,x29,#2241253 o(0x910383be); // add x30,x29,#224
1248 o(S, 0xf900001e | r << 5); // str x30,[x(r)]1254 o(0xf900001e | r << 5); // str x30,[x(r)]
1249 1255
1250 if (arm64_func_va_list_gr_offs) {1256 if (arm64_func_va_list_gr_offs) {
1251 if (arm64_func_va_list_stack)1257 if (arm64_func_va_list_stack)
1252 o(S, 0x910383be); // add x30,x29,#2241258 o(0x910383be); // add x30,x29,#224
1253 o(S, 0xf900041e | r << 5); // str x30,[x(r),#8]1259 o(0xf900041e | r << 5); // str x30,[x(r),#8]
1254 }1260 }
1255 1261
1256 if (arm64_func_va_list_vr_offs) {1262 if (arm64_func_va_list_vr_offs) {
1257 o(S, 0x910243be); // add x30,x29,#1441263 o(0x910243be); // add x30,x29,#144
1258 o(S, 0xf900081e | r << 5); // str x30,[x(r),#16]1264 o(0xf900081e | r << 5); // str x30,[x(r),#16]
1259 }1265 }
1260 1266
1261 arm64_movimm(S, 30, arm64_func_va_list_gr_offs);1267 arm64_movimm(30, arm64_func_va_list_gr_offs);
1262 o(S, 0xb900181e | r << 5); // str w30,[x(r),#24]1268 o(0xb900181e | r << 5); // str w30,[x(r),#24]
1263 1269
1264 arm64_movimm(S, 30, arm64_func_va_list_vr_offs);1270 arm64_movimm(30, arm64_func_va_list_vr_offs);
1265 o(S, 0xb9001c1e | r << 5); // str w30,[x(r),#28]1271 o(0xb9001c1e | r << 5); // str w30,[x(r),#28]
1266 1272
1267 --S->tccgen_vtop;1273 --vtop;
1268}1274}
1269 1275
1270ST_FUNC void gen_va_arg(TCCState *S, CType *t)1276ST_FUNC void gen_va_arg(CType *t)
1271{1277{
1272 int align, size = type_size(t, &align);1278 int align, size = type_size(t, &align);
1273 unsigned fsize, hfa = arm64_hfa(t, &fsize);1279 unsigned fsize, hfa = arm64_hfa(t, &fsize);
@@ -1278,69 +1284,69 @@ ST_FUNC void gen_va_arg(TCCState *S, CType *t) · 4 unmodified lines
1278 fsize = size;1284 fsize = size;
1279 }1285 }
1280 1286
1281 gaddrof(S);1287 gaddrof();
1282 r0 = intr(S, gv(S, RC_INT));1288 r0 = intr(gv(RC_INT));
1283 r1 = get_reg(S, RC_INT);1289 r1 = get_reg(RC_INT);
1284 S->tccgen_vtop[0].r = r1 | VT_LVAL;1290 vtop[0].r = r1 | VT_LVAL;
1285 r1 = intr(S, r1);1291 r1 = intr(r1);
1286 1292
1287 if (!hfa) {1293 if (!hfa) {
1288 uint32_t n = size > 16 ? 8 : (size + 7) & -8;1294 uint32_t n = size > 16 ? 8 : (size + 7) & -8;
1289 o(S, 0xb940181e | r0 << 5); // ldr w30,[x(r0),#24] // __gr_offs1295 o(0xb940181e | r0 << 5); // ldr w30,[x(r0),#24] // __gr_offs
1290 if (align == 16) {1296 if (align == 16) {
1291 assert(0); // this path untested but needed for __uint128_t1297 assert(0); // this path untested but needed for __uint128_t
1292 o(S, 0x11003fde); // add w30,w30,#151298 o(0x11003fde); // add w30,w30,#15
1293 o(S, 0x121c6fde); // and w30,w30,#-161299 o(0x121c6fde); // and w30,w30,#-16
1294 }1300 }
1295 o(S, 0x310003c0 | r1 | n << 10); // adds w(r1),w30,#(n)1301 o(0x310003c0 | r1 | n << 10); // adds w(r1),w30,#(n)
1296 o(S, 0x540000ad); // b.le .+201302 o(0x540000ad); // b.le .+20
1297 o(S, 0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack1303 o(0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack
1298 o(S, 0x9100001e | r1 << 5 | n << 10); // add x30,x(r1),#(n)1304 o(0x9100001e | r1 << 5 | n << 10); // add x30,x(r1),#(n)
1299 o(S, 0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack1305 o(0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack
1300 o(S, 0x14000004); // b .+161306 o(0x14000004); // b .+16
1301 o(S, 0xb9001800 | r1 | r0 << 5); // str w(r1),[x(r0),#24] // __gr_offs1307 o(0xb9001800 | r1 | r0 << 5); // str w(r1),[x(r0),#24] // __gr_offs
1302 o(S, 0xf9400400 | r1 | r0 << 5); // ldr x(r1),[x(r0),#8] // __gr_top1308 o(0xf9400400 | r1 | r0 << 5); // ldr x(r1),[x(r0),#8] // __gr_top
1303 o(S, 0x8b3ec000 | r1 | r1 << 5); // add x(r1),x(r1),w30,sxtw1309 o(0x8b3ec000 | r1 | r1 << 5); // add x(r1),x(r1),w30,sxtw
1304 if (size > 16)1310 if (size > 16)
1305 o(S, 0xf9400000 | r1 | r1 << 5); // ldr x(r1),[x(r1)]1311 o(0xf9400000 | r1 | r1 << 5); // ldr x(r1),[x(r1)]
1306 }1312 }
1307 else {1313 else {
1308 uint32_t rsz = hfa << 4;1314 uint32_t rsz = hfa << 4;
1309 uint32_t ssz = (size + 7) & -(uint32_t)8;1315 uint32_t ssz = (size + 7) & -(uint32_t)8;
1310 uint32_t b1, b2;1316 uint32_t b1, b2;
1311 o(S, 0xb9401c1e | r0 << 5); // ldr w30,[x(r0),#28] // __vr_offs1317 o(0xb9401c1e | r0 << 5); // ldr w30,[x(r0),#28] // __vr_offs
1312 o(S, 0x310003c0 | r1 | rsz << 10); // adds w(r1),w30,#(rsz)1318 o(0x310003c0 | r1 | rsz << 10); // adds w(r1),w30,#(rsz)
1313 b1 = S->tccgen_ind; o(S, 0x5400000d); // b.le lab11319 b1 = ind; o(0x5400000d); // b.le lab1
1314 o(S, 0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack1320 o(0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack
1315 if (fsize == 16) {1321 if (fsize == 16) {
1316 o(S, 0x91003c00 | r1 | r1 << 5); // add x(r1),x(r1),#151322 o(0x91003c00 | r1 | r1 << 5); // add x(r1),x(r1),#15
1317 o(S, 0x927cec00 | r1 | r1 << 5); // and x(r1),x(r1),#-161323 o(0x927cec00 | r1 | r1 << 5); // and x(r1),x(r1),#-16
1318 }1324 }
1319 o(S, 0x9100001e | r1 << 5 | ssz << 10); // add x30,x(r1),#(ssz)1325 o(0x9100001e | r1 << 5 | ssz << 10); // add x30,x(r1),#(ssz)
1320 o(S, 0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack1326 o(0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack
1321 b2 = S->tccgen_ind; o(S, 0x14000000); // b lab21327 b2 = ind; o(0x14000000); // b lab2
1322 // lab1:1328 // lab1:
1323 write32le(cur_text_section->data + b1, 0x5400000d | (S->tccgen_ind - b1) << 3);1329 write32le(cur_text_section->data + b1, 0x5400000d | (ind - b1) << 3);
1324 o(S, 0xb9001c00 | r1 | r0 << 5); // str w(r1),[x(r0),#28] // __vr_offs1330 o(0xb9001c00 | r1 | r0 << 5); // str w(r1),[x(r0),#28] // __vr_offs
1325 o(S, 0xf9400800 | r1 | r0 << 5); // ldr x(r1),[x(r0),#16] // __vr_top1331 o(0xf9400800 | r1 | r0 << 5); // ldr x(r1),[x(r0),#16] // __vr_top
1326 if (hfa == 1 || fsize == 16)1332 if (hfa == 1 || fsize == 16)
1327 o(S, 0x8b3ec000 | r1 | r1 << 5); // add x(r1),x(r1),w30,sxtw1333 o(0x8b3ec000 | r1 | r1 << 5); // add x(r1),x(r1),w30,sxtw
1328 else {1334 else {
1329 // We need to change the layout of this HFA.1335 // We need to change the layout of this HFA.
1330 // Get some space on the stack using global variable "loc":1336 // Get some space on the stack using global variable "loc":
1331 S->tccgen_loc = (S->tccgen_loc - size) & -(uint32_t)align;1337 loc = (loc - size) & -(uint32_t)align;
1332 o(S, 0x8b3ec000 | 30 | r1 << 5); // add x30,x(r1),w30,sxtw1338 o(0x8b3ec000 | 30 | r1 << 5); // add x30,x(r1),w30,sxtw
1333 arm64_movimm(S, r1, S->tccgen_loc);1339 arm64_movimm(r1, loc);
1334 o(S, 0x8b0003a0 | r1 | r1 << 16); // add x(r1),x29,x(r1)1340 o(0x8b0003a0 | r1 | r1 << 16); // add x(r1),x29,x(r1)
1335 o(S, 0x4c402bdc | (uint32_t)fsize << 7 |1341 o(0x4c402bdc | (uint32_t)fsize << 7 |
1336 (uint32_t)(hfa == 2) << 15 |1342 (uint32_t)(hfa == 2) << 15 |
1337 (uint32_t)(hfa == 3) << 14); // ld1 {v28.(4s|2d),...},[x30]1343 (uint32_t)(hfa == 3) << 14); // ld1 {v28.(4s|2d),...},[x30]
1338 o(S, 0x0d00801c | r1 << 5 | (fsize == 8) << 10 |1344 o(0x0d00801c | r1 << 5 | (fsize == 8) << 10 |
1339 (uint32_t)(hfa != 2) << 13 |1345 (uint32_t)(hfa != 2) << 13 |
1340 (uint32_t)(hfa != 3) << 21); // st(hfa) {v28.(s|d),...}[0],[x(r1)]1346 (uint32_t)(hfa != 3) << 21); // st(hfa) {v28.(s|d),...}[0],[x(r1)]
1341 }1347 }
1342 // lab2:1348 // lab2:
1343 write32le(cur_text_section->data + b2, 0x14000000 | (S->tccgen_ind - b2) >> 2);1349 write32le(cur_text_section->data + b2, 0x14000000 | (ind - b2) >> 2);
1344 }1350 }
1345}1351}
1346 1352
@@ -1350,7 +1356,7 @@ ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, · 3 unmodified lines
1350 return 0;1356 return 0;
1351}1357}
1352 1358
1353ST_FUNC void gfunc_return(TCCState *S, CType *func_type)1359ST_FUNC void gfunc_return(CType *func_type)
1354{1360{
1355 CType *t = func_type;1361 CType *t = func_type;
1356 unsigned long a;1362 unsigned long a;
@@ -1362,52 +1368,52 @@ ST_FUNC void gfunc_return(TCCState *S, CType *func_type) · 5 unmodified lines
1362 case 0:1368 case 0:
1363 if ((func_type->t & VT_BTYPE) == VT_STRUCT) {1369 if ((func_type->t & VT_BTYPE) == VT_STRUCT) {
1364 int align, size = type_size(func_type, &align);1370 int align, size = type_size(func_type, &align);
1365 gaddrof(S);1371 gaddrof();
1366 gv(S, RC_R(0));1372 gv(RC_R(0));
1367 arm64_ldrs(S, 0, size);1373 arm64_ldrs(0, size);
1368 }1374 }
1369 else1375 else
1370 gv(S, RC_IRET);1376 gv(RC_IRET);
1371 break;1377 break;
1372 case 1: {1378 case 1: {
1373 CType type = *func_type;1379 CType type = *func_type;
1374 mk_pointer(S, &type);1380 mk_pointer(&type);
1375 vset(S, &type, VT_LOCAL | VT_LVAL, S->tccgen_func_vc);1381 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
1376 indir(S);1382 indir();
1377 vswap(S);1383 vswap();
1378 vstore(S);1384 vstore();
1379 break;1385 break;
1380 }1386 }
1381 case 16:1387 case 16:
1382 if ((func_type->t & VT_BTYPE) == VT_STRUCT) {1388 if ((func_type->t & VT_BTYPE) == VT_STRUCT) {
1383 uint32_t j, sz, n = arm64_hfa(&S->tccgen_vtop->type, &sz);1389 uint32_t j, sz, n = arm64_hfa(&vtop->type, &sz);
1384 gaddrof(S);1390 gaddrof();
1385 gv(S, RC_R(0));1391 gv(RC_R(0));
1386 for (j = 0; j < n; j++)1392 for (j = 0; j < n; j++)
1387 o(S, 0x3d400000 |1393 o(0x3d400000 |
1388 (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |1394 (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |
1389 j | j << 10); // ldr ([sdq])(*),[x0,#(j * sz)]1395 j | j << 10); // ldr ([sdq])(*),[x0,#(j * sz)]
1390 }1396 }
1391 else1397 else
1392 gv(S, RC_FRET);1398 gv(RC_FRET);
1393 break;1399 break;
1394 default:1400 default:
1395 assert(0);1401 assert(0);
1396 }1402 }
1397 S->tccgen_vtop--;1403 vtop--;
1398}1404}
1399 1405
1400ST_FUNC void gfunc_epilog(TCCState *S)1406ST_FUNC void gfunc_epilog(void)
1401{1407{
1402#ifdef CONFIG_TCC_BCHECK1408#ifdef CONFIG_TCC_BCHECK
1403 if (S->do_bounds_check)1409 if (tcc_state->do_bounds_check)
1404 gen_bounds_epilog(S);1410 gen_bounds_epilog();
1405#endif1411#endif
1406 1412
1407 if (S->tccgen_loc) {1413 if (loc) {
1408 // Insert instructions to subtract size of stack frame from SP.1414 // Insert instructions to subtract size of stack frame from SP.
1409 unsigned char *ptr = cur_text_section->data + arm64_func_sub_sp_offset;1415 unsigned char *ptr = cur_text_section->data + arm64_func_sub_sp_offset;
1410 uint64_t diff = (-S->tccgen_loc + 15) & ~15;1416 uint64_t diff = (-loc + 15) & ~15;
1411 if (!(diff >> 24)) {1417 if (!(diff >> 24)) {
1412 if (diff & 0xfff) // sub sp,sp,#(diff & 0xfff)1418 if (diff & 0xfff) // sub sp,sp,#(diff & 0xfff)
1413 write32le(ptr, 0xd10003ff | (diff & 0xfff) << 10);1419 write32le(ptr, 0xd10003ff | (diff & 0xfff) << 10);
@@ -1433,40 +1439,40 @@ ST_FUNC void gfunc_epilog(TCCState *S) · 19 unmodified lines
1433 // sub sp,sp,x16,lsl #(j)1439 // sub sp,sp,x16,lsl #(j)
1434 }1440 }
1435 }1441 }
1436 o(S, 0x910003bf); // mov sp,x291442 o(0x910003bf); // mov sp,x29
1437 o(S, 0xa8ce7bfd); // ldp x29,x30,[sp],#2241443 o(0xa8ce7bfd); // ldp x29,x30,[sp],#224
1438 1444
1439 o(S, 0xd65f03c0); // ret1445 o(0xd65f03c0); // ret
1440}1446}
1441 1447
1442ST_FUNC void gen_fill_nops(TCCState *S, int bytes)1448ST_FUNC void gen_fill_nops(int bytes)
1443{1449{
1444 if ((bytes & 3))1450 if ((bytes & 3))
1445 tcc_error(S, "alignment of code section not multiple of 4");1451 tcc_error("alignment of code section not multiple of 4");
1446 while (bytes > 0) {1452 while (bytes > 0) {
1447 o(S, 0xd503201f); // nop1453 o(0xd503201f); // nop
1448 bytes -= 4;1454 bytes -= 4;
1449 }1455 }
1450}1456}
1451 1457
1452// Generate forward branch to label:1458// Generate forward branch to label:
1453ST_FUNC int gjmp(TCCState *S, int t)1459ST_FUNC int gjmp(int t)
1454{1460{
1455 int r = S->tccgen_ind;1461 int r = ind;
1456 if (S->tccgen_nocode_wanted)1462 if (nocode_wanted)
1457 return t;1463 return t;
1458 o(S, t);1464 o(t);
1459 return r;1465 return r;
1460}1466}
1461 1467
1462// Generate branch to known address:1468// Generate branch to known address:
1463ST_FUNC void gjmp_addr(TCCState *S, int a)1469ST_FUNC void gjmp_addr(int a)
1464{1470{
1465 assert(a - S->tccgen_ind + 0x8000000 < 0x10000000);1471 assert(a - ind + 0x8000000 < 0x10000000);
1466 o(S, 0x14000000 | ((a - S->tccgen_ind) >> 2 & 0x3ffffff));1472 o(0x14000000 | ((a - ind) >> 2 & 0x3ffffff));
1467}1473}
1468 1474
1469ST_FUNC int gjmp_append(TCCState *S, int n, int t)1475ST_FUNC int gjmp_append(int n, int t)
1470{1476{
1471 void *p;1477 void *p;
1472 /* insert vtop->c jump list in t */1478 /* insert vtop->c jump list in t */
@@ -1480,61 +1486,61 @@ ST_FUNC int gjmp_append(TCCState *S, int n, int t) · 7 unmodified lines
1480 return t;1486 return t;
1481}1487}
1482 1488
1483void arm64_vset_VT_CMP(TCCState *S, int op)1489void arm64_vset_VT_CMP(int op)
1484{1490{
1485 if (op >= TOK_ULT && op <= TOK_GT) {1491 if (op >= TOK_ULT && op <= TOK_GT) {
1486 S->tccgen_vtop->cmp_r = S->tccgen_vtop->r;1492 vtop->cmp_r = vtop->r;
1487 vset_VT_CMP(S, 0x80);1493 vset_VT_CMP(0x80);
1488 }1494 }
1489}1495}
1490 1496
1491static void arm64_gen_opil(TCCState *S, int op, uint32_t l);1497static void arm64_gen_opil(int op, uint32_t l);
1492 1498
1493static void arm64_load_cmp(TCCState *S, int r, SValue *sv)1499static void arm64_load_cmp(int r, SValue *sv)
1494{1500{
1495 sv->r = sv->cmp_r;1501 sv->r = sv->cmp_r;
1496 if (sv->c.i & 1) {1502 if (sv->c.i & 1) {
1497 vpushi(S, 1);1503 vpushi(1);
1498 arm64_gen_opil(S, '^', 0);1504 arm64_gen_opil('^', 0);
1499 }1505 }
1500 if (r != sv->r) {1506 if (r != sv->r) {
1501 load(S, r, sv);1507 load(r, sv);
1502 sv->r = r;1508 sv->r = r;
1503 }1509 }
1504}1510}
1505 1511
1506ST_FUNC int gjmp_cond(TCCState *S, int op, int t)1512ST_FUNC int gjmp_cond(int op, int t)
1507{1513{
1508 int bt = S->tccgen_vtop->type.t & VT_BTYPE;1514 int bt = vtop->type.t & VT_BTYPE;
1509 1515
1510 int inv = op & 1;1516 int inv = op & 1;
1511 S->tccgen_vtop->r = S->tccgen_vtop->cmp_r;1517 vtop->r = vtop->cmp_r;
1512 1518
1513 if (bt == VT_LDOUBLE) {1519 if (bt == VT_LDOUBLE) {
1514 uint32_t a, b, f = fltr(gv(S, RC_FLOAT));1520 uint32_t a, b, f = fltr(gv(RC_FLOAT));
1515 a = get_reg(S, RC_INT);1521 a = get_reg(RC_INT);
1516 vpushi(S, 0);1522 vpushi(0);
1517 S->tccgen_vtop[0].r = a;1523 vtop[0].r = a;
1518 b = get_reg(S, RC_INT);1524 b = get_reg(RC_INT);
1519 a = intr(S, a);1525 a = intr(a);
1520 b = intr(S, b);1526 b = intr(b);
1521 o(S, 0x4e083c00 | a | f << 5); // mov x(a),v(f).d[0]1527 o(0x4e083c00 | a | f << 5); // mov x(a),v(f).d[0]
1522 o(S, 0x4e183c00 | b | f << 5); // mov x(b),v(f).d[1]1528 o(0x4e183c00 | b | f << 5); // mov x(b),v(f).d[1]
1523 o(S, 0xaa000400 | a | a << 5 | b << 16); // orr x(a),x(a),x(b),lsl #11529 o(0xaa000400 | a | a << 5 | b << 16); // orr x(a),x(a),x(b),lsl #1
1524 o(S, 0xb4000040 | a | !!inv << 24); // cbz/cbnz x(a),.+81530 o(0xb4000040 | a | !!inv << 24); // cbz/cbnz x(a),.+8
1525 --S->tccgen_vtop;1531 --vtop;
1526 }1532 }
1527 else if (bt == VT_FLOAT || bt == VT_DOUBLE) {1533 else if (bt == VT_FLOAT || bt == VT_DOUBLE) {
1528 uint32_t a = fltr(gv(S, RC_FLOAT));1534 uint32_t a = fltr(gv(RC_FLOAT));
1529 o(S, 0x1e202008 | a << 5 | (bt != VT_FLOAT) << 22); // fcmp1535 o(0x1e202008 | a << 5 | (bt != VT_FLOAT) << 22); // fcmp
1530 o(S, 0x54000040 | !!inv); // b.eq/b.ne .+81536 o(0x54000040 | !!inv); // b.eq/b.ne .+8
1531 }1537 }
1532 else {1538 else {
1533 uint32_t ll = (bt == VT_PTR || bt == VT_LLONG);1539 uint32_t ll = (bt == VT_PTR || bt == VT_LLONG);
1534 uint32_t a = intr(S, gv(S, RC_INT));1540 uint32_t a = intr(gv(RC_INT));
1535 o(S, 0x34000040 | a | !!inv << 24 | ll << 31); // cbz/cbnz wA,.+81541 o(0x34000040 | a | !!inv << 24 | ll << 31); // cbz/cbnz wA,.+8
1536 }1542 }
1537 return gjmp(S, t);1543 return gjmp(t);
1538}1544}
1539 1545
1540static int arm64_iconst(uint64_t *val, SValue *sv)1546static int arm64_iconst(uint64_t *val, SValue *sv)
@@ -1551,7 +1557,7 @@ static int arm64_iconst(uint64_t *val, SValue *sv) · 10 unmodified lines
1551 return 1;1557 return 1;
1552}1558}
1553 1559
1554static int arm64_gen_opic(TCCState *S, int op, uint32_t l, int rev, uint64_t val,1560static int arm64_gen_opic(int op, uint32_t l, int rev, uint64_t val,
1555 uint32_t x, uint32_t a)1561 uint32_t x, uint32_t a)
1556{1562{
1557 if (op == '-' && !rev) {1563 if (op == '-' && !rev) {
@@ -1567,30 +1573,30 @@ static int arm64_gen_opic(TCCState *S, int op, uint32_t l, int rev, uint64_t val · 9 unmodified lines
1567 val = s ? -val : val;1573 val = s ? -val : val;
1568 val = l ? val : (uint32_t)val;1574 val = l ? val : (uint32_t)val;
1569 if (!(val & ~(uint64_t)0xfff))1575 if (!(val & ~(uint64_t)0xfff))
1570 o(S, 0x11000000 | l << 31 | s << 30 | x | a << 5 | val << 10);1576 o(0x11000000 | l << 31 | s << 30 | x | a << 5 | val << 10);
1571 else if (!(val & ~(uint64_t)0xfff000))1577 else if (!(val & ~(uint64_t)0xfff000))
1572 o(S, 0x11400000 | l << 31 | s << 30 | x | a << 5 | val >> 12 << 10);1578 o(0x11400000 | l << 31 | s << 30 | x | a << 5 | val >> 12 << 10);
1573 else {1579 else {
1574 arm64_movimm(S, 30, val); // use x301580 arm64_movimm(30, val); // use x30
1575 o(S, 0x0b1e0000 | l << 31 | s << 30 | x | a << 5);1581 o(0x0b1e0000 | l << 31 | s << 30 | x | a << 5);
1576 }1582 }
1577 return 1;1583 return 1;
1578 }1584 }
1579 1585
1580 case '-':1586 case '-':
1581 if (!val)1587 if (!val)
1582 o(S, 0x4b0003e0 | l << 31 | x | a << 16); // neg1588 o(0x4b0003e0 | l << 31 | x | a << 16); // neg
1583 else if (val == (l ? (uint64_t)-1 : (uint32_t)-1))1589 else if (val == (l ? (uint64_t)-1 : (uint32_t)-1))
1584 o(S, 0x2a2003e0 | l << 31 | x | a << 16); // mvn1590 o(0x2a2003e0 | l << 31 | x | a << 16); // mvn
1585 else {1591 else {
1586 arm64_movimm(S, 30, val); // use x301592 arm64_movimm(30, val); // use x30
1587 o(S, 0x4b0003c0 | l << 31 | x | a << 16); // sub1593 o(0x4b0003c0 | l << 31 | x | a << 16); // sub
1588 }1594 }
1589 return 1;1595 return 1;
1590 1596
1591 case '^':1597 case '^':
1592 if (val == -1 || (val == 0xffffffff && !l)) {1598 if (val == -1 || (val == 0xffffffff && !l)) {
1593 o(S, 0x2a2003e0 | l << 31 | x | a << 16); // mvn1599 o(0x2a2003e0 | l << 31 | x | a << 16); // mvn
1594 return 1;1600 return 1;
1595 }1601 }
1596 // fall through1602 // fall through
@@ -1599,7 +1605,7 @@ static int arm64_gen_opic(TCCState *S, int op, uint32_t l, int rev, uint64_t val · 2 unmodified lines
1599 int e = arm64_encode_bimm64(l ? val : val | val << 32);1605 int e = arm64_encode_bimm64(l ? val : val | val << 32);
1600 if (e < 0)1606 if (e < 0)
1601 return 0;1607 return 0;
1602 o(S, (op == '&' ? 0x12000000 :1608 o((op == '&' ? 0x12000000 :
1603 op == '|' ? 0x32000000 : 0x52000000) |1609 op == '|' ? 0x32000000 : 0x52000000) |
1604 l << 31 | x | a << 5 | (uint32_t)e << 10);1610 l << 31 | x | a << 5 | (uint32_t)e << 10);
1605 return 1;1611 return 1;
@@ -1614,14 +1620,14 @@ static int arm64_gen_opic(TCCState *S, int op, uint32_t l, int rev, uint64_t val · 8 unmodified lines
1614 return 0;1620 return 0;
1615 if (!val) {1621 if (!val) {
1616 // tcc_warning("shift count >= width of type");1622 // tcc_warning("shift count >= width of type");
1617 o(S, 0x2a0003e0 | l << 31 | a << 16);1623 o(0x2a0003e0 | l << 31 | a << 16);
1618 return 1;1624 return 1;
1619 }1625 }
1620 else if (op == TOK_SHL)1626 else if (op == TOK_SHL)
1621 o(S, 0x53000000 | l << 31 | l << 22 | x | a << 5 |1627 o(0x53000000 | l << 31 | l << 22 | x | a << 5 |
1622 (n - val) << 16 | (n - 1 - val) << 10); // lsl1628 (n - val) << 16 | (n - 1 - val) << 10); // lsl
1623 else1629 else
1624 o(S, 0x13000000 | (op == TOK_SHR) << 30 | l << 31 | l << 22 |1630 o(0x13000000 | (op == TOK_SHR) << 30 | l << 31 | l << 22 |
1625 x | a << 5 | val << 16 | (n - 1) << 10); // lsr/asr1631 x | a << 5 | val << 16 | (n - 1) << 10); // lsr/asr
1626 return 1;1632 return 1;
1627 }1633 }
@@ -1630,7 +1636,7 @@ static int arm64_gen_opic(TCCState *S, int op, uint32_t l, int rev, uint64_t val · 2 unmodified lines
1630 return 0;1636 return 0;
1631}1637}
1632 1638
1633static void arm64_gen_opil(TCCState *S, int op, uint32_t l)1639static void arm64_gen_opil(int op, uint32_t l)
1634{1640{
1635 uint32_t x, a, b;1641 uint32_t x, a, b;
1636 1642
@@ -1639,122 +1645,122 @@ static void arm64_gen_opil(TCCState *S, int op, uint32_t l) · 2 unmodified lines
1639 uint64_t val;1645 uint64_t val;
1640 int rev = 1;1646 int rev = 1;
1641 1647
1642 if (arm64_iconst(0, &S->tccgen_vtop[0])) {1648 if (arm64_iconst(0, &vtop[0])) {
1643 vswap(S);1649 vswap();
1644 rev = 0;1650 rev = 0;
1645 }1651 }
1646 if (arm64_iconst(&val, &S->tccgen_vtop[-1])) {1652 if (arm64_iconst(&val, &vtop[-1])) {
1647 gv(S, RC_INT);1653 gv(RC_INT);
1648 a = intr(S, S->tccgen_vtop[0].r);1654 a = intr(vtop[0].r);
1649 --S->tccgen_vtop;1655 --vtop;
1650 x = get_reg(S, RC_INT);1656 x = get_reg(RC_INT);
1651 ++S->tccgen_vtop;1657 ++vtop;
1652 if (arm64_gen_opic(S, op, l, rev, val, intr(S, x), a)) {1658 if (arm64_gen_opic(op, l, rev, val, intr(x), a)) {
1653 S->tccgen_vtop[0].r = x;1659 vtop[0].r = x;
1654 vswap(S);1660 vswap();
1655 --S->tccgen_vtop;1661 --vtop;
1656 return;1662 return;
1657 }1663 }
1658 }1664 }
1659 if (!rev)1665 if (!rev)
1660 vswap(S);1666 vswap();
1661 }1667 }
1662 1668
1663 gv2(S, RC_INT, RC_INT);1669 gv2(RC_INT, RC_INT);
1664 assert(S->tccgen_vtop[-1].r < VT_CONST && S->tccgen_vtop[0].r < VT_CONST);1670 assert(vtop[-1].r < VT_CONST && vtop[0].r < VT_CONST);
1665 a = intr(S, S->tccgen_vtop[-1].r);1671 a = intr(vtop[-1].r);
1666 b = intr(S, S->tccgen_vtop[0].r);1672 b = intr(vtop[0].r);
1667 S->tccgen_vtop -= 2;1673 vtop -= 2;
1668 x = get_reg(S, RC_INT);1674 x = get_reg(RC_INT);
1669 ++S->tccgen_vtop;1675 ++vtop;
1670 S->tccgen_vtop[0].r = x;1676 vtop[0].r = x;
1671 x = intr(S, x);1677 x = intr(x);
1672 1678
1673 switch (op) {1679 switch (op) {
1674 case '%':1680 case '%':
1675 // Use x30 for quotient:1681 // Use x30 for quotient:
1676 o(S, 0x1ac00c00 | l << 31 | 30 | a << 5 | b << 16); // sdiv1682 o(0x1ac00c00 | l << 31 | 30 | a << 5 | b << 16); // sdiv
1677 o(S, 0x1b008000 | l << 31 | x | (uint32_t)30 << 5 |1683 o(0x1b008000 | l << 31 | x | (uint32_t)30 << 5 |
1678 b << 16 | a << 10); // msub1684 b << 16 | a << 10); // msub
1679 break;1685 break;
1680 case '&':1686 case '&':
1681 o(S, 0x0a000000 | l << 31 | x | a << 5 | b << 16); // and1687 o(0x0a000000 | l << 31 | x | a << 5 | b << 16); // and
1682 break;1688 break;
1683 case '*':1689 case '*':
1684 o(S, 0x1b007c00 | l << 31 | x | a << 5 | b << 16); // mul1690 o(0x1b007c00 | l << 31 | x | a << 5 | b << 16); // mul
1685 break;1691 break;
1686 case '+':1692 case '+':
1687 o(S, 0x0b000000 | l << 31 | x | a << 5 | b << 16); // add1693 o(0x0b000000 | l << 31 | x | a << 5 | b << 16); // add
1688 break;1694 break;
1689 case '-':1695 case '-':
1690 o(S, 0x4b000000 | l << 31 | x | a << 5 | b << 16); // sub1696 o(0x4b000000 | l << 31 | x | a << 5 | b << 16); // sub
1691 break;1697 break;
1692 case '/':1698 case '/':
1693 o(S, 0x1ac00c00 | l << 31 | x | a << 5 | b << 16); // sdiv1699 o(0x1ac00c00 | l << 31 | x | a << 5 | b << 16); // sdiv
1694 break;1700 break;
1695 case '^':1701 case '^':
1696 o(S, 0x4a000000 | l << 31 | x | a << 5 | b << 16); // eor1702 o(0x4a000000 | l << 31 | x | a << 5 | b << 16); // eor
1697 break;1703 break;
1698 case '|':1704 case '|':
1699 o(S, 0x2a000000 | l << 31 | x | a << 5 | b << 16); // orr1705 o(0x2a000000 | l << 31 | x | a << 5 | b << 16); // orr
1700 break;1706 break;
1701 case TOK_EQ:1707 case TOK_EQ:
1702 o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp1708 o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
1703 o(S, 0x1a9f17e0 | x); // cset wA,eq1709 o(0x1a9f17e0 | x); // cset wA,eq
1704 break;1710 break;
1705 case TOK_GE:1711 case TOK_GE:
1706 o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp1712 o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
1707 o(S, 0x1a9fb7e0 | x); // cset wA,ge1713 o(0x1a9fb7e0 | x); // cset wA,ge
1708 break;1714 break;
1709 case TOK_GT:1715 case TOK_GT:
1710 o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp1716 o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
1711 o(S, 0x1a9fd7e0 | x); // cset wA,gt1717 o(0x1a9fd7e0 | x); // cset wA,gt
1712 break;1718 break;
1713 case TOK_LE:1719 case TOK_LE:
1714 o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp1720 o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
1715 o(S, 0x1a9fc7e0 | x); // cset wA,le1721 o(0x1a9fc7e0 | x); // cset wA,le
1716 break;1722 break;
1717 case TOK_LT:1723 case TOK_LT:
1718 o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp1724 o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
1719 o(S, 0x1a9fa7e0 | x); // cset wA,lt1725 o(0x1a9fa7e0 | x); // cset wA,lt
1720 break;1726 break;
1721 case TOK_NE:1727 case TOK_NE:
1722 o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp1728 o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
1723 o(S, 0x1a9f07e0 | x); // cset wA,ne1729 o(0x1a9f07e0 | x); // cset wA,ne
1724 break;1730 break;
1725 case TOK_SAR:1731 case TOK_SAR:
1726 o(S, 0x1ac02800 | l << 31 | x | a << 5 | b << 16); // asr1732 o(0x1ac02800 | l << 31 | x | a << 5 | b << 16); // asr
1727 break;1733 break;
1728 case TOK_SHL:1734 case TOK_SHL:
1729 o(S, 0x1ac02000 | l << 31 | x | a << 5 | b << 16); // lsl1735 o(0x1ac02000 | l << 31 | x | a << 5 | b << 16); // lsl
1730 break;1736 break;
1731 case TOK_SHR:1737 case TOK_SHR:
1732 o(S, 0x1ac02400 | l << 31 | x | a << 5 | b << 16); // lsr1738 o(0x1ac02400 | l << 31 | x | a << 5 | b << 16); // lsr
1733 break;1739 break;
1734 case TOK_UDIV:1740 case TOK_UDIV:
1735 case TOK_PDIV:1741 case TOK_PDIV:
1736 o(S, 0x1ac00800 | l << 31 | x | a << 5 | b << 16); // udiv1742 o(0x1ac00800 | l << 31 | x | a << 5 | b << 16); // udiv
1737 break;1743 break;
1738 case TOK_UGE:1744 case TOK_UGE:
1739 o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp1745 o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
1740 o(S, 0x1a9f37e0 | x); // cset wA,cs1746 o(0x1a9f37e0 | x); // cset wA,cs
1741 break;1747 break;
1742 case TOK_UGT:1748 case TOK_UGT:
1743 o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp1749 o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
1744 o(S, 0x1a9f97e0 | x); // cset wA,hi1750 o(0x1a9f97e0 | x); // cset wA,hi
1745 break;1751 break;
1746 case TOK_ULT:1752 case TOK_ULT:
1747 o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp1753 o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
1748 o(S, 0x1a9f27e0 | x); // cset wA,cc1754 o(0x1a9f27e0 | x); // cset wA,cc
1749 break;1755 break;
1750 case TOK_ULE:1756 case TOK_ULE:
1751 o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp1757 o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
1752 o(S, 0x1a9f87e0 | x); // cset wA,ls1758 o(0x1a9f87e0 | x); // cset wA,ls
1753 break;1759 break;
1754 case TOK_UMOD:1760 case TOK_UMOD:
1755 // Use x30 for quotient:1761 // Use x30 for quotient:
1756 o(S, 0x1ac00800 | l << 31 | 30 | a << 5 | b << 16); // udiv1762 o(0x1ac00800 | l << 31 | 30 | a << 5 | b << 16); // udiv
1757 o(S, 0x1b008000 | l << 31 | x | (uint32_t)30 << 5 |1763 o(0x1b008000 | l << 31 | x | (uint32_t)30 << 5 |
1758 b << 16 | a << 10); // msub1764 b << 16 | a << 10); // msub
1759 break;1765 break;
1760 default:1766 default:
@@ -1762,24 +1768,24 @@ static void arm64_gen_opil(TCCState *S, int op, uint32_t l) · 1 unmodified line
1762 }1768 }
1763}1769}
1764 1770
1765ST_FUNC void gen_opi(TCCState *S, int op)1771ST_FUNC void gen_opi(int op)
1766{1772{
1767 arm64_gen_opil(S, op, 0);1773 arm64_gen_opil(op, 0);
1768 arm64_vset_VT_CMP(S, op);1774 arm64_vset_VT_CMP(op);
1769}1775}
1770 1776
1771ST_FUNC void gen_opl(TCCState* S, int op)1777ST_FUNC void gen_opl(int op)
1772{1778{
1773 arm64_gen_opil(S, op, 1);1779 arm64_gen_opil(op, 1);
1774 arm64_vset_VT_CMP(S, op);1780 arm64_vset_VT_CMP(op);
1775}1781}
1776 1782
1777ST_FUNC void gen_opf(TCCState *S, int op)1783ST_FUNC void gen_opf(int op)
1778{1784{
1779 uint32_t x, a, b, dbl;1785 uint32_t x, a, b, dbl;
1780 1786
1781 if (S->tccgen_vtop[0].type.t == VT_LDOUBLE) {1787 if (vtop[0].type.t == VT_LDOUBLE) {
1782 CType type = S->tccgen_vtop[0].type;1788 CType type = vtop[0].type;
1783 int func = 0;1789 int func = 0;
1784 int cond = -1;1790 int cond = -1;
1785 switch (op) {1791 switch (op) {
@@ -1795,162 +1801,162 @@ ST_FUNC void gen_opf(TCCState *S, int op) · 9 unmodified lines
1795 case TOK_GT: func = TOK___gttf2; cond = 13; break;1801 case TOK_GT: func = TOK___gttf2; cond = 13; break;
1796 default: assert(0); break;1802 default: assert(0); break;
1797 }1803 }
1798 vpush_helper_func(S, func);1804 vpush_helper_func(func);
1799 vrott(S, 3);1805 vrott(3);
1800 gfunc_call(S, 2);1806 gfunc_call(2);
1801 vpushi(S, 0);1807 vpushi(0);
1802 S->tccgen_vtop->r = cond < 0 ? REG_FRET : REG_IRET;1808 vtop->r = cond < 0 ? REG_FRET : REG_IRET;
1803 if (cond < 0)1809 if (cond < 0)
1804 S->tccgen_vtop->type = type;1810 vtop->type = type;
1805 else {1811 else {
1806 o(S, 0x7100001f); // cmp w0,#01812 o(0x7100001f); // cmp w0,#0
1807 o(S, 0x1a9f07e0 | (uint32_t)cond << 12); // cset w0,(cond)1813 o(0x1a9f07e0 | (uint32_t)cond << 12); // cset w0,(cond)
1808 }1814 }
1809 return;1815 return;
1810 }1816 }
1811 1817
1812 dbl = S->tccgen_vtop[0].type.t != VT_FLOAT;1818 dbl = vtop[0].type.t != VT_FLOAT;
1813 gv2(S, RC_FLOAT, RC_FLOAT);1819 gv2(RC_FLOAT, RC_FLOAT);
1814 assert(S->tccgen_vtop[-1].r < VT_CONST && S->tccgen_vtop[0].r < VT_CONST);1820 assert(vtop[-1].r < VT_CONST && vtop[0].r < VT_CONST);
1815 a = fltr(S->tccgen_vtop[-1].r);1821 a = fltr(vtop[-1].r);
1816 b = fltr(S->tccgen_vtop[0].r);1822 b = fltr(vtop[0].r);
1817 S->tccgen_vtop -= 2;1823 vtop -= 2;
1818 switch (op) {1824 switch (op) {
1819 case TOK_EQ: case TOK_NE:1825 case TOK_EQ: case TOK_NE:
1820 case TOK_LT: case TOK_GE: case TOK_LE: case TOK_GT:1826 case TOK_LT: case TOK_GE: case TOK_LE: case TOK_GT:
1821 x = get_reg(S, RC_INT);1827 x = get_reg(RC_INT);
1822 ++S->tccgen_vtop;1828 ++vtop;
1823 S->tccgen_vtop[0].r = x;1829 vtop[0].r = x;
1824 x = intr(S, x);1830 x = intr(x);
1825 break;1831 break;
1826 default:1832 default:
1827 x = get_reg(S, RC_FLOAT);1833 x = get_reg(RC_FLOAT);
1828 ++S->tccgen_vtop;1834 ++vtop;
1829 S->tccgen_vtop[0].r = x;1835 vtop[0].r = x;
1830 x = fltr(x);1836 x = fltr(x);
1831 break;1837 break;
1832 }1838 }
1833 1839
1834 switch (op) {1840 switch (op) {
1835 case '*':1841 case '*':
1836 o(S, 0x1e200800 | dbl << 22 | x | a << 5 | b << 16); // fmul1842 o(0x1e200800 | dbl << 22 | x | a << 5 | b << 16); // fmul
1837 break;1843 break;
1838 case '+':1844 case '+':
1839 o(S, 0x1e202800 | dbl << 22 | x | a << 5 | b << 16); // fadd1845 o(0x1e202800 | dbl << 22 | x | a << 5 | b << 16); // fadd
1840 break;1846 break;
1841 case '-':1847 case '-':
1842 o(S, 0x1e203800 | dbl << 22 | x | a << 5 | b << 16); // fsub1848 o(0x1e203800 | dbl << 22 | x | a << 5 | b << 16); // fsub
1843 break;1849 break;
1844 case '/':1850 case '/':
1845 o(S, 0x1e201800 | dbl << 22 | x | a << 5 | b << 16); // fdiv1851 o(0x1e201800 | dbl << 22 | x | a << 5 | b << 16); // fdiv
1846 break;1852 break;
1847 case TOK_EQ:1853 case TOK_EQ:
1848 o(S, 0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp1854 o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
1849 o(S, 0x1a9f17e0 | x); // cset w(x),eq1855 o(0x1a9f17e0 | x); // cset w(x),eq
1850 break;1856 break;
1851 case TOK_GE:1857 case TOK_GE:
1852 o(S, 0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp1858 o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
1853 o(S, 0x1a9fb7e0 | x); // cset w(x),ge1859 o(0x1a9fb7e0 | x); // cset w(x),ge
1854 break;1860 break;
1855 case TOK_GT:1861 case TOK_GT:
1856 o(S, 0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp1862 o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
1857 o(S, 0x1a9fd7e0 | x); // cset w(x),gt1863 o(0x1a9fd7e0 | x); // cset w(x),gt
1858 break;1864 break;
1859 case TOK_LE:1865 case TOK_LE:
1860 o(S, 0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp1866 o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
1861 o(S, 0x1a9f87e0 | x); // cset w(x),ls1867 o(0x1a9f87e0 | x); // cset w(x),ls
1862 break;1868 break;
1863 case TOK_LT:1869 case TOK_LT:
1864 o(S, 0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp1870 o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
1865 o(S, 0x1a9f57e0 | x); // cset w(x),mi1871 o(0x1a9f57e0 | x); // cset w(x),mi
1866 break;1872 break;
1867 case TOK_NE:1873 case TOK_NE:
1868 o(S, 0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp1874 o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
1869 o(S, 0x1a9f07e0 | x); // cset w(x),ne1875 o(0x1a9f07e0 | x); // cset w(x),ne
1870 break;1876 break;
1871 default:1877 default:
1872 assert(0);1878 assert(0);
1873 }1879 }
1874 arm64_vset_VT_CMP(S, op);1880 arm64_vset_VT_CMP(op);
1875}1881}
1876 1882
1877// Generate sign extension from 32 to 64 bits:1883// Generate sign extension from 32 to 64 bits:
1878ST_FUNC void gen_cvt_sxtw(TCCState *S)1884ST_FUNC void gen_cvt_sxtw(void)
1879{1885{
1880 uint32_t r = intr(S, gv(S, RC_INT));1886 uint32_t r = intr(gv(RC_INT));
1881 o(S, 0x93407c00 | r | r << 5); // sxtw x(r),w(r)1887 o(0x93407c00 | r | r << 5); // sxtw x(r),w(r)
1882}1888}
1883 1889
1884/* char/short to int conversion */1890/* char/short to int conversion */
1885ST_FUNC void gen_cvt_csti(TCCState *S, int t)1891ST_FUNC void gen_cvt_csti(int t)
1886{1892{
1887 int r = intr(S, gv(S, RC_INT));1893 int r = intr(gv(RC_INT));
1888 o(S, 0x13001c001894 o(0x13001c00
1889 | ((t & VT_BTYPE) == VT_SHORT) << 131895 | ((t & VT_BTYPE) == VT_SHORT) << 13
1890 | (uint32_t)!!(t & VT_UNSIGNED) << 301896 | (uint32_t)!!(t & VT_UNSIGNED) << 30
1891 | r | r << 5); // [su]xt[bh] w(r),w(r)1897 | r | r << 5); // [su]xt[bh] w(r),w(r)
1892}1898}
1893 1899
1894ST_FUNC void gen_cvt_itof(TCCState *S, int t)1900ST_FUNC void gen_cvt_itof(int t)
1895{1901{
1896 if (t == VT_LDOUBLE) {1902 if (t == VT_LDOUBLE) {
1897 int f = S->tccgen_vtop->type.t;1903 int f = vtop->type.t;
1898 int func = (f & VT_BTYPE) == VT_LLONG ?1904 int func = (f & VT_BTYPE) == VT_LLONG ?
1899 (f & VT_UNSIGNED ? TOK___floatunditf : TOK___floatditf) :1905 (f & VT_UNSIGNED ? TOK___floatunditf : TOK___floatditf) :
1900 (f & VT_UNSIGNED ? TOK___floatunsitf : TOK___floatsitf);1906 (f & VT_UNSIGNED ? TOK___floatunsitf : TOK___floatsitf);
1901 vpush_helper_func(S, func);1907 vpush_helper_func(func);
1902 vrott(S, 2);1908 vrott(2);
1903 gfunc_call(S, 1);1909 gfunc_call(1);
1904 vpushi(S, 0);1910 vpushi(0);
1905 S->tccgen_vtop->type.t = t;1911 vtop->type.t = t;
1906 S->tccgen_vtop->r = REG_FRET;1912 vtop->r = REG_FRET;
1907 return;1913 return;
1908 }1914 }
1909 else {1915 else {
1910 int d, n = intr(S, gv(S, RC_INT));1916 int d, n = intr(gv(RC_INT));
1911 int s = !(S->tccgen_vtop->type.t & VT_UNSIGNED);1917 int s = !(vtop->type.t & VT_UNSIGNED);
1912 uint32_t l = ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG);1918 uint32_t l = ((vtop->type.t & VT_BTYPE) == VT_LLONG);
1913 --S->tccgen_vtop;1919 --vtop;
1914 d = get_reg(S, RC_FLOAT);1920 d = get_reg(RC_FLOAT);
1915 ++S->tccgen_vtop;1921 ++vtop;
1916 S->tccgen_vtop[0].r = d;1922 vtop[0].r = d;
1917 o(S, 0x1e220000 | (uint32_t)!s << 16 |1923 o(0x1e220000 | (uint32_t)!s << 16 |
1918 (uint32_t)(t != VT_FLOAT) << 22 | fltr(d) |1924 (uint32_t)(t != VT_FLOAT) << 22 | fltr(d) |
1919 l << 31 | n << 5); // [us]cvtf [sd](d),[wx](n)1925 l << 31 | n << 5); // [us]cvtf [sd](d),[wx](n)
1920 }1926 }
1921}1927}
1922 1928
1923ST_FUNC void gen_cvt_ftoi(TCCState *S, int t)1929ST_FUNC void gen_cvt_ftoi(int t)
1924{1930{
1925 if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {1931 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
1926 int func = (t & VT_BTYPE) == VT_LLONG ?1932 int func = (t & VT_BTYPE) == VT_LLONG ?
1927 (t & VT_UNSIGNED ? TOK___fixunstfdi : TOK___fixtfdi) :1933 (t & VT_UNSIGNED ? TOK___fixunstfdi : TOK___fixtfdi) :
1928 (t & VT_UNSIGNED ? TOK___fixunstfsi : TOK___fixtfsi);1934 (t & VT_UNSIGNED ? TOK___fixunstfsi : TOK___fixtfsi);
1929 vpush_helper_func(S, func);1935 vpush_helper_func(func);
1930 vrott(S, 2);1936 vrott(2);
1931 gfunc_call(S, 1);1937 gfunc_call(1);
1932 vpushi(S, 0);1938 vpushi(0);
1933 S->tccgen_vtop->type.t = t;1939 vtop->type.t = t;
1934 S->tccgen_vtop->r = REG_IRET;1940 vtop->r = REG_IRET;
1935 return;1941 return;
1936 }1942 }
1937 else {1943 else {
1938 int d, n = fltr(gv(S, RC_FLOAT));1944 int d, n = fltr(gv(RC_FLOAT));
1939 uint32_t l = ((S->tccgen_vtop->type.t & VT_BTYPE) != VT_FLOAT);1945 uint32_t l = ((vtop->type.t & VT_BTYPE) != VT_FLOAT);
1940 --S->tccgen_vtop;1946 --vtop;
1941 d = get_reg(S, RC_INT);1947 d = get_reg(RC_INT);
1942 ++S->tccgen_vtop;1948 ++vtop;
1943 S->tccgen_vtop[0].r = d;1949 vtop[0].r = d;
1944 o(S, 0x1e380000 |1950 o(0x1e380000 |
1945 (uint32_t)!!(t & VT_UNSIGNED) << 16 |1951 (uint32_t)!!(t & VT_UNSIGNED) << 16 |
1946 (uint32_t)((t & VT_BTYPE) == VT_LLONG) << 31 | intr(S, d) |1952 (uint32_t)((t & VT_BTYPE) == VT_LLONG) << 31 | intr(d) |
1947 l << 22 | n << 5); // fcvtz[su] [wx](d),[sd](n)1953 l << 22 | n << 5); // fcvtz[su] [wx](d),[sd](n)
1948 }1954 }
1949}1955}
1950 1956
1951ST_FUNC void gen_cvt_ftof(TCCState *S, int t)1957ST_FUNC void gen_cvt_ftof(int t)
1952{1958{
1953 int f = S->tccgen_vtop[0].type.t & VT_BTYPE;1959 int f = vtop[0].type.t & VT_BTYPE;
1954 assert(t == VT_FLOAT || t == VT_DOUBLE || t == VT_LDOUBLE);1960 assert(t == VT_FLOAT || t == VT_DOUBLE || t == VT_LDOUBLE);
1955 assert(f == VT_FLOAT || f == VT_DOUBLE || f == VT_LDOUBLE);1961 assert(f == VT_FLOAT || f == VT_DOUBLE || f == VT_LDOUBLE);
1956 if (t == f)1962 if (t == f)
@@ -1960,142 +1966,142 @@ ST_FUNC void gen_cvt_ftof(TCCState *S, int t) · 3 unmodified lines
1960 int func = (t == VT_LDOUBLE) ?1966 int func = (t == VT_LDOUBLE) ?
1961 (f == VT_FLOAT ? TOK___extendsftf2 : TOK___extenddftf2) :1967 (f == VT_FLOAT ? TOK___extendsftf2 : TOK___extenddftf2) :
1962 (t == VT_FLOAT ? TOK___trunctfsf2 : TOK___trunctfdf2);1968 (t == VT_FLOAT ? TOK___trunctfsf2 : TOK___trunctfdf2);
1963 vpush_helper_func(S, func);1969 vpush_helper_func(func);
1964 vrott(S, 2);1970 vrott(2);
1965 gfunc_call(S, 1);1971 gfunc_call(1);
1966 vpushi(S, 0);1972 vpushi(0);
1967 S->tccgen_vtop->type.t = t;1973 vtop->type.t = t;
1968 S->tccgen_vtop->r = REG_FRET;1974 vtop->r = REG_FRET;
1969 }1975 }
1970 else {1976 else {
1971 int x, a;1977 int x, a;
1972 gv(S, RC_FLOAT);1978 gv(RC_FLOAT);
1973 assert(S->tccgen_vtop[0].r < VT_CONST);1979 assert(vtop[0].r < VT_CONST);
1974 a = fltr(S->tccgen_vtop[0].r);1980 a = fltr(vtop[0].r);
1975 --S->tccgen_vtop;1981 --vtop;
1976 x = get_reg(S, RC_FLOAT);1982 x = get_reg(RC_FLOAT);
1977 ++S->tccgen_vtop;1983 ++vtop;
1978 S->tccgen_vtop[0].r = x;1984 vtop[0].r = x;
1979 x = fltr(x);1985 x = fltr(x);
1980 1986
1981 if (f == VT_FLOAT)1987 if (f == VT_FLOAT)
1982 o(S, 0x1e22c000 | x | a << 5); // fcvt d(x),s(a)1988 o(0x1e22c000 | x | a << 5); // fcvt d(x),s(a)
1983 else1989 else
1984 o(S, 0x1e624000 | x | a << 5); // fcvt s(x),d(a)1990 o(0x1e624000 | x | a << 5); // fcvt s(x),d(a)
1985 }1991 }
1986}1992}
1987 1993
1988/* increment tcov counter */1994/* increment tcov counter */
1989ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv)1995ST_FUNC void gen_increment_tcov (SValue *sv)
1990{1996{
1991 int r1, r2;1997 int r1, r2;
1992 1998
1993 vpushv(S, sv);1999 vpushv(sv);
1994 S->tccgen_vtop->r = r1 = get_reg(S, RC_INT);2000 vtop->r = r1 = get_reg(RC_INT);
1995 r2 = get_reg(S, RC_INT);2001 r2 = get_reg(RC_INT);
1996 greloca(S, cur_text_section, sv->sym, S->tccgen_ind, R_AARCH64_ADR_GOT_PAGE, 0);2002 greloca(cur_text_section, sv->sym, ind, R_AARCH64_ADR_GOT_PAGE, 0);
1997 o(S, 0x90000000 | r1); // adrp r1, #sym2003 o(0x90000000 | r1); // adrp r1, #sym
1998 greloca(S, cur_text_section, sv->sym, S->tccgen_ind, R_AARCH64_LD64_GOT_LO12_NC, 0);2004 greloca(cur_text_section, sv->sym, ind, R_AARCH64_LD64_GOT_LO12_NC, 0);
1999 o(S, 0xf9400000 | r1 | (r1 << 5)); // ld xr,[xr, #sym]2005 o(0xf9400000 | r1 | (r1 << 5)); // ld xr,[xr, #sym]
2000 o(S, 0xf9400000 | (intr(S, r1)<<5) | intr(S, r2)); // ldr r2, [r1]2006 o(0xf9400000 | (intr(r1)<<5) | intr(r2)); // ldr r2, [r1]
2001 o(S, 0x91000400 | (intr(S, r2)<<5) | intr(S, r2)); // add r2, r2, #12007 o(0x91000400 | (intr(r2)<<5) | intr(r2)); // add r2, r2, #1
2002 o(S, 0xf9000000 | (intr(S, r1)<<5) | intr(S, r2)); // str r2, [r1]2008 o(0xf9000000 | (intr(r1)<<5) | intr(r2)); // str r2, [r1]
2003 vpop(S);2009 vpop();
2004}2010}
2005 2011
2006ST_FUNC void ggoto(TCCState *S)2012ST_FUNC void ggoto(void)
2007{2013{
2008 arm64_gen_bl_or_b(S, 1);2014 arm64_gen_bl_or_b(1);
2009 --S->tccgen_vtop;2015 --vtop;
2010}2016}
2011 2017
2012ST_FUNC void gen_clear_cache(TCCState *S)2018ST_FUNC void gen_clear_cache(void)
2013{2019{
2014 uint32_t beg, end, dsz, isz, p, lab1, b1;2020 uint32_t beg, end, dsz, isz, p, lab1, b1;
2015 gv2(S, RC_INT, RC_INT);2021 gv2(RC_INT, RC_INT);
2016 vpushi(S, 0);2022 vpushi(0);
2017 S->tccgen_vtop->r = get_reg(S, RC_INT);2023 vtop->r = get_reg(RC_INT);
2018 vpushi(S, 0);2024 vpushi(0);
2019 S->tccgen_vtop->r = get_reg(S, RC_INT);2025 vtop->r = get_reg(RC_INT);
2020 vpushi(S, 0);2026 vpushi(0);
2021 S->tccgen_vtop->r = get_reg(S, RC_INT);2027 vtop->r = get_reg(RC_INT);
2022 beg = intr(S, S->tccgen_vtop[-4].r); // x02028 beg = intr(vtop[-4].r); // x0
2023 end = intr(S, S->tccgen_vtop[-3].r); // x12029 end = intr(vtop[-3].r); // x1
2024 dsz = intr(S, S->tccgen_vtop[-2].r); // x22030 dsz = intr(vtop[-2].r); // x2
2025 isz = intr(S, S->tccgen_vtop[-1].r); // x32031 isz = intr(vtop[-1].r); // x3
2026 p = intr(S, S->tccgen_vtop[0].r); // x42032 p = intr(vtop[0].r); // x4
2027 S->tccgen_vtop -= 5;2033 vtop -= 5;
2028 2034
2029 o(S, 0xd53b0020 | isz); // mrs x(isz),ctr_el02035 o(0xd53b0020 | isz); // mrs x(isz),ctr_el0
2030 o(S, 0x52800080 | p); // mov w(p),#42036 o(0x52800080 | p); // mov w(p),#4
2031 o(S, 0x53104c00 | dsz | isz << 5); // ubfx w(dsz),w(isz),#16,#42037 o(0x53104c00 | dsz | isz << 5); // ubfx w(dsz),w(isz),#16,#4
2032 o(S, 0x1ac02000 | dsz | p << 5 | dsz << 16); // lsl w(dsz),w(p),w(dsz)2038 o(0x1ac02000 | dsz | p << 5 | dsz << 16); // lsl w(dsz),w(p),w(dsz)
2033 o(S, 0x12000c00 | isz | isz << 5); // and w(isz),w(isz),#152039 o(0x12000c00 | isz | isz << 5); // and w(isz),w(isz),#15
2034 o(S, 0x1ac02000 | isz | p << 5 | isz << 16); // lsl w(isz),w(p),w(isz)2040 o(0x1ac02000 | isz | p << 5 | isz << 16); // lsl w(isz),w(p),w(isz)
2035 o(S, 0x51000400 | p | dsz << 5); // sub w(p),w(dsz),#12041 o(0x51000400 | p | dsz << 5); // sub w(p),w(dsz),#1
2036 o(S, 0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p)2042 o(0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p)
2037 b1 = S->tccgen_ind; o(S, 0x14000000); // b2043 b1 = ind; o(0x14000000); // b
2038 lab1 = S->tccgen_ind;2044 lab1 = ind;
2039 o(S, 0xd50b7b20 | p); // dc cvau,x(p)2045 o(0xd50b7b20 | p); // dc cvau,x(p)
2040 o(S, 0x8b000000 | p | p << 5 | dsz << 16); // add x(p),x(p),x(dsz)2046 o(0x8b000000 | p | p << 5 | dsz << 16); // add x(p),x(p),x(dsz)
2041 write32le(cur_text_section->data + b1, 0x14000000 | (S->tccgen_ind - b1) >> 2);2047 write32le(cur_text_section->data + b1, 0x14000000 | (ind - b1) >> 2);
2042 o(S, 0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end)2048 o(0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end)
2043 o(S, 0x54ffffa3 | ((lab1 - S->tccgen_ind) << 3 & 0xffffe0)); // b.cc lab12049 o(0x54ffffa3 | ((lab1 - ind) << 3 & 0xffffe0)); // b.cc lab1
2044 o(S, 0xd5033b9f); // dsb ish2050 o(0xd5033b9f); // dsb ish
2045 o(S, 0x51000400 | p | isz << 5); // sub w(p),w(isz),#12051 o(0x51000400 | p | isz << 5); // sub w(p),w(isz),#1
2046 o(S, 0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p)2052 o(0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p)
2047 b1 = S->tccgen_ind; o(S, 0x14000000); // b2053 b1 = ind; o(0x14000000); // b
2048 lab1 = S->tccgen_ind;2054 lab1 = ind;
2049 o(S, 0xd50b7520 | p); // ic ivau,x(p)2055 o(0xd50b7520 | p); // ic ivau,x(p)
2050 o(S, 0x8b000000 | p | p << 5 | isz << 16); // add x(p),x(p),x(isz)2056 o(0x8b000000 | p | p << 5 | isz << 16); // add x(p),x(p),x(isz)
2051 write32le(cur_text_section->data + b1, 0x14000000 | (S->tccgen_ind - b1) >> 2);2057 write32le(cur_text_section->data + b1, 0x14000000 | (ind - b1) >> 2);
2052 o(S, 0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end)2058 o(0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end)
2053 o(S, 0x54ffffa3 | ((lab1 - S->tccgen_ind) << 3 & 0xffffe0)); // b.cc lab12059 o(0x54ffffa3 | ((lab1 - ind) << 3 & 0xffffe0)); // b.cc lab1
2054 o(S, 0xd5033b9f); // dsb ish2060 o(0xd5033b9f); // dsb ish
2055 o(S, 0xd5033fdf); // isb2061 o(0xd5033fdf); // isb
2056}2062}
2057 2063
2058ST_FUNC void gen_vla_sp_save(TCCState *S, int addr) {2064ST_FUNC void gen_vla_sp_save(int addr) {
2059 uint32_t r = intr(S, get_reg(S, RC_INT));2065 uint32_t r = intr(get_reg(RC_INT));
2060 o(S, 0x910003e0 | r); // mov x(r),sp2066 o(0x910003e0 | r); // mov x(r),sp
2061 arm64_strx(S, 3, r, 29, addr);2067 arm64_strx(3, r, 29, addr);
2062}2068}
2063 2069
2064ST_FUNC void gen_vla_sp_restore(TCCState *S, int addr) {2070ST_FUNC void gen_vla_sp_restore(int addr) {
2065 // Use x30 because this function can be called when there2071 // Use x30 because this function can be called when there
2066 // is a live return value in x0 but there is nothing on2072 // is a live return value in x0 but there is nothing on
2067 // the value stack to prevent get_reg from returning x0.2073 // the value stack to prevent get_reg from returning x0.
2068 uint32_t r = 30;2074 uint32_t r = 30;
2069 arm64_ldrx(S, 0, 3, r, 29, addr);2075 arm64_ldrx(0, 3, r, 29, addr);
2070 o(S, 0x9100001f | r << 5); // mov sp,x(r)2076 o(0x9100001f | r << 5); // mov sp,x(r)
2071}2077}
2072 2078
2073ST_FUNC void gen_vla_alloc(TCCState *S, CType *type, int align) {2079ST_FUNC void gen_vla_alloc(CType *type, int align) {
2074 uint32_t r;2080 uint32_t r;
2075#if defined(CONFIG_TCC_BCHECK)2081#if defined(CONFIG_TCC_BCHECK)
2076 if (S->do_bounds_check)2082 if (tcc_state->do_bounds_check)
2077 vpushv(S, S->tccgen_vtop);2083 vpushv(vtop);
2078#endif2084#endif
2079 r = intr(S, gv(S, RC_INT));2085 r = intr(gv(RC_INT));
2080#if defined(CONFIG_TCC_BCHECK)2086#if defined(CONFIG_TCC_BCHECK)
2081 if (S->do_bounds_check)2087 if (tcc_state->do_bounds_check)
2082 o(S, 0x91004000 | r | r << 5); // add x(r),x(r),#15+12088 o(0x91004000 | r | r << 5); // add x(r),x(r),#15+1
2083 else2089 else
2084#endif2090#endif
2085 o(S, 0x91003c00 | r | r << 5); // add x(r),x(r),#152091 o(0x91003c00 | r | r << 5); // add x(r),x(r),#15
2086 o(S, 0x927cec00 | r | r << 5); // bic x(r),x(r),#152092 o(0x927cec00 | r | r << 5); // bic x(r),x(r),#15
2087 o(S, 0xcb2063ff | r << 16); // sub sp,sp,x(r)2093 o(0xcb2063ff | r << 16); // sub sp,sp,x(r)
2088 vpop(S);2094 vpop();
2089#if defined(CONFIG_TCC_BCHECK)2095#if defined(CONFIG_TCC_BCHECK)
2090 if (S->do_bounds_check) {2096 if (tcc_state->do_bounds_check) {
2091 vpushi(S, 0);2097 vpushi(0);
2092 S->tccgen_vtop->r = TREG_R(0);2098 vtop->r = TREG_R(0);
2093 o(S, 0x910003e0 | S->tccgen_vtop->r); // mov r0,sp2099 o(0x910003e0 | vtop->r); // mov r0,sp
2094 vswap(S);2100 vswap();
2095 vpush_helper_func(S, TOK___bound_new_region);2101 vpush_helper_func(TOK___bound_new_region);
2096 vrott(S, 3);2102 vrott(3);
2097 gfunc_call(S, 2);2103 gfunc_call(2);
2098 S->func_bound_add_epilog = 1;2104 func_bound_add_epilog = 1;
2099 }2105 }
2100#endif2106#endif
2101}2107}
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 *S, unsigned got_offset, struct sym_attr *attr)93ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
94{94{
95 Section *plt = S->plt;95 Section *plt = s1->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(S, plt, 32);100 section_ptr_add(plt, 32);
101 }101 }
102 plt_offset = plt->data_offset;102 plt_offset = plt->data_offset;
103 103
104 p = section_ptr_add(S, plt, 16);104 p = section_ptr_add(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 *S, unsigned got_offset, struct sym_a · 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 *S)112ST_FUNC void relocate_plt(TCCState *s1)
113{113{
114 uint8_t *p, *p_end;114 uint8_t *p, *p_end;
115 115
116 if (!S->plt)116 if (!s1->plt)
117 return;117 return;
118 118
119 p = S->plt->data;119 p = s1->plt->data;
120 p_end = p + S->plt->data_offset;120 p_end = p + s1->plt->data_offset;
121 121
122 if (p < p_end) {122 if (p < p_end) {
123 uint64_t plt = S->plt->sh_addr;123 uint64_t plt = s1->plt->sh_addr;
124 uint64_t got = S->got->sh_addr + 16;124 uint64_t got = s1->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(S, "Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt);127 tcc_error("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 *S) · 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 = S->got->sh_addr;140 got = s1->got->sh_addr;
141 while (p < p_end) {141 while (p < p_end) {
142 uint64_t pc = plt + (p - S->plt->data);142 uint64_t pc = plt + (p - s1->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(S, "Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc);146 tcc_error("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 *S) · 5 unmodified lines
155 }155 }
156 }156 }
157 157
158 if (S->plt->reloc) {158 if (s1->plt->reloc) {
159 ElfW_Rel *rel;159 ElfW_Rel *rel;
160 p = S->got->data;160 p = s1->got->data;
161 for_each_elem(S->plt->reloc, 0, rel, ElfW_Rel) {161 for_each_elem(s1->plt->reloc, 0, rel, ElfW_Rel) {
162 write64le(p + rel->r_offset, S->plt->sh_addr);162 write64le(p + rel->r_offset, s1->plt->sh_addr);
163 }163 }
164 }164 }
165}165}
166 166
167void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)167void relocate(TCCState *s1, 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 *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a · 2 unmodified lines
173 173
174 switch(type) {174 switch(type) {
175 case R_AARCH64_ABS64:175 case R_AARCH64_ABS64:
176 if (S->output_type == TCC_OUTPUT_DLL) {176 if (s1->output_type == TCC_OUTPUT_DLL) {
177 esym_index = get_sym_attr(S, sym_index, 0)->dyn_index;177 esym_index = get_sym_attr(s1, 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 *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a · 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 (S->output_type == TCC_OUTPUT_DLL) {193 if (s1->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 *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a · 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 (S->output_type == TCC_OUTPUT_DLL) {205 if (s1->output_type == TCC_OUTPUT_DLL) {
206 /* DLL relocation */206 /* DLL relocation */
207 esym_index = get_sym_attr(S, sym_index, 0)->dyn_index;207 esym_index = get_sym_attr(s1, 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 *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a · 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(S, "R_AARCH64_ADR_PREL_PG_HI21 relocation failed");238 tcc_error("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 *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a · 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(S, "R_AARCH64_(JUMP|CALL)26 relocation failed"271 tcc_error("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 *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a · 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 (((S->got->sh_addr +279 (((s1->got->sh_addr +
280 get_sym_attr(S, sym_index, 0)->got_offset) >> 12) - (addr >> 12));280 get_sym_attr(s1, 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(S, "R_AARCH64_ADR_GOT_PAGE relocation failed");282 tcc_error("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 *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a · 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 ((S->got->sh_addr +290 ((s1->got->sh_addr +
291 get_sym_attr(S, sym_index, 0)->got_offset) & 0xff8) << 7));291 get_sym_attr(s1, 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 *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a · 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 - S->pe_imagebase);307 add32le(ptr, val - s1->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(S, "internal compiler error file at %s:%d", __FILE__, __LINE__);\175 tcc_error("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(TCCState* S, int c)189void C67_g(int c)
190{190{
191 int ind1;191 int ind1;
192 if (S->tccgen_nocode_wanted)192 if (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 = S->tccgen_ind + 4;197 ind1 = ind + 4;
198 if (ind1 > (int) cur_text_section->data_allocated)198 if (ind1 > (int) cur_text_section->data_allocated)
199 section_realloc(S, cur_text_section, ind1);199 section_realloc(cur_text_section, ind1);
200 cur_text_section->data[S->tccgen_ind] = c & 0xff;200 cur_text_section->data[ind] = c & 0xff;
201 cur_text_section->data[S->tccgen_ind + 1] = (c >> 8) & 0xff;201 cur_text_section->data[ind + 1] = (c >> 8) & 0xff;
202 cur_text_section->data[S->tccgen_ind + 2] = (c >> 16) & 0xff;202 cur_text_section->data[ind + 2] = (c >> 16) & 0xff;
203 cur_text_section->data[S->tccgen_ind + 3] = (c >> 24) & 0xff;203 cur_text_section->data[ind + 3] = (c >> 24) & 0xff;
204 S->tccgen_ind = ind1;204 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(TCCState* S, int t, int a)209void gsym_addr(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(TCCState* S, 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(S, &S->tccgen_char_pointer_type, cur_text_section, a, 0);223 sym = get_sym_ref(&char_pointer_type, cur_text_section, a, 0);
224 greloc(S, cur_text_section, sym, t, R_C60LO16);224 greloc(cur_text_section, sym, t, R_C60LO16);
225 greloc(S, cur_text_section, sym, t + 4, R_C60HI16);225 greloc(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(TCCState* S, int r)258int C67_map_regn(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(TCCState* S, 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(TCCState* S, int r)299int C67_map_regc(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(TCCState* S, 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(TCCState* S, int r)320int C67_map_regs(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(TCCState* S, int r) · 21 unmodified lines
345 return 0;345 return 0;
346}346}
347 347
348int C67_map_S12(TCCState* S, char *s)348int C67_map_S12(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(TCCState* S, char *s) · 5 unmodified lines
357 return 0;357 return 0;
358}358}
359 359
360int C67_map_D12(TCCState* S, char *s)360int C67_map_D12(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(TCCState* S, char *s) · 7 unmodified lines
371 371
372 372
373 373
374void C67_asm(TCCState* S, const char *s, int a, int b, int c)374void C67_asm(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(TCCState* S, 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(S, (C67_map_regn(S, b) << 23) |386 C67_g((C67_map_regn(b) << 23) |
387 ((a & 0xffff) << 7) | (0x0a << 2) | (C67_map_regs(S, b) << 1));387 ((a & 0xffff) << 7) | (0x0a << 2) | (C67_map_regs(b) << 1));
388 } else if (strstr(s, "MVKH") == s) {388 } else if (strstr(s, "MVKH") == s) {
389 C67_g(S, (C67_map_regn(S, b) << 23) |389 C67_g((C67_map_regn(b) << 23) |
390 (((a >> 16) & 0xffff) << 7) |390 (((a >> 16) & 0xffff) << 7) |
391 (0x1a << 2) | (C67_map_regs(S, b) << 1));391 (0x1a << 2) | (C67_map_regs(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(S, (C67_map_regn(S, a) << 23) | //src393 C67_g((C67_map_regn(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(TCCState* S, 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(S, a) << 1) | //side of src401 (C67_map_regs(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(S, (C67_map_regn(S, a) << 23) | //src404 C67_g((C67_map_regn(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(TCCState* S, 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(S, a) << 1) | //side of src412 (C67_map_regs(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(S, (C67_map_regn(S, a) << 23) | //src415 C67_g((C67_map_regn(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(TCCState* S, 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(S, a) << 1) | //side of src423 (C67_map_regs(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(S, (C67_map_regn(S, a) << 23) | //src426 C67_g((C67_map_regn(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(TCCState* S, 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(S, a) << 1) | //side of src434 (C67_map_regs(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(S, (C67_map_regn(S, a) << 23) | //src437 C67_g((C67_map_regn(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(TCCState* S, 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(S, a) << 1) | //side of src445 (C67_map_regs(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(S, (C67_map_regn(S, a) << 23) | //src448 C67_g((C67_map_regn(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(TCCState* S, 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(S, a) << 1) | //side of src456 (C67_map_regs(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(S, (C67_map_regn(S, a) << 23) | //src459 C67_g((C67_map_regn(a) << 23) | //src
460 (C67_map_regn(S, b) << 18) | //base reg A0460 (C67_map_regn(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(S, b) << 7) | //y D1/D2 base reg side464 (C67_map_regs(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(S, a) << 1) | //side of src467 (C67_map_regs(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(S, (C67_map_regn(S, a) << 23) | //src470 C67_g((C67_map_regn(a) << 23) | //src
471 (C67_map_regn(S, b) << 18) | //base reg A0471 (C67_map_regn(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(S, b) << 7) | //y D1/D2 base reg side475 (C67_map_regs(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(S, a) << 1) | //side of src478 (C67_map_regs(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(S, (C67_map_regn(S, a) << 23) | //src481 C67_g((C67_map_regn(a) << 23) | //src
482 (C67_map_regn(S, b) << 18) | //base reg A0482 (C67_map_regn(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(S, b) << 7) | //y D1/D2 base reg side486 (C67_map_regs(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(S, a) << 1) | //side of src489 (C67_map_regs(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(S, (C67_map_regn(S, a) << 23) | //src493 C67_g((C67_map_regn(a) << 23) | //src
494 (C67_map_regn(S, b) << 18) | //base reg A0494 (C67_map_regn(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(S, b) << 7) | //y D1/D2 base reg side498 (C67_map_regs(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(S, a) << 1) | //side of src501 (C67_map_regs(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(S, (C67_map_regn(S, a) << 23) | //dst504 C67_g((C67_map_regn(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(TCCState* S, 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(S, a) << 1) | //side of dst512 (C67_map_regs(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(S, (C67_map_regn(S, a) << 23) | //dst515 C67_g((C67_map_regn(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(TCCState* S, 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(S, a) << 1) | //side of dst523 (C67_map_regs(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(S, (C67_map_regn(S, a) << 23) | //dst526 C67_g((C67_map_regn(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(TCCState* S, 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(S, a) << 1) | //side of dst534 (C67_map_regs(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(S, (C67_map_regn(S, a) << 23) | //dst537 C67_g((C67_map_regn(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(TCCState* S, 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(S, a) << 1) | //side of dst545 (C67_map_regs(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(S, (C67_map_regn(S, a) << 23) | //dst548 C67_g((C67_map_regn(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(TCCState* S, 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(S, a) << 1) | //side of dst556 (C67_map_regs(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(S, (C67_map_regn(S, a) << 23) | //dst559 C67_g((C67_map_regn(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(TCCState* S, 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(S, a) << 1) | //side of dst567 (C67_map_regs(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(S, (C67_map_regn(S, a) << 23) | //dst570 C67_g((C67_map_regn(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(TCCState* S, 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(S, a) << 1) | //side of dst578 (C67_map_regs(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(S, (C67_map_regn(S, a) << 23) | //dst581 C67_g((C67_map_regn(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(TCCState* S, 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(S, a) << 1) | //side of dst589 (C67_map_regs(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(S, (C67_map_regn(S, b) << 23) | //dst592 C67_g((C67_map_regn(b) << 23) | //dst
593 (C67_map_regn(S, a) << 18) | //base reg A15593 (C67_map_regn(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(S, a) << 7) | //y D1/D2 src side597 (C67_map_regs(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(S, b) << 1) | //side of dst600 (C67_map_regs(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(S, (C67_map_regn(S, b) << 23) | //dst603 C67_g((C67_map_regn(b) << 23) | //dst
604 (C67_map_regn(S, a) << 18) | //base reg A15604 (C67_map_regn(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(S, a) << 7) | //y D1/D2 src side608 (C67_map_regs(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(S, b) << 1) | //side of dst611 (C67_map_regs(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(S, (C67_map_regn(S, b) << 23) | //dst614 C67_g((C67_map_regn(b) << 23) | //dst
615 (C67_map_regn(S, a) << 18) | //base reg A15615 (C67_map_regn(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(S, a) << 7) | //y D1/D2 src side619 (C67_map_regs(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(S, b) << 1) | //side of dst622 (C67_map_regs(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(S, (C67_map_regn(S, b) << 23) | //dst625 C67_g((C67_map_regn(b) << 23) | //dst
626 (C67_map_regn(S, a) << 18) | //base reg A15626 (C67_map_regn(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(S, a) << 7) | //y D1/D2 src side630 (C67_map_regs(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(S, b) << 1) | //side of dst633 (C67_map_regs(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(S, (C67_map_regn(S, b) << 23) | //dst636 C67_g((C67_map_regn(b) << 23) | //dst
637 (C67_map_regn(S, a) << 18) | //base reg A15637 (C67_map_regn(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(S, a) << 7) | //y D1/D2 src side641 (C67_map_regs(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(S, b) << 1) | //side of dst644 (C67_map_regs(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(S, (C67_map_regn(S, b) << 23) | //dst647 C67_g((C67_map_regn(b) << 23) | //dst
648 (C67_map_regn(S, a) << 18) | //base reg A15648 (C67_map_regn(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(S, a) << 7) | //y D1/D2 src side652 (C67_map_regs(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(S, b) << 1) | //side of dst655 (C67_map_regs(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(S, (C67_map_regn(S, b) << 23) | //dst658 C67_g((C67_map_regn(b) << 23) | //dst
659 (C67_map_regn(S, a) << 18) | //base reg A15659 (C67_map_regn(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(S, a) << 7) | //y D1/D2 src side663 (C67_map_regs(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(S, b) << 1) | //side of dst666 (C67_map_regs(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(S, a) ^ C67_map_regs(S, b);669 xpath = C67_map_regs(a) ^ C67_map_regs(b);
670 ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a));670 ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
671 671
672 C67_g(S, (C67_map_regn(S, c) << 23) | //dst672 C67_g((C67_map_regn(c) << 23) | //dst
673 (C67_map_regn(S, b) << 18) | //src2673 (C67_map_regn(b) << 18) | //src2
674 (C67_map_regn(S, a) << 13) | //src1674 (C67_map_regn(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(S, c) << 1) | //side for reg c678 (C67_map_regs(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(S, a) ^ C67_map_regs(S, b);681 xpath = C67_map_regs(a) ^ C67_map_regs(b);
682 ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a));682 ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
683 683
684 C67_g(S, (C67_map_regn(S, c) << 23) | //dst684 C67_g((C67_map_regn(c) << 23) | //dst
685 (C67_map_regn(S, b) << 18) | //src2685 (C67_map_regn(b) << 18) | //src2
686 (C67_map_regn(S, a) << 13) | //src1686 (C67_map_regn(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(S, c) << 1) | //side for reg c690 (C67_map_regs(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(S, a) ^ C67_map_regs(S, b);693 xpath = C67_map_regs(a) ^ C67_map_regs(b);
694 ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a));694 ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
695 695
696 C67_g(S, (C67_map_regn(S, c) << 23) | //dst696 C67_g((C67_map_regn(c) << 23) | //dst
697 (C67_map_regn(S, b) << 18) | //src2697 (C67_map_regn(b) << 18) | //src2
698 (C67_map_regn(S, a) << 13) | //src1698 (C67_map_regn(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(S, c) << 1) | //side for reg c702 (C67_map_regs(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(S, a) ^ C67_map_regs(S, b);707 xpath = C67_map_regs(a) ^ C67_map_regs(b);
708 ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a));708 ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
709 709
710 C67_g(S, (C67_map_regn(S, c) << 23) | //dst710 C67_g((C67_map_regn(c) << 23) | //dst
711 (C67_map_regn(S, b) << 18) | //src2711 (C67_map_regn(b) << 18) | //src2
712 (C67_map_regn(S, a) << 13) | //src1712 (C67_map_regn(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(S, c) << 1) | //side for reg c716 (C67_map_regs(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(S, a) ^ C67_map_regs(S, b);719 xpath = C67_map_regs(a) ^ C67_map_regs(b);
720 ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a));720 ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
721 721
722 C67_g(S, (C67_map_regn(S, c) << 23) | //dst722 C67_g((C67_map_regn(c) << 23) | //dst
723 (C67_map_regn(S, b) << 18) | //src2723 (C67_map_regn(b) << 18) | //src2
724 (C67_map_regn(S, a) << 13) | //src1724 (C67_map_regn(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(S, c) << 1) | //side for reg c728 (C67_map_regs(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(S, a) ^ C67_map_regs(S, b);731 xpath = C67_map_regs(a) ^ C67_map_regs(b);
732 ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a));732 ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
733 733
734 C67_g(S, (C67_map_regn(S, c) << 23) | //dst734 C67_g((C67_map_regn(c) << 23) | //dst
735 (C67_map_regn(S, b) << 18) | //src2735 (C67_map_regn(b) << 18) | //src2
736 (C67_map_regn(S, a) << 13) | //src1736 (C67_map_regn(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(S, c) << 1) | //side for reg c740 (C67_map_regs(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(S, a) ^ C67_map_regs(S, b);743 xpath = C67_map_regs(a) ^ C67_map_regs(b);
744 ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a));744 ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
745 745
746 C67_g(S, (C67_map_regn(S, c) << 23) | //dst746 C67_g((C67_map_regn(c) << 23) | //dst
747 (C67_map_regn(S, b) << 18) | //src2747 (C67_map_regn(b) << 18) | //src2
748 (C67_map_regn(S, a) << 13) | //src1748 (C67_map_regn(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(S, c) << 1) | //side for reg c752 (C67_map_regs(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(S, a) ^ C67_map_regs(S, b);755 xpath = C67_map_regs(a) ^ C67_map_regs(b);
756 ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a));756 ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
757 757
758 C67_g(S, (C67_map_regn(S, c) << 23) | //dst758 C67_g((C67_map_regn(c) << 23) | //dst
759 (C67_map_regn(S, b) << 18) | //src2759 (C67_map_regn(b) << 18) | //src2
760 (C67_map_regn(S, a) << 13) | //src1760 (C67_map_regn(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(S, c) << 1) | //side for reg c764 (C67_map_regs(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(S, a) ^ C67_map_regs(S, b);767 xpath = C67_map_regs(a) ^ C67_map_regs(b);
768 ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a));768 ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
769 769
770 C67_g(S, (C67_map_regn(S, c) << 23) | //dst770 C67_g((C67_map_regn(c) << 23) | //dst
771 (C67_map_regn(S, b) << 18) | //src2771 (C67_map_regn(b) << 18) | //src2
772 (C67_map_regn(S, a) << 13) | //src1772 (C67_map_regn(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(S, c) << 1) | //side for reg c776 (C67_map_regs(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(S, a) ^ C67_map_regs(S, b);779 xpath = C67_map_regs(a) ^ C67_map_regs(b);
780 ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a));780 ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
781 781
782 C67_g(S, (C67_map_regn(S, c) << 23) | //dst782 C67_g((C67_map_regn(c) << 23) | //dst
783 (C67_map_regn(S, b) << 18) | //src2783 (C67_map_regn(b) << 18) | //src2
784 (C67_map_regn(S, a) << 13) | //src1784 (C67_map_regn(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(S, c) << 1) | //side for reg c788 (C67_map_regs(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(S, a) ^ C67_map_regs(S, b);791 xpath = C67_map_regs(a) ^ C67_map_regs(b);
792 ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a));792 ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
793 793
794 C67_g(S, (C67_map_regn(S, c) << 23) | //dst794 C67_g((C67_map_regn(c) << 23) | //dst
795 (C67_map_regn(S, b) << 18) | //src2795 (C67_map_regn(b) << 18) | //src2
796 (C67_map_regn(S, a) << 13) | //src1796 (C67_map_regn(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(S, c) << 1) | //side for reg c800 (C67_map_regs(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(S, (0 << 29) | //creg803 C67_g((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(S, c) ^ 1;810 xpath = C67_map_regs(c) ^ 1;
811 811
812 C67_g(S, (C67_map_regc(S, b) << 29) | //creg812 C67_g((C67_map_regc(b) << 29) | //creg
813 (a << 28) | //inv813 (a << 28) | //inv
814 (0 << 23) | //dst814 (0 << 23) | //dst
815 (C67_map_regn(S, c) << 18) | //src2815 (C67_map_regn(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(TCCState* S, 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(S, b) ^ C67_map_regs(S, c);823 xpath = C67_map_regs(b) ^ C67_map_regs(c);
824 824
825 C67_g(S, (0 << 29) | //creg825 C67_g((0 << 29) | //creg
826 (0 << 28) | //inv826 (0 << 28) | //inv
827 (C67_map_regn(S, c) << 23) | //dst827 (C67_map_regn(c) << 23) | //dst
828 (C67_map_regn(S, b) << 18) | //src2828 (C67_map_regn(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(S, c) << 1) | //side of dest833 (C67_map_regs(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(S, b) ^ C67_map_regs(S, c);836 xpath = C67_map_regs(b) ^ C67_map_regs(c);
837 837
838 C67_g(S, (0 << 29) | //creg838 C67_g((0 << 29) | //creg
839 (0 << 28) | //inv839 (0 << 28) | //inv
840 (C67_map_regn(S, c) << 23) | //dst840 (C67_map_regn(c) << 23) | //dst
841 (C67_map_regn(S, b) << 18) | //src2841 (C67_map_regn(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(S, c) << 1) | //side of dest846 (C67_map_regs(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(S, b) ^ C67_map_regs(S, c);849 xpath = C67_map_regs(b) ^ C67_map_regs(c);
850 850
851 C67_g(S, (0 << 29) | //creg851 C67_g((0 << 29) | //creg
852 (0 << 28) | //inv852 (0 << 28) | //inv
853 (C67_map_regn(S, c) << 23) | //dst853 (C67_map_regn(c) << 23) | //dst
854 ((C67_map_regn(S, b) + 1) << 18) | //src2 WEIRD CPU must specify odd reg for some reason854 ((C67_map_regn(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(S, c) << 1) | //side of dest859 (C67_map_regs(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(S, b) ^ C67_map_regs(S, c);862 xpath = C67_map_regs(b) ^ C67_map_regs(c);
863 863
864 C67_g(S, (0 << 29) | //creg864 C67_g((0 << 29) | //creg
865 (0 << 28) | //inv865 (0 << 28) | //inv
866 (C67_map_regn(S, c) << 23) | //dst866 (C67_map_regn(c) << 23) | //dst
867 (C67_map_regn(S, b) << 18) | //src2 867 (C67_map_regn(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(S, c) << 1) | //side of dest872 (C67_map_regs(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(S, b) ^ C67_map_regs(S, c);875 xpath = C67_map_regs(b) ^ C67_map_regs(c);
876 876
877 C67_g(S, (0 << 29) | //creg877 C67_g((0 << 29) | //creg
878 (0 << 28) | //inv878 (0 << 28) | //inv
879 (C67_map_regn(S, c) << 23) | //dst879 (C67_map_regn(c) << 23) | //dst
880 (C67_map_regn(S, b) << 18) | //src2 880 (C67_map_regn(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(S, c) << 1) | //side of dest885 (C67_map_regs(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(S, b) ^ C67_map_regs(S, c);888 xpath = C67_map_regs(b) ^ C67_map_regs(c);
889 889
890 C67_g(S, (0 << 29) | //creg890 C67_g((0 << 29) | //creg
891 (0 << 28) | //inv891 (0 << 28) | //inv
892 (C67_map_regn(S, c) << 23) | //dst892 (C67_map_regn(c) << 23) | //dst
893 (C67_map_regn(S, b) << 18) | //src2 893 (C67_map_regn(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(S, c) << 1) | //side of dest898 (C67_map_regs(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(S, b) ^ C67_map_regs(S, c);901 xpath = C67_map_regs(b) ^ C67_map_regs(c);
902 902
903 C67_g(S, (0 << 29) | //creg903 C67_g((0 << 29) | //creg
904 (0 << 28) | //inv904 (0 << 28) | //inv
905 (C67_map_regn(S, c) << 23) | //dst905 (C67_map_regn(c) << 23) | //dst
906 ((C67_map_regn(S, b) + 1) << 18) | //src2 WEIRD CPU must specify odd reg for some reason906 ((C67_map_regn(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(S, c) << 1) | //side of dest911 (C67_map_regs(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(S, b) ^ C67_map_regs(S, c);914 xpath = C67_map_regs(b) ^ C67_map_regs(c);
915 915
916 C67_g(S, (0 << 29) | //creg916 C67_g((0 << 29) | //creg
917 (0 << 28) | //inv917 (0 << 28) | //inv
918 (C67_map_regn(S, c) << 23) | //dst918 (C67_map_regn(c) << 23) | //dst
919 (C67_map_regn(S, b) << 18) | //src2919 (C67_map_regn(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(S, c) << 1) | //side of dest924 (C67_map_regs(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(S, b) == C67_map_regs(S, c));927 ALWAYS_ASSERT(C67_map_regs(b) == C67_map_regs(c));
928 928
929 C67_g(S, (0 << 29) | //creg929 C67_g((0 << 29) | //creg
930 (0 << 28) | //inv930 (0 << 28) | //inv
931 (C67_map_regn(S, c) << 23) | //dst931 (C67_map_regn(c) << 23) | //dst
932 ((C67_map_regn(S, b) + 1) << 18) | //src2 WEIRD CPU must specify odd reg for some reason932 ((C67_map_regn(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(S, c) << 1) | //side of dest937 (C67_map_regs(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(S, b) ^ C67_map_regs(S, c);940 xpath = C67_map_regs(b) ^ C67_map_regs(c);
941 941
942 ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c));942 ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
943 943
944 C67_g(S, (0 << 29) | //creg944 C67_g((0 << 29) | //creg
945 (0 << 28) | //inv945 (0 << 28) | //inv
946 (C67_map_regn(S, c) << 23) | //dst946 (C67_map_regn(c) << 23) | //dst
947 (C67_map_regn(S, b) << 18) | //src2 (possible x path)947 (C67_map_regn(b) << 18) | //src2 (possible x path)
948 (C67_map_regn(S, a) << 13) | //src1 948 (C67_map_regn(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(S, c) << 1) | //side of dest952 (C67_map_regs(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(S, b) ^ C67_map_regs(S, c);955 xpath = C67_map_regs(b) ^ C67_map_regs(c);
956 956
957 ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c));957 ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
958 958
959 C67_g(S, (0 << 29) | //creg959 C67_g((0 << 29) | //creg
960 (0 << 28) | //inv960 (0 << 28) | //inv
961 (C67_map_regn(S, c) << 23) | //dst961 (C67_map_regn(c) << 23) | //dst
962 (C67_map_regn(S, b) << 18) | //src2 (possible x path)962 (C67_map_regn(b) << 18) | //src2 (possible x path)
963 (C67_map_regn(S, a) << 13) | //src1 963 (C67_map_regn(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(S, c) << 1) | //side of dest967 (C67_map_regs(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(S, b) ^ C67_map_regs(S, c);970 xpath = C67_map_regs(b) ^ C67_map_regs(c);
971 971
972 ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c));972 ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
973 973
974 C67_g(S, (0 << 29) | //creg974 C67_g((0 << 29) | //creg
975 (0 << 28) | //inv975 (0 << 28) | //inv
976 (C67_map_regn(S, c) << 23) | //dst976 (C67_map_regn(c) << 23) | //dst
977 (C67_map_regn(S, b) << 18) | //src2 (possible x path)977 (C67_map_regn(b) << 18) | //src2 (possible x path)
978 (C67_map_regn(S, a) << 13) | //src1 978 (C67_map_regn(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(S, c) << 1) | //side of dest982 (C67_map_regs(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(S, b) ^ C67_map_regs(S, c);985 xpath = C67_map_regs(b) ^ C67_map_regs(c);
986 986
987 ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c));987 ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
988 988
989 C67_g(S, (0 << 29) | //creg989 C67_g((0 << 29) | //creg
990 (0 << 28) | //inv990 (0 << 28) | //inv
991 (C67_map_regn(S, c) << 23) | //dst991 (C67_map_regn(c) << 23) | //dst
992 (C67_map_regn(S, b) << 18) | //src2 (possible x path)992 (C67_map_regn(b) << 18) | //src2 (possible x path)
993 (C67_map_regn(S, a) << 13) | //src1 993 (C67_map_regn(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(S, c) << 1) | //side of dest997 (C67_map_regs(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(S, b) ^ C67_map_regs(S, c);1000 xpath = C67_map_regs(b) ^ C67_map_regs(c);
1001 1001
1002 ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c));1002 ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
1003 1003
1004 C67_g(S, (0 << 29) | //creg1004 C67_g((0 << 29) | //creg
1005 (0 << 28) | //inv1005 (0 << 28) | //inv
1006 (C67_map_regn(S, c) << 23) | //dst1006 (C67_map_regn(c) << 23) | //dst
1007 (C67_map_regn(S, b) << 18) | //src2 (possible x path)1007 (C67_map_regn(b) << 18) | //src2 (possible x path)
1008 (C67_map_regn(S, a) << 13) | //src1 1008 (C67_map_regn(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(S, c) << 1) | //side of dest1012 (C67_map_regs(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(S, b) ^ C67_map_regs(S, c);1015 xpath = C67_map_regs(b) ^ C67_map_regs(c);
1016 1016
1017 ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c));1017 ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
1018 1018
1019 C67_g(S, (0 << 29) | //creg1019 C67_g((0 << 29) | //creg
1020 (0 << 28) | //inv1020 (0 << 28) | //inv
1021 (C67_map_regn(S, c) << 23) | //dst1021 (C67_map_regn(c) << 23) | //dst
1022 (C67_map_regn(S, b) << 18) | //src2 (possible x path)1022 (C67_map_regn(b) << 18) | //src2 (possible x path)
1023 (C67_map_regn(S, a) << 13) | //src1 1023 (C67_map_regn(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(S, c) << 1) | //side of dest1027 (C67_map_regs(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(S, b) ^ C67_map_regs(S, c);1030 xpath = C67_map_regs(b) ^ C67_map_regs(c);
1031 1031
1032 ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c));1032 ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
1033 1033
1034 C67_g(S, (0 << 29) | //creg1034 C67_g((0 << 29) | //creg
1035 (0 << 28) | //inv1035 (0 << 28) | //inv
1036 (C67_map_regn(S, c) << 23) | //dst1036 (C67_map_regn(c) << 23) | //dst
1037 (C67_map_regn(S, b) << 18) | //src2 (possible x path)1037 (C67_map_regn(b) << 18) | //src2 (possible x path)
1038 (C67_map_regn(S, a) << 13) | //src1 1038 (C67_map_regn(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(S, c) << 1) | //side of dest1042 (C67_map_regs(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(S, b) ^ C67_map_regs(S, c);1045 xpath = C67_map_regs(b) ^ C67_map_regs(c);
1046 1046
1047 ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c));1047 ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
1048 1048
1049 C67_g(S, (0 << 29) | //creg1049 C67_g((0 << 29) | //creg
1050 (0 << 28) | //inv1050 (0 << 28) | //inv
1051 (C67_map_regn(S, c) << 23) | //dst1051 (C67_map_regn(c) << 23) | //dst
1052 (C67_map_regn(S, b) << 18) | //src2 (possible x path)1052 (C67_map_regn(b) << 18) | //src2 (possible x path)
1053 (C67_map_regn(S, a) << 13) | //src1 1053 (C67_map_regn(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(S, c) << 1) | //side of dest1057 (C67_map_regs(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(S, b) ^ C67_map_regs(S, c);1060 xpath = C67_map_regs(b) ^ C67_map_regs(c);
1061 1061
1062 ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c));1062 ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
1063 1063
1064 C67_g(S, (0 << 29) | //creg1064 C67_g((0 << 29) | //creg
1065 (0 << 28) | //inv1065 (0 << 28) | //inv
1066 (C67_map_regn(S, c) << 23) | //dst1066 (C67_map_regn(c) << 23) | //dst
1067 (C67_map_regn(S, b) << 18) | //src2 (possible x path)1067 (C67_map_regn(b) << 18) | //src2 (possible x path)
1068 (C67_map_regn(S, a) << 13) | //src1 1068 (C67_map_regn(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(S, c) << 1) | //side of dest1072 (C67_map_regs(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(S, b) ^ C67_map_regs(S, c);1075 xpath = C67_map_regs(b) ^ C67_map_regs(c);
1076 1076
1077 ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c));1077 ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
1078 1078
1079 C67_g(S, (0 << 29) | //creg1079 C67_g((0 << 29) | //creg
1080 (0 << 28) | //inv1080 (0 << 28) | //inv
1081 (C67_map_regn(S, c) << 23) | //dst1081 (C67_map_regn(c) << 23) | //dst
1082 (C67_map_regn(S, b) << 18) | //src2 (possible x path)1082 (C67_map_regn(b) << 18) | //src2 (possible x path)
1083 (C67_map_regn(S, a) << 13) | //src1 1083 (C67_map_regn(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(S, c) << 1) | //side of dest1087 (C67_map_regs(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(S, b) ^ C67_map_regs(S, c);1090 xpath = C67_map_regs(b) ^ C67_map_regs(c);
1091 1091
1092 ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c));1092 ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
1093 1093
1094 C67_g(S, (0 << 29) | //creg1094 C67_g((0 << 29) | //creg
1095 (0 << 28) | //inv1095 (0 << 28) | //inv
1096 (C67_map_regn(S, c) << 23) | //dst1096 (C67_map_regn(c) << 23) | //dst
1097 (C67_map_regn(S, b) << 18) | //src2 (possible x path)1097 (C67_map_regn(b) << 18) | //src2 (possible x path)
1098 (C67_map_regn(S, a) << 13) | //src1 1098 (C67_map_regn(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(S, c) << 1) | //side of dest1102 (C67_map_regs(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(S, b) ^ C67_map_regs(S, c);1105 xpath = C67_map_regs(b) ^ C67_map_regs(c);
1106 1106
1107 ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c));1107 ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
1108 1108
1109 C67_g(S, (0 << 29) | //creg1109 C67_g((0 << 29) | //creg
1110 (0 << 28) | //inv1110 (0 << 28) | //inv
1111 (C67_map_regn(S, c) << 23) | //dst1111 (C67_map_regn(c) << 23) | //dst
1112 (C67_map_regn(S, b) << 18) | //src21112 (C67_map_regn(b) << 18) | //src2
1113 (C67_map_regn(S, a) << 13) | //src1 (cst5)1113 (C67_map_regn(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(S, c) << 1) | //side of dest1117 (C67_map_regs(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(S, b) ^ C67_map_regs(S, c);1120 xpath = C67_map_regs(b) ^ C67_map_regs(c);
1121 1121
1122 ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a));1122 ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
1123 1123
1124 C67_g(S, (0 << 29) | //creg1124 C67_g((0 << 29) | //creg
1125 (0 << 28) | //inv1125 (0 << 28) | //inv
1126 (C67_map_regn(S, c) << 23) | //dst1126 (C67_map_regn(c) << 23) | //dst
1127 (C67_map_regn(S, b) << 18) | //src21127 (C67_map_regn(b) << 18) | //src2
1128 (C67_map_regn(S, a) << 13) | //src1 1128 (C67_map_regn(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(S, c) << 1) | //side of dest1132 (C67_map_regs(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(S, b) ^ C67_map_regs(S, c);1135 xpath = C67_map_regs(b) ^ C67_map_regs(c);
1136 1136
1137 ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a));1137 ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
1138 1138
1139 C67_g(S, (0 << 29) | //creg1139 C67_g((0 << 29) | //creg
1140 (0 << 28) | //inv1140 (0 << 28) | //inv
1141 (C67_map_regn(S, c) << 23) | //dst1141 (C67_map_regn(c) << 23) | //dst
1142 (C67_map_regn(S, b) << 18) | //src21142 (C67_map_regn(b) << 18) | //src2
1143 (C67_map_regn(S, a) << 13) | //src1 1143 (C67_map_regn(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(S, c) << 1) | //side of dest1147 (C67_map_regs(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(S, b) ^ C67_map_regs(S, c);1150 xpath = C67_map_regs(b) ^ C67_map_regs(c);
1151 1151
1152 ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a));1152 ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
1153 1153
1154 C67_g(S, (0 << 29) | //creg1154 C67_g((0 << 29) | //creg
1155 (0 << 28) | //inv1155 (0 << 28) | //inv
1156 (C67_map_regn(S, c) << 23) | //dst1156 (C67_map_regn(c) << 23) | //dst
1157 (C67_map_regn(S, b) << 18) | //src21157 (C67_map_regn(b) << 18) | //src2
1158 (C67_map_regn(S, a) << 13) | //src1 1158 (C67_map_regn(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(S, c) << 1) | //side of dest1162 (C67_map_regs(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(S, (0 << 29) | //creg1167 C67_g((0 << 29) | //creg
1168 (0 << 28) | //inv1168 (0 << 28) | //inv
1169 (C67_map_regn(S, b) << 23) | //dst1169 (C67_map_regn(b) << 23) | //dst
1170 (a << 07) | //scst161170 (a << 07) | //scst16
1171 (0x14 << 2) | //opcode fixed1171 (0x14 << 2) | //opcode fixed
1172 (C67_map_regs(S, b) << 1) | //side of dst1172 (C67_map_regs(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(S, (0 << 29) | //creg1177 C67_g((0 << 29) | //creg
1178 (0 << 28) | //inv1178 (0 << 28) | //inv
1179 (C67_map_regn(S, b) << 23) | //dst1179 (C67_map_regn(b) << 23) | //dst
1180 (a << 07) | //scst161180 (a << 07) | //scst16
1181 (0x14 << 2) | //opcode fixed1181 (0x14 << 2) | //opcode fixed
1182 (C67_map_regs(S, b) << 1) | //side of dst1182 (C67_map_regs(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(S, ((a - 1) << 13) | //no of cycles1185 C67_g(((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(TCCState* S, 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(TCCState* S, int r, int fc)1198void C67_MVKL(int r, int fc)
1199{1199{
1200 C67_asm(S, "MVKL.", fc, r, 0);1200 C67_asm("MVKL.", fc, r, 0);
1201}1201}
1202 1202
1203void C67_MVKH(TCCState* S, int r, int fc)1203void C67_MVKH(int r, int fc)
1204{1204{
1205 C67_asm(S, "MVKH.", fc, r, 0);1205 C67_asm("MVKH.", fc, r, 0);
1206}1206}
1207 1207
1208void C67_STB_SP_A0(TCCState* S, int r)1208void C67_STB_SP_A0(int r)
1209{1209{
1210 C67_asm(S, "STB.D *+SP[A0]", r, 0, 0); // STB r,*+SP[A0]1210 C67_asm("STB.D *+SP[A0]", r, 0, 0); // STB r,*+SP[A0]
1211}1211}
1212 1212
1213void C67_STH_SP_A0(TCCState* S, int r)1213void C67_STH_SP_A0(int r)
1214{1214{
1215 C67_asm(S, "STH.D *+SP[A0]", r, 0, 0); // STH r,*+SP[A0]1215 C67_asm("STH.D *+SP[A0]", r, 0, 0); // STH r,*+SP[A0]
1216}1216}
1217 1217
1218void C67_STW_SP_A0(TCCState* S, int r)1218void C67_STW_SP_A0(int r)
1219{1219{
1220 C67_asm(S, "STW.D *+SP[A0]", r, 0, 0); // STW r,*+SP[A0]1220 C67_asm("STW.D *+SP[A0]", r, 0, 0); // STW r,*+SP[A0]
1221}1221}
1222 1222
1223void C67_STB_PTR(TCCState* S, int r, int r2)1223void C67_STB_PTR(int r, int r2)
1224{1224{
1225 C67_asm(S, "STB.D *", r, r2, 0); // STB r, *r21225 C67_asm("STB.D *", r, r2, 0); // STB r, *r2
1226}1226}
1227 1227
1228void C67_STH_PTR(TCCState* S, int r, int r2)1228void C67_STH_PTR(int r, int r2)
1229{1229{
1230 C67_asm(S, "STH.D *", r, r2, 0); // STH r, *r21230 C67_asm("STH.D *", r, r2, 0); // STH r, *r2
1231}1231}
1232 1232
1233void C67_STW_PTR(TCCState* S, int r, int r2)1233void C67_STW_PTR(int r, int r2)
1234{1234{
1235 C67_asm(S, "STW.D *", r, r2, 0); // STW r, *r21235 C67_asm("STW.D *", r, r2, 0); // STW r, *r2
1236}1236}
1237 1237
1238void C67_STW_PTR_PRE_INC(TCCState* S, int r, int r2, int n)1238void C67_STW_PTR_PRE_INC(int r, int r2, int n)
1239{1239{
1240 C67_asm(S, "STW.D +*", r, r2, n); // STW r, *+r21240 C67_asm("STW.D +*", r, r2, n); // STW r, *+r2
1241}1241}
1242 1242
1243void C67_PUSH(TCCState* S, int r)1243void C67_PUSH(int r)
1244{1244{
1245 C67_asm(S, "STW.D SP POST DEC", r, 0, 0); // STW r,*SP--1245 C67_asm("STW.D SP POST DEC", r, 0, 0); // STW r,*SP--
1246}1246}
1247 1247
1248void C67_LDW_SP_A0(TCCState* S, int r)1248void C67_LDW_SP_A0(int r)
1249{1249{
1250 C67_asm(S, "LDW.D *+SP[A0]", r, 0, 0); // LDW *+SP[A0],r1250 C67_asm("LDW.D *+SP[A0]", r, 0, 0); // LDW *+SP[A0],r
1251}1251}
1252 1252
1253void C67_LDDW_SP_A0(TCCState* S, int r)1253void C67_LDDW_SP_A0(int r)
1254{1254{
1255 C67_asm(S, "LDDW.D *+SP[A0]", r, 0, 0); // LDDW *+SP[A0],r1255 C67_asm("LDDW.D *+SP[A0]", r, 0, 0); // LDDW *+SP[A0],r
1256}1256}
1257 1257
1258void C67_LDH_SP_A0(TCCState* S, int r)1258void C67_LDH_SP_A0(int r)
1259{1259{
1260 C67_asm(S, "LDH.D *+SP[A0]", r, 0, 0); // LDH *+SP[A0],r1260 C67_asm("LDH.D *+SP[A0]", r, 0, 0); // LDH *+SP[A0],r
1261}1261}
1262 1262
1263void C67_LDB_SP_A0(TCCState* S, int r)1263void C67_LDB_SP_A0(int r)
1264{1264{
1265 C67_asm(S, "LDB.D *+SP[A0]", r, 0, 0); // LDB *+SP[A0],r1265 C67_asm("LDB.D *+SP[A0]", r, 0, 0); // LDB *+SP[A0],r
1266}1266}
1267 1267
1268void C67_LDHU_SP_A0(TCCState* S, int r)1268void C67_LDHU_SP_A0(int r)
1269{1269{
1270 C67_asm(S, "LDHU.D *+SP[A0]", r, 0, 0); // LDHU *+SP[A0],r1270 C67_asm("LDHU.D *+SP[A0]", r, 0, 0); // LDHU *+SP[A0],r
1271}1271}
1272 1272
1273void C67_LDBU_SP_A0(TCCState* S, int r)1273void C67_LDBU_SP_A0(int r)
1274{1274{
1275 C67_asm(S, "LDBU.D *+SP[A0]", r, 0, 0); // LDBU *+SP[A0],r1275 C67_asm("LDBU.D *+SP[A0]", r, 0, 0); // LDBU *+SP[A0],r
1276}1276}
1277 1277
1278void C67_LDW_PTR(TCCState* S, int r, int r2)1278void C67_LDW_PTR(int r, int r2)
1279{1279{
1280 C67_asm(S, "LDW.D *", r, r2, 0); // LDW *r,r21280 C67_asm("LDW.D *", r, r2, 0); // LDW *r,r2
1281}1281}
1282 1282
1283void C67_LDDW_PTR(TCCState* S, int r, int r2)1283void C67_LDDW_PTR(int r, int r2)
1284{1284{
1285 C67_asm(S, "LDDW.D *", r, r2, 0); // LDDW *r,r21285 C67_asm("LDDW.D *", r, r2, 0); // LDDW *r,r2
1286}1286}
1287 1287
1288void C67_LDH_PTR(TCCState* S, int r, int r2)1288void C67_LDH_PTR(int r, int r2)
1289{1289{
1290 C67_asm(S, "LDH.D *", r, r2, 0); // LDH *r,r21290 C67_asm("LDH.D *", r, r2, 0); // LDH *r,r2
1291}1291}
1292 1292
1293void C67_LDB_PTR(TCCState* S, int r, int r2)1293void C67_LDB_PTR(int r, int r2)
1294{1294{
1295 C67_asm(S, "LDB.D *", r, r2, 0); // LDB *r,r21295 C67_asm("LDB.D *", r, r2, 0); // LDB *r,r2
1296}1296}
1297 1297
1298void C67_LDHU_PTR(TCCState* S, int r, int r2)1298void C67_LDHU_PTR(int r, int r2)
1299{1299{
1300 C67_asm(S, "LDHU.D *", r, r2, 0); // LDHU *r,r21300 C67_asm("LDHU.D *", r, r2, 0); // LDHU *r,r2
1301}1301}
1302 1302
1303void C67_LDBU_PTR(TCCState* S, int r, int r2)1303void C67_LDBU_PTR(int r, int r2)
1304{1304{
1305 C67_asm(S, "LDBU.D *", r, r2, 0); // LDBU *r,r21305 C67_asm("LDBU.D *", r, r2, 0); // LDBU *r,r2
1306}1306}
1307 1307
1308void C67_LDW_PTR_PRE_INC(TCCState* S, int r, int r2)1308void C67_LDW_PTR_PRE_INC(int r, int r2)
1309{1309{
1310 C67_asm(S, "LDW.D +*", r, r2, 0); // LDW *+r,r21310 C67_asm("LDW.D +*", r, r2, 0); // LDW *+r,r2
1311}1311}
1312 1312
1313void C67_POP(TCCState* S, int r)1313void C67_POP(int r)
1314{1314{
1315 C67_asm(S, "LDW.D SP PRE INC", r, 0, 0); // LDW *++SP,r1315 C67_asm("LDW.D SP PRE INC", r, 0, 0); // LDW *++SP,r
1316}1316}
1317 1317
1318void C67_POP_DW(TCCState* S, int r)1318void C67_POP_DW(int r)
1319{1319{
1320 C67_asm(S, "LDDW.D SP PRE INC", r, 0, 0); // LDDW *++SP,r1320 C67_asm("LDDW.D SP PRE INC", r, 0, 0); // LDDW *++SP,r
1321}1321}
1322 1322
1323void C67_CMPLT(TCCState* S, int s1, int s2, int dst)1323void C67_CMPLT(int s1, int s2, int dst)
1324{1324{
1325 C67_asm(S, "CMPLT.L1", s1, s2, dst);1325 C67_asm("CMPLT.L1", s1, s2, dst);
1326}1326}
1327 1327
1328void C67_CMPGT(TCCState* S, int s1, int s2, int dst)1328void C67_CMPGT(int s1, int s2, int dst)
1329{1329{
1330 C67_asm(S, "CMPGT.L1", s1, s2, dst);1330 C67_asm("CMPGT.L1", s1, s2, dst);
1331}1331}
1332 1332
1333void C67_CMPEQ(TCCState* S, int s1, int s2, int dst)1333void C67_CMPEQ(int s1, int s2, int dst)
1334{1334{
1335 C67_asm(S, "CMPEQ.L1", s1, s2, dst);1335 C67_asm("CMPEQ.L1", s1, s2, dst);
1336}1336}
1337 1337
1338void C67_CMPLTU(TCCState* S, int s1, int s2, int dst)1338void C67_CMPLTU(int s1, int s2, int dst)
1339{1339{
1340 C67_asm(S, "CMPLTU.L1", s1, s2, dst);1340 C67_asm("CMPLTU.L1", s1, s2, dst);
1341}1341}
1342 1342
1343void C67_CMPGTU(TCCState* S, int s1, int s2, int dst)1343void C67_CMPGTU(int s1, int s2, int dst)
1344{1344{
1345 C67_asm(S, "CMPGTU.L1", s1, s2, dst);1345 C67_asm("CMPGTU.L1", s1, s2, dst);
1346}1346}
1347 1347
1348 1348
1349void C67_CMPLTSP(TCCState* S, int s1, int s2, int dst)1349void C67_CMPLTSP(int s1, int s2, int dst)
1350{1350{
1351 C67_asm(S, "CMPLTSP.S1", s1, s2, dst);1351 C67_asm("CMPLTSP.S1", s1, s2, dst);
1352}1352}
1353 1353
1354void C67_CMPGTSP(TCCState* S, int s1, int s2, int dst)1354void C67_CMPGTSP(int s1, int s2, int dst)
1355{1355{
1356 C67_asm(S, "CMPGTSP.S1", s1, s2, dst);1356 C67_asm("CMPGTSP.S1", s1, s2, dst);
1357}1357}
1358 1358
1359void C67_CMPEQSP(TCCState* S, int s1, int s2, int dst)1359void C67_CMPEQSP(int s1, int s2, int dst)
1360{1360{
1361 C67_asm(S, "CMPEQSP.S1", s1, s2, dst);1361 C67_asm("CMPEQSP.S1", s1, s2, dst);
1362}1362}
1363 1363
1364void C67_CMPLTDP(TCCState* S, int s1, int s2, int dst)1364void C67_CMPLTDP(int s1, int s2, int dst)
1365{1365{
1366 C67_asm(S, "CMPLTDP.S1", s1, s2, dst);1366 C67_asm("CMPLTDP.S1", s1, s2, dst);
1367}1367}
1368 1368
1369void C67_CMPGTDP(TCCState* S, int s1, int s2, int dst)1369void C67_CMPGTDP(int s1, int s2, int dst)
1370{1370{
1371 C67_asm(S, "CMPGTDP.S1", s1, s2, dst);1371 C67_asm("CMPGTDP.S1", s1, s2, dst);
1372}1372}
1373 1373
1374void C67_CMPEQDP(TCCState* S, int s1, int s2, int dst)1374void C67_CMPEQDP(int s1, int s2, int dst)
1375{1375{
1376 C67_asm(S, "CMPEQDP.S1", s1, s2, dst);1376 C67_asm("CMPEQDP.S1", s1, s2, dst);
1377}1377}
1378 1378
1379 1379
1380void C67_IREG_B_REG(TCCState* S, int inv, int r1, int r2) // [!R] B r21380void C67_IREG_B_REG(int inv, int r1, int r2) // [!R] B r2
1381{1381{
1382 C67_asm(S, "B.S2", inv, r1, r2);1382 C67_asm("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(TCCState* S, int disp) // B +2 Branch with constant displacement1389void C67_B_DISP(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(TCCState* S, int disp) // B +2 Branch with constant displacem · 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(S, "B DISP", disp + ((S->tccgen_ind & 31) >> 2), 0, 0);1398 C67_asm("B DISP", disp + ((ind & 31) >> 2), 0, 0);
1399}1399}
1400 1400
1401void C67_NOP(TCCState* S, int n)1401void C67_NOP(int n)
1402{1402{
1403 C67_asm(S, "NOP", n, 0, 0);1403 C67_asm("NOP", n, 0, 0);
1404}1404}
1405 1405
1406void C67_ADDK(TCCState* S, int n, int r)1406void C67_ADDK(int n, int r)
1407{1407{
1408 ALWAYS_ASSERT(abs(n) < 32767);1408 ALWAYS_ASSERT(abs(n) < 32767);
1409 1409
1410 C67_asm(S, "ADDK", n, r, 0);1410 C67_asm("ADDK", n, r, 0);
1411}1411}
1412 1412
1413void C67_ADDK_PARALLEL(TCCState* S, int n, int r)1413void C67_ADDK_PARALLEL(int n, int r)
1414{1414{
1415 ALWAYS_ASSERT(abs(n) < 32767);1415 ALWAYS_ASSERT(abs(n) < 32767);
1416 1416
1417 C67_asm(S, "||ADDK", n, r, 0);1417 C67_asm("||ADDK", n, r, 0);
1418}1418}
1419 1419
1420void C67_Adjust_ADDK(TCCState* S, int *inst, int n)1420void C67_Adjust_ADDK(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(TCCState* S, int r, int v)1427void C67_MV(int r, int v)
1428{1428{
1429 C67_asm(S, "MV.L", 0, r, v);1429 C67_asm("MV.L", 0, r, v);
1430}1430}
1431 1431
1432 1432
1433void C67_DPTRUNC(TCCState* S, int r, int v)1433void C67_DPTRUNC(int r, int v)
1434{1434{
1435 C67_asm(S, "DPTRUNC.L", 0, r, v);1435 C67_asm("DPTRUNC.L", 0, r, v);
1436}1436}
1437 1437
1438void C67_SPTRUNC(TCCState* S, int r, int v)1438void C67_SPTRUNC(int r, int v)
1439{1439{
1440 C67_asm(S, "SPTRUNC.L", 0, r, v);1440 C67_asm("SPTRUNC.L", 0, r, v);
1441}1441}
1442 1442
1443void C67_INTSP(TCCState* S, int r, int v)1443void C67_INTSP(int r, int v)
1444{1444{
1445 C67_asm(S, "INTSP.L", 0, r, v);1445 C67_asm("INTSP.L", 0, r, v);
1446}1446}
1447 1447
1448void C67_INTDP(TCCState* S, int r, int v)1448void C67_INTDP(int r, int v)
1449{1449{
1450 C67_asm(S, "INTDP.L", 0, r, v);1450 C67_asm("INTDP.L", 0, r, v);
1451}1451}
1452 1452
1453void C67_INTSPU(TCCState* S, int r, int v)1453void C67_INTSPU(int r, int v)
1454{1454{
1455 C67_asm(S, "INTSPU.L", 0, r, v);1455 C67_asm("INTSPU.L", 0, r, v);
1456}1456}
1457 1457
1458void C67_INTDPU(TCCState* S, int r, int v)1458void C67_INTDPU(int r, int v)
1459{1459{
1460 C67_asm(S, "INTDPU.L", 0, r, v);1460 C67_asm("INTDPU.L", 0, r, v);
1461}1461}
1462 1462
1463void C67_SPDP(TCCState* S, int r, int v)1463void C67_SPDP(int r, int v)
1464{1464{
1465 C67_asm(S, "SPDP.L", 0, r, v);1465 C67_asm("SPDP.L", 0, r, v);
1466}1466}
1467 1467
1468void C67_DPSP(TCCState* S, int r, int v) // note regs must be on the same side1468void C67_DPSP(int r, int v) // note regs must be on the same side
1469{1469{
1470 C67_asm(S, "DPSP.L", 0, r, v);1470 C67_asm("DPSP.L", 0, r, v);
1471}1471}
1472 1472
1473void C67_ADD(TCCState* S, int r, int v)1473void C67_ADD(int r, int v)
1474{1474{
1475 C67_asm(S, "ADD.L", v, r, v);1475 C67_asm("ADD.L", v, r, v);
1476}1476}
1477 1477
1478void C67_SUB(TCCState* S, int r, int v)1478void C67_SUB(int r, int v)
1479{1479{
1480 C67_asm(S, "SUB.L", v, r, v);1480 C67_asm("SUB.L", v, r, v);
1481}1481}
1482 1482
1483void C67_AND(TCCState* S, int r, int v)1483void C67_AND(int r, int v)
1484{1484{
1485 C67_asm(S, "AND.L", v, r, v);1485 C67_asm("AND.L", v, r, v);
1486}1486}
1487 1487
1488void C67_OR(TCCState* S, int r, int v)1488void C67_OR(int r, int v)
1489{1489{
1490 C67_asm(S, "OR.L", v, r, v);1490 C67_asm("OR.L", v, r, v);
1491}1491}
1492 1492
1493void C67_XOR(TCCState* S, int r, int v)1493void C67_XOR(int r, int v)
1494{1494{
1495 C67_asm(S, "XOR.L", v, r, v);1495 C67_asm("XOR.L", v, r, v);
1496}1496}
1497 1497
1498void C67_ADDSP(TCCState* S, int r, int v)1498void C67_ADDSP(int r, int v)
1499{1499{
1500 C67_asm(S, "ADDSP.L", v, r, v);1500 C67_asm("ADDSP.L", v, r, v);
1501}1501}
1502 1502
1503void C67_SUBSP(TCCState* S, int r, int v)1503void C67_SUBSP(int r, int v)
1504{1504{
1505 C67_asm(S, "SUBSP.L", v, r, v);1505 C67_asm("SUBSP.L", v, r, v);
1506}1506}
1507 1507
1508void C67_MPYSP(TCCState* S, int r, int v)1508void C67_MPYSP(int r, int v)
1509{1509{
1510 C67_asm(S, "MPYSP.M", v, r, v);1510 C67_asm("MPYSP.M", v, r, v);
1511}1511}
1512 1512
1513void C67_ADDDP(TCCState* S, int r, int v)1513void C67_ADDDP(int r, int v)
1514{1514{
1515 C67_asm(S, "ADDDP.L", v, r, v);1515 C67_asm("ADDDP.L", v, r, v);
1516}1516}
1517 1517
1518void C67_SUBDP(TCCState* S, int r, int v)1518void C67_SUBDP(int r, int v)
1519{1519{
1520 C67_asm(S, "SUBDP.L", v, r, v);1520 C67_asm("SUBDP.L", v, r, v);
1521}1521}
1522 1522
1523void C67_MPYDP(TCCState* S, int r, int v)1523void C67_MPYDP(int r, int v)
1524{1524{
1525 C67_asm(S, "MPYDP.M", v, r, v);1525 C67_asm("MPYDP.M", v, r, v);
1526}1526}
1527 1527
1528void C67_MPYI(TCCState* S, int r, int v)1528void C67_MPYI(int r, int v)
1529{1529{
1530 C67_asm(S, "MPYI.M", v, r, v);1530 C67_asm("MPYI.M", v, r, v);
1531}1531}
1532 1532
1533void C67_SHL(TCCState* S, int r, int v)1533void C67_SHL(int r, int v)
1534{1534{
1535 C67_asm(S, "SHL.S", r, v, v);1535 C67_asm("SHL.S", r, v, v);
1536}1536}
1537 1537
1538void C67_SHRU(TCCState* S, int r, int v)1538void C67_SHRU(int r, int v)
1539{1539{
1540 C67_asm(S, "SHRU.S", r, v, v);1540 C67_asm("SHRU.S", r, v, v);
1541}1541}
1542 1542
1543void C67_SHR(TCCState* S, int r, int v)1543void C67_SHR(int r, int v)
1544{1544{
1545 C67_asm(S, "SHR.S", r, v, v);1545 C67_asm("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(TCCState* S, int r, SValue * sv)1551void load(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(TCCState* S, 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(S, r, &v1);1567 load(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(S, "long double not supported");1570 tcc_error("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(TCCState* S, 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(S, v, r); // LDBU *v,r1611 C67_LDBU_PTR(v, r); // LDBU *v,r
1612 else1612 else
1613 C67_LDB_PTR(S, v, r); // LDB *v,r1613 C67_LDB_PTR(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(S, v, r); // LDHU *v,r1616 C67_LDHU_PTR(v, r); // LDHU *v,r
1617 else1617 else
1618 C67_LDH_PTR(S, v, r); // LDH *v,r1618 C67_LDH_PTR(v, r); // LDH *v,r
1619 } else if (size == 4) {1619 } else if (size == 4) {
1620 C67_LDW_PTR(S, v, r); // LDW *v,r1620 C67_LDW_PTR(v, r); // LDW *v,r
1621 } else if (size == 8) {1621 } else if (size == 8) {
1622 C67_LDDW_PTR(S, v, r); // LDDW *v,r1622 C67_LDDW_PTR(v, r); // LDDW *v,r
1623 }1623 }
1624 1624
1625 C67_NOP(S, 4); // NOP 41625 C67_NOP(4); // NOP 4
1626 return;1626 return;
1627 } else if (fr & VT_SYM) {1627 } else if (fr & VT_SYM) {
1628 greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched1628 greloc(cur_text_section, sv->sym, ind, R_C60LO16); // rem the inst need to be patched
1629 greloc(S, cur_text_section, sv->sym, S->tccgen_ind + 4, R_C60HI16);1629 greloc(cur_text_section, sv->sym, ind + 4, R_C60HI16);
1630 1630
1631 1631
1632 C67_MVKL(S, C67_A0, fc); //r=reg to load, constant1632 C67_MVKL(C67_A0, fc); //r=reg to load, constant
1633 C67_MVKH(S, C67_A0, fc); //r=reg to load, constant1633 C67_MVKH(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(S, C67_A0, r); // LDBU *A0,r1638 C67_LDBU_PTR(C67_A0, r); // LDBU *A0,r
1639 else1639 else
1640 C67_LDB_PTR(S, C67_A0, r); // LDB *A0,r1640 C67_LDB_PTR(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(S, C67_A0, r); // LDHU *A0,r1643 C67_LDHU_PTR(C67_A0, r); // LDHU *A0,r
1644 else1644 else
1645 C67_LDH_PTR(S, C67_A0, r); // LDH *A0,r1645 C67_LDH_PTR(C67_A0, r); // LDH *A0,r
1646 } else if (size == 4) {1646 } else if (size == 4) {
1647 C67_LDW_PTR(S, C67_A0, r); // LDW *A0,r1647 C67_LDW_PTR(C67_A0, r); // LDW *A0,r
1648 } else if (size == 8) {1648 } else if (size == 8) {
1649 C67_LDDW_PTR(S, C67_A0, r); // LDDW *A0,r1649 C67_LDDW_PTR(C67_A0, r); // LDDW *A0,r
1650 }1650 }
1651 1651
1652 C67_NOP(S, 4); // NOP 41652 C67_NOP(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(S, C67_A0, (fc / element) + 8 / element); //r=reg to load, constant1658 C67_MVKL(C67_A0, (fc / element) + 8 / element); //r=reg to load, constant
1659 C67_MVKH(S, C67_A0, (fc / element) + 8 / element); //r=reg to load, constant1659 C67_MVKH(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(S, r); // LDBU r, SP[A0]1663 C67_LDBU_SP_A0(r); // LDBU r, SP[A0]
1664 else1664 else
1665 C67_LDB_SP_A0(S, r); // LDB r, SP[A0]1665 C67_LDB_SP_A0(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(S, r); // LDHU r, SP[A0]1668 C67_LDHU_SP_A0(r); // LDHU r, SP[A0]
1669 else1669 else
1670 C67_LDH_SP_A0(S, r); // LDH r, SP[A0]1670 C67_LDH_SP_A0(r); // LDH r, SP[A0]
1671 } else if (size == 4) {1671 } else if (size == 4) {
1672 C67_LDW_SP_A0(S, r); // LDW r, SP[A0]1672 C67_LDW_SP_A0(r); // LDW r, SP[A0]
1673 } else if (size == 8) {1673 } else if (size == 8) {
1674 C67_LDDW_SP_A0(S, r); // LDDW r, SP[A0]1674 C67_LDDW_SP_A0(r); // LDDW r, SP[A0]
1675 }1675 }
1676 1676
1677 1677
1678 C67_NOP(S, 4); // NOP 41678 C67_NOP(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(S, cur_text_section, sv->sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched1684 greloc(cur_text_section, sv->sym, ind, R_C60LO16); // rem the inst need to be patched
1685 greloc(S, cur_text_section, sv->sym, S->tccgen_ind + 4, R_C60HI16);1685 greloc(cur_text_section, sv->sym, ind + 4, R_C60HI16);
1686 }1686 }
1687 C67_MVKL(S, r, fc); //r=reg to load, constant1687 C67_MVKL(r, fc); //r=reg to load, constant
1688 C67_MVKH(S, r, fc); //r=reg to load, constant1688 C67_MVKH(r, fc); //r=reg to load, constant
1689 } else if (v == VT_LOCAL) {1689 } else if (v == VT_LOCAL) {
1690 C67_MVKL(S, r, fc + 8); //r=reg to load, constant C67 stack points to next free1690 C67_MVKL(r, fc + 8); //r=reg to load, constant C67 stack points to next free
1691 C67_MVKH(S, r, fc + 8); //r=reg to load, constant1691 C67_MVKH(r, fc + 8); //r=reg to load, constant
1692 C67_ADD(S, C67_FP, r); // MV v,r v -> r1692 C67_ADD(C67_FP, r); // MV v,r v -> r
1693 } else if (v == VT_CMP) {1693 } else if (v == VT_CMP) {
1694 C67_MV(S, C67_compare_reg, r); // MV v,r v -> r1694 C67_MV(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(S, 4); // Branch with constant displacement, skip over this branch, load, nop, load1697 C67_B_DISP(4); // Branch with constant displacement, skip over this branch, load, nop, load
1698 C67_MVKL(S, r, t); // r=reg to load, 0 or 1 (do this while branching)1698 C67_MVKL(r, t); // r=reg to load, 0 or 1 (do this while branching)
1699 C67_NOP(S, 4); // NOP 41699 C67_NOP(4); // NOP 4
1700 gsym(S, fc); // modifies other branches to branch here1700 gsym(fc); // modifies other branches to branch here
1701 C67_MVKL(S, r, t ^ 1); // r=reg to load, 0 or 11701 C67_MVKL(r, t ^ 1); // r=reg to load, 0 or 1
1702 } else if (v != r) {1702 } else if (v != r) {
1703 C67_MV(S, v, r); // MV v,r v -> r1703 C67_MV(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(S, v + 1, r + 1); // MV v,r v -> r1706 C67_MV(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(TCCState* S, int r, SValue * v)1713void store(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(TCCState* S, 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(S, "long double not supported");1724 tcc_error("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(TCCState* S, 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(S, cur_text_section, v->sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched1739 greloc(cur_text_section, v->sym, ind, R_C60LO16); // rem the inst need to be patched
1740 greloc(S, cur_text_section, v->sym, S->tccgen_ind + 4, R_C60HI16);1740 greloc(cur_text_section, v->sym, ind + 4, R_C60HI16);
1741 }1741 }
1742 C67_MVKL(S, C67_A0, fc); //r=reg to load, constant1742 C67_MVKL(C67_A0, fc); //r=reg to load, constant
1743 C67_MVKH(S, C67_A0, fc); //r=reg to load, constant1743 C67_MVKH(C67_A0, fc); //r=reg to load, constant
1744 1744
1745 if (size == 1)1745 if (size == 1)
1746 C67_STB_PTR(S, r, C67_A0); // STB r, *A01746 C67_STB_PTR(r, C67_A0); // STB r, *A0
1747 else if (size == 2)1747 else if (size == 2)
1748 C67_STH_PTR(S, r, C67_A0); // STH r, *A01748 C67_STH_PTR(r, C67_A0); // STH r, *A0
1749 else if (size == 4 || size == 8)1749 else if (size == 4 || size == 8)
1750 C67_STW_PTR(S, r, C67_A0); // STW r, *A01750 C67_STW_PTR(r, C67_A0); // STW r, *A0
1751 1751
1752 if (size == 8)1752 if (size == 8)
1753 C67_STW_PTR_PRE_INC(S, r + 1, C67_A0, 1); // STW r, *+A0[1]1753 C67_STW_PTR_PRE_INC(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(TCCState* S, 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(S, C67_A0, (fc / element) + 8 / element); //r=reg to load, constant1784 C67_MVKL(C67_A0, (fc / element) + 8 / element); //r=reg to load, constant
1785 C67_MVKH(S, C67_A0, (fc / element) + 8 / element); //r=reg to load, constant1785 C67_MVKH(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(S, r); // STB r, SP[A0]1790 C67_STB_SP_A0(r); // STB r, SP[A0]
1791 else if (size == 2)1791 else if (size == 2)
1792 C67_STH_SP_A0(S, r); // STH r, SP[A0]1792 C67_STH_SP_A0(r); // STH r, SP[A0]
1793 else if (size == 4 || size == 8)1793 else if (size == 4 || size == 8)
1794 C67_STW_SP_A0(S, r); // STW r, SP[A0]1794 C67_STW_SP_A0(r); // STW r, SP[A0]
1795 1795
1796 if (size == 8) {1796 if (size == 8) {
1797 C67_ADDK(S, 1, C67_A0); // ADDK 1,A01797 C67_ADDK(1, C67_A0); // ADDK 1,A0
1798 C67_STW_SP_A0(S, r + 1); // STW r, SP[A0]1798 C67_STW_SP_A0(r + 1); // STW r, SP[A0]
1799 }1799 }
1800 } else {1800 } else {
1801 if (size == 1)1801 if (size == 1)
1802 C67_STB_PTR(S, r, fr); // STB r, *fr1802 C67_STB_PTR(r, fr); // STB r, *fr
1803 else if (size == 2)1803 else if (size == 2)
1804 C67_STH_PTR(S, r, fr); // STH r, *fr1804 C67_STH_PTR(r, fr); // STH r, *fr
1805 else if (size == 4 || size == 8)1805 else if (size == 4 || size == 8)
1806 C67_STW_PTR(S, r, fr); // STW r, *fr1806 C67_STW_PTR(r, fr); // STW r, *fr
1807 1807
1808 if (size == 8) {1808 if (size == 8) {
1809 C67_STW_PTR_PRE_INC(S, r + 1, fr, 1); // STW r, *+fr[1]1809 C67_STW_PTR_PRE_INC(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(TCCState* S, int is_jmp)1816static void gcall_or_jmp(int is_jmp)
1817{1817{
1818 int r;1818 int r;
1819 Sym *sym;1819 Sym *sym;
1820 1820
1821 if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {1821 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
1822 /* constant case */1822 /* constant case */
1823 if (S->tccgen_vtop->r & VT_SYM) {1823 if (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(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched1828 greloc(cur_text_section, vtop->sym, ind, R_C60LO16); // rem the inst need to be patched
1829 greloc(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind + 4, R_C60HI16);1829 greloc(cur_text_section, vtop->sym, ind + 4, R_C60HI16);
1830 1830
1831 C67_MVKL(S, C67_A0, 0); //r=reg to load, constant1831 C67_MVKL(C67_A0, 0); //r=reg to load, constant
1832 C67_MVKH(S, C67_A0, 0); //r=reg to load, constant1832 C67_MVKH(C67_A0, 0); //r=reg to load, constant
1833 C67_IREG_B_REG(S, 0, C67_CREG_ZERO, C67_A0); // B.S2x A01833 C67_IREG_B_REG(0, C67_CREG_ZERO, C67_A0); // B.S2x A0
1834 1834
1835 if (is_jmp) {1835 if (is_jmp) {
1836 C67_NOP(S, 5); // simple jump, just put NOP1836 C67_NOP(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(S, &S->tccgen_char_pointer_type, cur_text_section, S->tccgen_ind + 12, 0); // symbol for return address1840 sym = get_sym_ref(&char_pointer_type, cur_text_section, ind + 12, 0); // symbol for return address
1841 greloc(S, cur_text_section, sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched1841 greloc(cur_text_section, sym, ind, R_C60LO16); // rem the inst need to be patched
1842 greloc(S, cur_text_section, sym, S->tccgen_ind + 4, R_C60HI16);1842 greloc(cur_text_section, sym, ind + 4, R_C60HI16);
1843 C67_MVKL(S, C67_B3, 0); //r=reg to load, constant1843 C67_MVKL(C67_B3, 0); //r=reg to load, constant
1844 C67_MVKH(S, C67_B3, 0); //r=reg to load, constant1844 C67_MVKH(C67_B3, 0); //r=reg to load, constant
1845 C67_NOP(S, 3); // put remaining NOPs1845 C67_NOP(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(TCCState* S, int is_jmp) · 1 unmodified line
1850 }1850 }
1851 } else {1851 } else {
1852 /* otherwise, indirect call */1852 /* otherwise, indirect call */
1853 r = gv(S, RC_INT);1853 r = gv(RC_INT);
1854 C67_IREG_B_REG(S, 0, C67_CREG_ZERO, r); // B.S2x r1854 C67_IREG_B_REG(0, C67_CREG_ZERO, r); // B.S2x r
1855 1855
1856 if (is_jmp) {1856 if (is_jmp) {
1857 C67_NOP(S, 5); // simple jump, just put NOP1857 C67_NOP(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(S, &S->tccgen_char_pointer_type, cur_text_section, S->tccgen_ind + 12, 0); // symbol for return address1861 sym = get_sym_ref(&char_pointer_type, cur_text_section, ind + 12, 0); // symbol for return address
1862 greloc(S, cur_text_section, sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched1862 greloc(cur_text_section, sym, ind, R_C60LO16); // rem the inst need to be patched
1863 greloc(S, cur_text_section, sym, S->tccgen_ind + 4, R_C60HI16);1863 greloc(cur_text_section, sym, ind + 4, R_C60HI16);
1864 C67_MVKL(S, C67_B3, 0); //r=reg to load, constant1864 C67_MVKL(C67_B3, 0); //r=reg to load, constant
1865 C67_MVKH(S, C67_B3, 0); //r=reg to load, constant1865 C67_MVKH(C67_B3, 0); //r=reg to load, constant
1866 C67_NOP(S, 3); // put remaining NOPs1866 C67_NOP(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(TCCState* S, int nb_args)1880void gfunc_call(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(S, "more than 10 function params not currently supported");1886 tcc_error("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 ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_STRUCT) {1891 if ((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 ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG) {1898 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
1899 tcc_error(S, "long long not supported");1899 tcc_error("long long not supported");
1900 } else if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {1900 } else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
1901 tcc_error(S, "long double not supported");1901 tcc_error("long double not supported");
1902 } else if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_DOUBLE) {1902 } else if ((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(TCCState* S, 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(S, RC_C67_A4 << (2 * i));1910 r = gv(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(S, r);1915 C67_PUSH(r);
1916 1916
1917 if (size == 8) {1917 if (size == 8) {
1918 C67_STW_PTR_PRE_INC(S, r + 1, C67_SP, 3); // STW r, *+SP[3] (go back and put the other)1918 C67_STW_PTR_PRE_INC(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 S->tccgen_vtop--;1922 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(TCCState* S, 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(S, TREG_C67_A4 + i * 2);1930 C67_POP_DW(TREG_C67_A4 + i * 2);
1931 else1931 else
1932 C67_POP(S, TREG_C67_A4 + i * 2);1932 C67_POP(TREG_C67_A4 + i * 2);
1933 }1933 }
1934 gcall_or_jmp(S, 0);1934 gcall_or_jmp(0);
1935 S->tccgen_vtop--;1935 vtop--;
1936}1936}
1937 1937
1938 1938
@@ -1946,7 +1946,7 @@ void gfunc_call(TCCState* S, 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(TCCState* S, Sym *func_sym)1949void gfunc_prolog(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(TCCState* S, 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 ((S->tccgen_func_vt.t & VT_BTYPE) == VT_STRUCT) {1961 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
1962 S->tccgen_func_vc = addr;1962 func_vc = addr;
1963 addr += 4;1963 addr += 4;
1964 }1964 }
1965 1965
@@ -1968,7 +1968,7 @@ void gfunc_prolog(TCCState* S, 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(S, sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL, addr);1971 sym_push(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(TCCState* S, 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(S, C67_FP, C67_A0); // move FP -> A01995 C67_MV(C67_FP, C67_A0); // move FP -> A0
1996 C67_MV(S, C67_SP, C67_FP); // move SP -> FP1996 C67_MV(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 S->tccgen_loc = 0;2000 loc = 0;
2001 for (i = 0; i < NoOfCurFuncArgs; i++) {2001 for (i = 0; i < NoOfCurFuncArgs; i++) {
2002 2002
2003 ParamLocOnStack[i] = S->tccgen_loc; // remember where the param is2003 ParamLocOnStack[i] = loc; // remember where the param is
2004 S->tccgen_loc += -8;2004 loc += -8;
2005 2005
2006 C67_PUSH(S, TREG_C67_A4 + i * 2);2006 C67_PUSH(TREG_C67_A4 + i * 2);
2007 2007
2008 if (TranslateStackToReg[i] == 8) {2008 if (TranslateStackToReg[i] == 8) {
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)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)
2010 }2010 }
2011 }2011 }
2012 2012
2013 TotalBytesPushedOnStack = -S->tccgen_loc;2013 TotalBytesPushedOnStack = -loc;
2014 2014
2015 func_sub_sp_offset = S->tccgen_ind; // remember where we put the stack instruction 2015 func_sub_sp_offset = ind; // remember where we put the stack instruction
2016 C67_ADDK(S, 0, C67_SP); // ADDK.L2 loc,SP (just put zero temporarily)2016 C67_ADDK(0, C67_SP); // ADDK.L2 loc,SP (just put zero temporarily)
2017 2017
2018 C67_PUSH(S, C67_A0);2018 C67_PUSH(C67_A0);
2019 C67_PUSH(S, C67_B3);2019 C67_PUSH(C67_B3);
2020}2020}
2021 2021
2022/* generate function epilog */2022/* generate function epilog */
2023void gfunc_epilog(TCCState* S)2023void gfunc_epilog(void)
2024{2024{
2025 {2025 {
2026 int local = (-S->tccgen_loc + 7) & -8; // stack must stay aligned to 8 bytes for LDDW instr2026 int local = (-loc + 7) & -8; // stack must stay aligned to 8 bytes for LDDW instr
2027 C67_POP(S, C67_B3);2027 C67_POP(C67_B3);
2028 C67_NOP(S, 4); // NOP wait for load2028 C67_NOP(4); // NOP wait for load
2029 C67_IREG_B_REG(S, 0, C67_CREG_ZERO, C67_B3); // B.S2 B32029 C67_IREG_B_REG(0, C67_CREG_ZERO, C67_B3); // B.S2 B3
2030 C67_POP(S, C67_FP);2030 C67_POP(C67_FP);
2031 C67_ADDK(S, local, C67_SP); // ADDK.L2 loc,SP 2031 C67_ADDK(local, C67_SP); // ADDK.L2 loc,SP
2032 C67_Adjust_ADDK(S, (int *) (cur_text_section->data +2032 C67_Adjust_ADDK((int *) (cur_text_section->data +
2033 func_sub_sp_offset),2033 func_sub_sp_offset),
2034 -local + TotalBytesPushedOnStack);2034 -local + TotalBytesPushedOnStack);
2035 C67_NOP(S, 3); // NOP 2035 C67_NOP(3); // NOP
2036 }2036 }
2037}2037}
2038 2038
2039ST_FUNC void gen_fill_nops(TCCState* S, int bytes)2039ST_FUNC void gen_fill_nops(int bytes)
2040{2040{
2041 if ((bytes & 3))2041 if ((bytes & 3))
2042 tcc_error(S, "alignment of code section not multiple of 4");2042 tcc_error("alignment of code section not multiple of 4");
2043 while (bytes > 0) {2043 while (bytes > 0) {
2044 C67_NOP(S, 4);2044 C67_NOP(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(TCCState* S, int t)2050int gjmp(int t)
2051{2051{
2052 int ind1 = S->tccgen_ind;2052 int ind1 = ind;
2053 if (S->tccgen_nocode_wanted)2053 if (nocode_wanted)
2054 return t;2054 return t;
2055 2055
2056 C67_MVKL(S, C67_A0, t); //r=reg to load, constant2056 C67_MVKL(C67_A0, t); //r=reg to load, constant
2057 C67_MVKH(S, C67_A0, t); //r=reg to load, constant2057 C67_MVKH(C67_A0, t); //r=reg to load, constant
2058 C67_IREG_B_REG(S, 0, C67_CREG_ZERO, C67_A0); // [!R] B.S2x A02058 C67_IREG_B_REG(0, C67_CREG_ZERO, C67_A0); // [!R] B.S2x A0
2059 C67_NOP(S, 5);2059 C67_NOP(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(TCCState* S, int a)2064void gjmp_addr(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(TCCState* S, 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(S, &S->tccgen_char_pointer_type, cur_text_section, a, 0);2073 sym = get_sym_ref(&char_pointer_type, cur_text_section, a, 0);
2074 greloc(S, cur_text_section, sym, S->tccgen_ind, R_C60LO16);2074 greloc(cur_text_section, sym, ind, R_C60LO16);
2075 greloc(S, cur_text_section, sym, S->tccgen_ind + 4, R_C60HI16);2075 greloc(cur_text_section, sym, ind + 4, R_C60HI16);
2076 2076
2077 gjmp(S, 0); // place a zero there later the symbol will be added to it2077 gjmp(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(TCCState* S, int op, int t)2081ST_FUNC int gjmp_cond(int op, int t)
2082{2082{
2083 int ind1;2083 int ind1;
2084 int inv = op & 1;2084 int inv = op & 1;
2085 if (S->tccgen_nocode_wanted)2085 if (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 = S->tccgen_ind;2090 ind1 = ind;
2091 C67_MVKL(S, C67_A0, t); //r=reg to load, constant2091 C67_MVKL(C67_A0, t); //r=reg to load, constant
2092 C67_MVKH(S, C67_A0, t); //r=reg to load, constant2092 C67_MVKH(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(S, C67_compare_reg, C67_B2);2097 C67_MV(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(S, C67_invert_test ^ inv, C67_compare_reg, C67_A0); // [!R] B.S2x A02101 C67_IREG_B_REG(C67_invert_test ^ inv, C67_compare_reg, C67_A0); // [!R] B.S2x A0
2102 C67_NOP(S, 5);2102 C67_NOP(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(TCCState* S, int n0, int t)2108ST_FUNC int gjmp_append(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(TCCState* S, 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(TCCState* S, int op)2132void gen_opi(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(TCCState* S, 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(S, RC_INT_BSIDE, RC_INT); // make sure r (src1) is on the B Side of CPU2149 gv2(RC_INT_BSIDE, RC_INT); // make sure r (src1) is on the B Side of CPU
2150 else2150 else
2151 gv2(S, RC_INT, RC_INT);2151 gv2(RC_INT, RC_INT);
2152 2152
2153 r = S->tccgen_vtop[-1].r;2153 r = vtop[-1].r;
2154 fr = S->tccgen_vtop[0].r;2154 fr = 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(S, r, fr, C67_B2);2160 C67_CMPLT(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(S, r, fr, C67_B2);2163 C67_CMPLT(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(S, r, fr, C67_B2);2166 C67_CMPGT(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(S, r, fr, C67_B2);2169 C67_CMPGT(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(S, r, fr, C67_B2);2172 C67_CMPEQ(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(S, r, fr, C67_B2);2175 C67_CMPEQ(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(S, r, fr, C67_B2);2178 C67_CMPLTU(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(S, r, fr, C67_B2);2181 C67_CMPLTU(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(S, r, fr, C67_B2);2184 C67_CMPGTU(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(S, r, fr, C67_B2);2187 C67_CMPGTU(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(S, fr, r); // ADD r,fr,r2190 C67_ADD(fr, r); // ADD r,fr,r
2191 else if (op == '-')2191 else if (op == '-')
2192 C67_SUB(S, fr, r); // SUB r,fr,r2192 C67_SUB(fr, r); // SUB r,fr,r
2193 else if (op == '&')2193 else if (op == '&')
2194 C67_AND(S, fr, r); // AND r,fr,r2194 C67_AND(fr, r); // AND r,fr,r
2195 else if (op == '|')2195 else if (op == '|')
2196 C67_OR(S, fr, r); // OR r,fr,r2196 C67_OR(fr, r); // OR r,fr,r
2197 else if (op == '^')2197 else if (op == '^')
2198 C67_XOR(S, fr, r); // XOR r,fr,r2198 C67_XOR(fr, r); // XOR r,fr,r
2199 else2199 else
2200 ALWAYS_ASSERT(FALSE);2200 ALWAYS_ASSERT(FALSE);
2201 2201
2202 S->tccgen_vtop--;2202 vtop--;
2203 if (op >= TOK_ULT && op <= TOK_GT)2203 if (op >= TOK_ULT && op <= TOK_GT)
2204 vset_VT_CMP(S, 0x80);2204 vset_VT_CMP(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(TCCState* S, 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(S, RC_INT, RC_INT);2227 gv2(RC_INT, RC_INT);
2228 r = S->tccgen_vtop[-1].r;2228 r = vtop[-1].r;
2229 fr = S->tccgen_vtop[0].r;2229 fr = vtop[0].r;
2230 S->tccgen_vtop--;2230 vtop--;
2231 C67_MPYI(S, fr, r); // 32 bit multiply fr,r,fr2231 C67_MPYI(fr, r); // 32 bit multiply fr,r,fr
2232 C67_NOP(S, 8); // NOP 8 for worst case2232 C67_NOP(8); // NOP 8 for worst case
2233 break;2233 break;
2234 case TOK_SHL:2234 case TOK_SHL:
2235 gv2(S, RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst2235 gv2(RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst
2236 r = S->tccgen_vtop[-1].r;2236 r = vtop[-1].r;
2237 fr = S->tccgen_vtop[0].r;2237 fr = vtop[0].r;
2238 S->tccgen_vtop--;2238 vtop--;
2239 C67_SHL(S, fr, r); // arithmetic/logical shift2239 C67_SHL(fr, r); // arithmetic/logical shift
2240 break;2240 break;
2241 2241
2242 case TOK_SHR:2242 case TOK_SHR:
2243 gv2(S, RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst2243 gv2(RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst
2244 r = S->tccgen_vtop[-1].r;2244 r = vtop[-1].r;
2245 fr = S->tccgen_vtop[0].r;2245 fr = vtop[0].r;
2246 S->tccgen_vtop--;2246 vtop--;
2247 C67_SHRU(S, fr, r); // logical shift2247 C67_SHRU(fr, r); // logical shift
2248 break;2248 break;
2249 2249
2250 case TOK_SAR:2250 case TOK_SAR:
2251 gv2(S, RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst2251 gv2(RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst
2252 r = S->tccgen_vtop[-1].r;2252 r = vtop[-1].r;
2253 fr = S->tccgen_vtop[0].r;2253 fr = vtop[0].r;
2254 S->tccgen_vtop--;2254 vtop--;
2255 C67_SHR(S, fr, r); // arithmetic shift2255 C67_SHR(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(S);2261 vswap();
2262 /* call generic idiv function */2262 /* call generic idiv function */
2263 vpush_helper_func(S, t);2263 vpush_helper_func(t);
2264 vrott(S, 3);2264 vrott(3);
2265 gfunc_call(S, 2);2265 gfunc_call(2);
2266 vpushi(S, 0);2266 vpushi(0);
2267 S->tccgen_vtop->r = REG_IRET;2267 vtop->r = REG_IRET;
2268 S->tccgen_vtop->r2 = VT_CONST;2268 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(TCCState* S, 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(TCCState* S, int op)2290void gen_opf(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(S, RC_EDX, RC_EAX); // make sure src2 is on b side2295 gv2(RC_EDX, RC_EAX); // make sure src2 is on b side
2296 else2296 else
2297 gv2(S, RC_FLOAT, RC_FLOAT); // make sure src2 is on b side2297 gv2(RC_FLOAT, RC_FLOAT); // make sure src2 is on b side
2298 2298
2299 ft = S->tccgen_vtop->type.t;2299 ft = vtop->type.t;
2300 fc = S->tccgen_vtop->c.i;2300 fc = vtop->c.i;
2301 r = S->tccgen_vtop->r;2301 r = vtop->r;
2302 fr = S->tccgen_vtop[-1].r;2302 fr = vtop[-1].r;
2303 2303
2304 2304
2305 if ((ft & VT_BTYPE) == VT_LDOUBLE)2305 if ((ft & VT_BTYPE) == VT_LDOUBLE)
2306 tcc_error(S, "long doubles not supported");2306 tcc_error("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 = S->tccgen_vtop[-1].r;2310 r = vtop[-1].r;
2311 fr = S->tccgen_vtop[0].r;2311 fr = 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(S, r, fr, C67_B2);2317 C67_CMPLTDP(r, fr, C67_B2);
2318 else2318 else
2319 C67_CMPLTSP(S, r, fr, C67_B2);2319 C67_CMPLTSP(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(S, r, fr, C67_B2);2324 C67_CMPLTDP(r, fr, C67_B2);
2325 else2325 else
2326 C67_CMPLTSP(S, r, fr, C67_B2);2326 C67_CMPLTSP(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(S, r, fr, C67_B2);2331 C67_CMPGTDP(r, fr, C67_B2);
2332 else2332 else
2333 C67_CMPGTSP(S, r, fr, C67_B2);2333 C67_CMPGTSP(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(S, r, fr, C67_B2);2338 C67_CMPGTDP(r, fr, C67_B2);
2339 else2339 else
2340 C67_CMPGTSP(S, r, fr, C67_B2);2340 C67_CMPGTSP(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(S, r, fr, C67_B2);2345 C67_CMPEQDP(r, fr, C67_B2);
2346 else2346 else
2347 C67_CMPEQSP(S, r, fr, C67_B2);2347 C67_CMPEQSP(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(S, r, fr, C67_B2);2352 C67_CMPEQDP(r, fr, C67_B2);
2353 else2353 else
2354 C67_CMPEQSP(S, r, fr, C67_B2);2354 C67_CMPEQSP(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(S, 0x80);2360 vset_VT_CMP(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(S, r, fr); // ADD fr,r,fr2364 C67_ADDDP(r, fr); // ADD fr,r,fr
2365 C67_NOP(S, 6);2365 C67_NOP(6);
2366 } else {2366 } else {
2367 C67_ADDSP(S, r, fr); // ADD fr,r,fr2367 C67_ADDSP(r, fr); // ADD fr,r,fr
2368 C67_NOP(S, 3);2368 C67_NOP(3);
2369 }2369 }
2370 S->tccgen_vtop--;2370 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(S, r, fr); // SUB fr,r,fr2373 C67_SUBDP(r, fr); // SUB fr,r,fr
2374 C67_NOP(S, 6);2374 C67_NOP(6);
2375 } else {2375 } else {
2376 C67_SUBSP(S, r, fr); // SUB fr,r,fr2376 C67_SUBSP(r, fr); // SUB fr,r,fr
2377 C67_NOP(S, 3);2377 C67_NOP(3);
2378 }2378 }
2379 S->tccgen_vtop--;2379 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(S, r, fr); // MPY fr,r,fr2382 C67_MPYDP(r, fr); // MPY fr,r,fr
2383 C67_NOP(S, 9);2383 C67_NOP(9);
2384 } else {2384 } else {
2385 C67_MPYSP(S, r, fr); // MPY fr,r,fr2385 C67_MPYSP(r, fr); // MPY fr,r,fr
2386 C67_NOP(S, 3);2386 C67_NOP(3);
2387 }2387 }
2388 S->tccgen_vtop--;2388 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(S);2392 vswap();
2393 /* call generic idiv function */2393 /* call generic idiv function */
2394 vpush_helper_func(S, TOK__divd);2394 vpush_helper_func(TOK__divd);
2395 vrott(S, 3);2395 vrott(3);
2396 gfunc_call(S, 2);2396 gfunc_call(2);
2397 vpushi(S, 0);2397 vpushi(0);
2398 S->tccgen_vtop->r = REG_FRET;2398 vtop->r = REG_FRET;
2399 S->tccgen_vtop->r2 = REG_IRE2;2399 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(S);2403 vswap();
2404 /* call generic idiv function */2404 /* call generic idiv function */
2405 vpush_helper_func(S, TOK__divf);2405 vpush_helper_func(TOK__divf);
2406 vrott(S, 3);2406 vrott(3);
2407 gfunc_call(S, 2);2407 gfunc_call(2);
2408 vpushi(S, 0);2408 vpushi(0);
2409 S->tccgen_vtop->r = REG_FRET;2409 vtop->r = REG_FRET;
2410 S->tccgen_vtop->r2 = VT_CONST;2410 vtop->r2 = VT_CONST;
2411 }2411 }
2412 } else2412 } else
2413 ALWAYS_ASSERT(FALSE);2413 ALWAYS_ASSERT(FALSE);
@@ -2419,122 +2419,122 @@ void gen_opf(TCCState* S, 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(TCCState* S, int t)2422void gen_cvt_itof(int t)
2423{2423{
2424 int r;2424 int r;
2425 2425
2426 gv(S, RC_INT);2426 gv(RC_INT);
2427 r = S->tccgen_vtop->r;2427 r = 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(S, r, r);2431 C67_INTDPU(r, r);
2432 else2432 else
2433 C67_INTDP(S, r, r);2433 C67_INTDP(r, r);
2434 2434
2435 C67_NOP(S, 4);2435 C67_NOP(4);
2436 S->tccgen_vtop->type.t = VT_DOUBLE;2436 vtop->type.t = VT_DOUBLE;
2437 } else {2437 } else {
2438 if (t & VT_UNSIGNED)2438 if (t & VT_UNSIGNED)
2439 C67_INTSPU(S, r, r);2439 C67_INTSPU(r, r);
2440 else2440 else
2441 C67_INTSP(S, r, r);2441 C67_INTSP(r, r);
2442 C67_NOP(S, 3);2442 C67_NOP(3);
2443 S->tccgen_vtop->type.t = VT_FLOAT;2443 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(TCCState* S, int t)2450void gen_cvt_ftoi(int t)
2451{2451{
2452 int r;2452 int r;
2453 2453
2454 gv(S, RC_FLOAT);2454 gv(RC_FLOAT);
2455 r = S->tccgen_vtop->r;2455 r = vtop->r;
2456 2456
2457 if (t != VT_INT)2457 if (t != VT_INT)
2458 tcc_error(S, "long long not supported");2458 tcc_error("long long not supported");
2459 else {2459 else {
2460 if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_DOUBLE) {2460 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) {
2461 C67_DPTRUNC(S, r, r);2461 C67_DPTRUNC(r, r);
2462 C67_NOP(S, 3);2462 C67_NOP(3);
2463 } else {2463 } else {
2464 C67_SPTRUNC(S, r, r);2464 C67_SPTRUNC(r, r);
2465 C67_NOP(S, 3);2465 C67_NOP(3);
2466 }2466 }
2467 2467
2468 S->tccgen_vtop->type.t = VT_INT;2468 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(TCCState* S, int t)2474void gen_cvt_ftof(int t)
2475{2475{
2476 int r, r2;2476 int r, r2;
2477 2477
2478 if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_DOUBLE &&2478 if ((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(S, RC_FLOAT); // get it in a register pair2482 gv(RC_FLOAT); // get it in a register pair
2483 2483
2484 r = S->tccgen_vtop->r;2484 r = vtop->r;
2485 2485
2486 C67_DPSP(S, r, r); // convert it to SP same register2486 C67_DPSP(r, r); // convert it to SP same register
2487 C67_NOP(S, 3);2487 C67_NOP(3);
2488 2488
2489 S->tccgen_vtop->type.t = VT_FLOAT;2489 vtop->type.t = VT_FLOAT;
2490 S->tccgen_vtop->r2 = VT_CONST; // set this as unused2490 vtop->r2 = VT_CONST; // set this as unused
2491 } else if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_FLOAT &&2491 } else if ((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(S, RC_FLOAT); // get it in a register2495 gv(RC_FLOAT); // get it in a register
2496 2496
2497 r = S->tccgen_vtop->r;2497 r = 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(S, RC_ECX);2500 r2 = get_reg(RC_ECX);
2501 } else if (r == TREG_EDX) {2501 } else if (r == TREG_EDX) {
2502 r2 = get_reg(S, RC_ST0);2502 r2 = get_reg(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(S, r, r); // convert it to DP same register2508 C67_SPDP(r, r); // convert it to DP same register
2509 C67_NOP(S, 1);2509 C67_NOP(1);
2510 2510
2511 S->tccgen_vtop->type.t = VT_DOUBLE;2511 vtop->type.t = VT_DOUBLE;
2512 S->tccgen_vtop->r2 = r2; // set this as unused2512 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(TCCState* S)2519void ggoto(void)
2520{2520{
2521 gcall_or_jmp(S, 1);2521 gcall_or_jmp(1);
2522 S->tccgen_vtop--;2522 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(TCCState* S, int addr) {2526ST_FUNC void gen_vla_sp_save(int addr) {
2527 tcc_error(S, "variable length arrays unsupported for this target");2527 tcc_error("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(TCCState* S, int addr) {2531ST_FUNC void gen_vla_sp_restore(int addr) {
2532 tcc_error(S, "variable length arrays unsupported for this target");2532 tcc_error("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(TCCState* S, CType *type, int align) {2536ST_FUNC void gen_vla_alloc(CType *type, int align) {
2537 tcc_error(S, "variable length arrays unsupported for this target");2537 tcc_error("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 *S, unsigned got_offset, struct sym_attr *attr)68ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
69{69{
70 tcc_error(S, "C67 got not implemented");70 tcc_error("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 *S)76ST_FUNC void relocate_plt(TCCState *s1)
77{77{
78 uint8_t *p, *p_end;78 uint8_t *p, *p_end;
79 79
80 if (!S->plt)80 if (!s1->plt)
81 return;81 return;
82 82
83 p = S->plt->data;83 p = s1->plt->data;
84 p_end = p + S->plt->data_offset;84 p_end = p + s1->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 *S) · 3 unmodified lines
91 }91 }
92}92}
93 93
94void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)94void relocate(TCCState *s1, 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 *S)256static inline int get_reg_shift(TCCState *s1)
257{257{
258 int shift, v;258 int shift, v;
259 v = asm_int_expr(S);259 v = asm_int_expr(s1);
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 *S) · 8 unmodified lines
271 shift = 3;271 shift = 3;
272 break;272 break;
273 default:273 default:
274 expect(S, "1, 2, 4 or 8 constant");274 expect("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 *S) · 1 unmodified line
279}279}
280 280
281#ifdef TCC_TARGET_X86_64281#ifdef TCC_TARGET_X86_64
282static int asm_parse_numeric_reg(TCCState *S, int t, unsigned int *type)282static int asm_parse_numeric_reg(int t, unsigned int *type)
283{283{
284 int reg = -1;284 int reg = -1;
285 if (t >= TOK_IDENT && t < S->tccpp_tok_ident) {285 if (t >= TOK_IDENT && t < tok_ident) {
286 const char *s = S->tccpp_table_ident[t - TOK_IDENT]->str;286 const char *s = 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(TCCState *S, int t, unsigned int *type) · 28 unmodified lines
318}318}
319#endif319#endif
320 320
321static int asm_parse_reg(TCCState* S, unsigned int *type)321static int asm_parse_reg(unsigned int *type)
322{322{
323 int reg = 0;323 int reg = 0;
324 *type = 0;324 *type = 0;
325 if (S->tccpp_tok != '%')325 if (tok != '%')
326 goto error_32;326 goto error_32;
327 next(S);327 next();
328 if (S->tccpp_tok >= TOK_ASM_eax && S->tccpp_tok <= TOK_ASM_edi) {328 if (tok >= TOK_ASM_eax && tok <= TOK_ASM_edi) {
329 reg = S->tccpp_tok - TOK_ASM_eax;329 reg = 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 (S->tccpp_tok >= TOK_ASM_rax && S->tccpp_tok <= TOK_ASM_rdi) {332 } else if (tok >= TOK_ASM_rax && tok <= TOK_ASM_rdi) {
333 reg = S->tccpp_tok - TOK_ASM_rax;333 reg = tok - TOK_ASM_rax;
334 *type = OP_REG64;334 *type = OP_REG64;
335 } else if (S->tccpp_tok == TOK_ASM_rip) {335 } else if (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(S, S->tccpp_tok, type)) >= 0338 } else if ((reg = asm_parse_numeric_reg(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(S, "register");344 expect("register");
345 }345 }
346 next(S);346 next();
347 return reg;347 return reg;
348}348}
349 349
350static void parse_operand(TCCState *S, Operand *op)350static void parse_operand(TCCState *s1, 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 (S->tccpp_tok == '*') {357 if (tok == '*') {
358 next(S);358 next();
359 indir = OP_INDIR;359 indir = OP_INDIR;
360 }360 }
361 361
362 if (S->tccpp_tok == '%') {362 if (tok == '%') {
363 next(S);363 next();
364 if (S->tccpp_tok >= TOK_ASM_al && S->tccpp_tok <= TOK_ASM_db7) {364 if (tok >= TOK_ASM_al && tok <= TOK_ASM_db7) {
365 reg = S->tccpp_tok - TOK_ASM_al;365 reg = 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 *S, 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 (S->tccpp_tok >= TOK_ASM_dr0 && S->tccpp_tok <= TOK_ASM_dr7) {374 } else if (tok >= TOK_ASM_dr0 && tok <= TOK_ASM_dr7) {
375 op->type = OP_DB;375 op->type = OP_DB;
376 op->reg = S->tccpp_tok - TOK_ASM_dr0;376 op->reg = tok - TOK_ASM_dr0;
377 } else if (S->tccpp_tok >= TOK_ASM_es && S->tccpp_tok <= TOK_ASM_gs) {377 } else if (tok >= TOK_ASM_es && tok <= TOK_ASM_gs) {
378 op->type = OP_SEG;378 op->type = OP_SEG;
379 op->reg = S->tccpp_tok - TOK_ASM_es;379 op->reg = tok - TOK_ASM_es;
380 } else if (S->tccpp_tok == TOK_ASM_st) {380 } else if (tok == TOK_ASM_st) {
381 op->type = OP_ST;381 op->type = OP_ST;
382 op->reg = 0;382 op->reg = 0;
383 next(S);383 next();
384 if (S->tccpp_tok == '(') {384 if (tok == '(') {
385 next(S);385 next();
386 if (S->tccpp_tok != TOK_PPNUM)386 if (tok != TOK_PPNUM)
387 goto reg_error;387 goto reg_error;
388 p = S->tccpp_tokc.str.data;388 p = 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(S);393 next();
394 skip(S, ')');394 skip(')');
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 (S->tccpp_tok >= TOK_ASM_spl && S->tccpp_tok <= TOK_ASM_dil) {400 } else if (tok >= TOK_ASM_spl && tok <= TOK_ASM_dil) {
401 op->type = OP_REG8 | OP_REG8_LOW;401 op->type = OP_REG8 | OP_REG8_LOW;
402 op->reg = 4 + S->tccpp_tok - TOK_ASM_spl;402 op->reg = 4 + tok - TOK_ASM_spl;
403 } else if ((op->reg = asm_parse_numeric_reg(S, S->tccpp_tok, &op->type)) >= 0) {403 } else if ((op->reg = asm_parse_numeric_reg(tok, &op->type)) >= 0) {
404 ;404 ;
405#endif405#endif
406 } else {406 } else {
407 reg_error:407 reg_error:
408 tcc_error(S, "unknown register %%%s", get_tok_str(S, S->tccpp_tok, &S->tccpp_tokc));408 tcc_error("unknown register %%%s", get_tok_str(tok, &tokc));
409 }409 }
410 next(S);410 next();
411 no_skip: ;411 no_skip: ;
412 } else if (S->tccpp_tok == '$') {412 } else if (tok == '$') {
413 /* constant value */413 /* constant value */
414 next(S);414 next();
415 asm_expr(S, &e);415 asm_expr(s1, &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 *S, 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 (S->tccpp_tok != '(') {436 if (tok != '(') {
437 asm_expr(S, &e);437 asm_expr(s1, &e);
438 op->e = e;438 op->e = e;
439 } else {439 } else {
440 next(S);440 next();
441 if (S->tccpp_tok == '%') {441 if (tok == '%') {
442 unget_tok(S, '(');442 unget_tok('(');
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(S, &e);447 asm_expr(s1, &e);
448 if (S->tccpp_tok != ')')448 if (tok != ')')
449 expect(S, ")");449 expect(")");
450 next(S);450 next();
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 (S->tccpp_tok == '(') {456 if (tok == '(') {
457 unsigned int type = 0;457 unsigned int type = 0;
458 next(S);458 next();
459 if (S->tccpp_tok != ',') {459 if (tok != ',') {
460 op->reg = asm_parse_reg(S, &type);460 op->reg = asm_parse_reg(&type);
461 }461 }
462 if (S->tccpp_tok == ',') {462 if (tok == ',') {
463 next(S);463 next();
464 if (S->tccpp_tok != ',') {464 if (tok != ',') {
465 op->reg2 = asm_parse_reg(S, &type);465 op->reg2 = asm_parse_reg(&type);
466 }466 }
467 if (S->tccpp_tok == ',') {467 if (tok == ',') {
468 next(S);468 next();
469 op->shift = get_reg_shift(S);469 op->shift = get_reg_shift(s1);
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(S, ')');474 skip(')');
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 *S, 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(TCCState* S, ExprValue *pe)483ST_FUNC void gen_expr32(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(S, VT_SYM, pe->sym, pe->v);488 gen_addrpc32(VT_SYM, pe->sym, pe->v);
489 else489 else
490 gen_addr32(S, pe->sym ? VT_SYM : 0, pe->sym, pe->v);490 gen_addr32(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(TCCState* S, ExprValue *pe)494ST_FUNC void gen_expr64(ExprValue *pe)
495{495{
496 gen_addr64(S, pe->sym ? VT_SYM : 0, pe->sym, pe->v);496 gen_addr64(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(TCCState* S, ExprValue *pe)501static void gen_disp32(ExprValue *pe)
502{502{
503 Sym *sym = pe->sym;503 Sym *sym = pe->sym;
504 ElfSym *esym = elfsym(S, sym);504 ElfSym *esym = elfsym(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(S, pe->v + esym->st_value - S->tccgen_ind - 4);510 gen_le32(pe->v + esym->st_value - 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(S, VT_SYM, sym, pe->v);516 gen_addrpc32(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(TCCState* S, int reg, Operand *op)521static inline int asm_modrm(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(S, 0xc0 + (reg << 3) + op->reg);526 g(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(S, 0x04 + (reg << 3));530 g(0x04 + (reg << 3));
531 g(S, 0x25);531 g(0x25);
532#else532#else
533 g(S, 0x05 + (reg << 3));533 g(0x05 + (reg << 3));
534#endif534#endif
535 gen_expr32(S, &op->e);535 gen_expr32(&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(S, 0x05 + (reg << 3));539 g(0x05 + (reg << 3));
540 gen_addrpc32(S, pe->sym ? VT_SYM : 0, pe->sym, pe->v);540 gen_addrpc32(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
541 return S->tccgen_ind;541 return 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(TCCState* S, 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(S, mod + (reg << 3) + reg1);560 g(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(S, (op->shift << 6) + (reg2 << 3) + sib_reg1);566 g((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(S, op->e.v);570 g(op->e.v);
571 } else if (mod == 0x80 || op->reg == -1) {571 } else if (mod == 0x80 || op->reg == -1) {
572 gen_expr32(S, &op->e);572 gen_expr32(&op->e);
573 }573 }
574 }574 }
575 return 0;575 return 0;
@@ -581,7 +581,7 @@ static inline int asm_modrm(TCCState* S, 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(TCCState* S, int width64, Operand *ops, int nb_ops, int *op_type,584static void asm_rex(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(TCCState* S, int width64, Operand *ops, int nb_ops, int *op_ · 43 unmodified lines
631 }631 }
632 if (rex) {632 if (rex) {
633 if (saw_high_8bit)633 if (saw_high_8bit)
634 tcc_error(S, "can't encode register %%%ch when REX prefix is required",634 tcc_error("can't encode register %%%ch when REX prefix is required",
635 "acdb"[saw_high_8bit-4]);635 "acdb"[saw_high_8bit-4]);
636 g(S, rex);636 g(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 *S, int opcode)682ST_FUNC void asm_opcode(TCCState *s1, 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 *S, 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(S, ';');700 unget_tok(';');
701 701
702 /* get operands */702 /* get operands */
703 pop = ops;703 pop = ops;
@@ -705,27 +705,27 @@ ST_FUNC void asm_opcode(TCCState *S, 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 (S->tccpp_tok == ';' || S->tccpp_tok == TOK_LINEFEED)708 if (tok == ';' || tok == TOK_LINEFEED)
709 break;709 break;
710 if (nb_ops >= MAX_OPERANDS) {710 if (nb_ops >= MAX_OPERANDS) {
711 tcc_error(S, "incorrect number of operands");711 tcc_error("incorrect number of operands");
712 }712 }
713 parse_operand(S, pop);713 parse_operand(s1, pop);
714 if (S->tccpp_tok == ':') {714 if (tok == ':') {
715 if (pop->type != OP_SEG || seg_prefix)715 if (pop->type != OP_SEG || seg_prefix)
716 tcc_error(S, "incorrect prefix");716 tcc_error("incorrect prefix");
717 seg_prefix = segment_prefixes[pop->reg];717 seg_prefix = segment_prefixes[pop->reg];
718 next(S);718 next();
719 parse_operand(S, pop);719 parse_operand(s1, pop);
720 if (!(pop->type & OP_EA)) {720 if (!(pop->type & OP_EA)) {
721 tcc_error(S, "segment prefix must be followed by memory reference");721 tcc_error("segment prefix must be followed by memory reference");
722 }722 }
723 }723 }
724 pop++;724 pop++;
725 nb_ops++;725 nb_ops++;
726 if (S->tccpp_tok != ',')726 if (tok != ',')
727 break;727 break;
728 next(S);728 next();
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(S, b >> 8);845 g(b >> 8);
846 g(S, b);846 g(b);
847 return;847 return;
848 } else if (opcode <= TOK_ASM_alllast) {848 } else if (opcode <= TOK_ASM_alllast) {
849 tcc_error(S, "bad operand with opcode '%s'",849 tcc_error("bad operand with opcode '%s'",
850 get_tok_str(S, opcode, NULL));850 get_tok_str(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 = S->tccpp_table_ident[opcode - TOK_IDENT];854 TokenSym *ts = 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(S, ts->str, ts->len-1)->tok;858 opcode = tok_alloc(ts->str, ts->len-1)->tok;
859 goto again;859 goto again;
860 }860 }
861 tcc_error(S, "unknown opcode '%s'", ts->str);861 tcc_error("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(S, "cannot infer opcode suffix");889 tcc_error("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(S, 0x67);897 g(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(S, 0x66);916 g(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(S, 0x9b);946 g(0x9b);
947 if (seg_prefix)947 if (seg_prefix)
948 g(S, seg_prefix);948 g(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(S, "bad op table");1001 tcc_error("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 (S, rex64, ops, nb_ops, op_type, modreg_index, modrm_index);1017 asm_rex (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(S, ops[0].e.sym);1038 esym = elfsym(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 - S->tccgen_ind - 2 - (v >= 0xff);1041 jmp_disp = ops[0].e.v + esym->st_value - 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(S, "invalid displacement");1056 tcc_error("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(S, op1);1063 g(op1);
1064 op1 = (v >> 8) & 0xff;1064 op1 = (v >> 8) & 0xff;
1065 if (op1)1065 if (op1)
1066 g(S, op1);1066 g(op1);
1067 g(S, v);1067 g(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(S, reg, &ops[modrm_index]);1087 pc = asm_modrm(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(S, &ops[1].e);1095 gen_expr32(&ops[1].e);
1096 if (ops[0].e.sym)1096 if (ops[0].e.sym)
1097 tcc_error(S, "cannot relocate");1097 tcc_error("cannot relocate");
1098 gen_le16(S, ops[0].e.v);1098 gen_le16(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(S, "cannot relocate");1119 tcc_error("cannot relocate");
1120 1120
1121 if (v & (OP_IM8 | OP_IM8S)) {1121 if (v & (OP_IM8 | OP_IM8S)) {
1122 g(S, ops[i].e.v);1122 g(ops[i].e.v);
1123 } else if (v & OP_IM16) {1123 } else if (v & OP_IM16) {
1124 gen_le16(S, ops[i].e.v);1124 gen_le16(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(S, &ops[i].e);1127 gen_expr64(&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(S, &ops[i].e);1130 gen_disp32(&ops[i].e);
1131 } else {1131 } else {
1132 gen_expr32(S, &ops[i].e);1132 gen_expr32(&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 - S->tccgen_ind);1139 add32le(cur_text_section->data + pc - 4, pc - 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(TCCState* S, const char *str)1144static inline int constraint_priority(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(TCCState* S, const char *str) · 34 unmodified lines
1182 pr = 4;1182 pr = 4;
1183 break;1183 break;
1184 default:1184 default:
1185 tcc_error(S, "unknown constraint '%c'", c);1185 tcc_error("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 (TCCState* S, int t)1203ST_FUNC int asm_parse_regvar (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 = S->tccpp_table_ident[t - TOK_IDENT]->str;1209 s = 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, s + 1);1212 t = tok_alloc_const(s + 1);
1213 unget_tok(S, t);1213 unget_tok(t);
1214 unget_tok(S, '%');1214 unget_tok('%');
1215 parse_operand(S, &op);1215 parse_operand(tcc_state, &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 (TCCState* S, 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(TCCState* S, ASMOperand *operands,1228ST_FUNC void asm_compute_constraints(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(TCCState* S, 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(S, operands, nb_operands, str, NULL);1256 k = find_constraint(operands, nb_operands, str, NULL);
1257 if ((unsigned)k >= i || i < nb_outputs)1257 if ((unsigned)k >= i || i < nb_outputs)
1258 tcc_error(S, "invalid reference in constraint %d ('%s')",1258 tcc_error("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(S, "cannot reference twice the same operand");1262 tcc_error("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(TCCState* S, 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(S, str);1271 op->priority = constraint_priority(str);
1272 }1272 }
1273 }1273 }
1274 1274
@@ -1316,7 +1316,7 @@ ST_FUNC void asm_compute_constraints(TCCState* S, 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(S, "asm regvar requests register that's taken already");1319 tcc_error("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(TCCState* S, 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(S, "'%c' modifier can only be applied to outputs", c);1333 tcc_error("'%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(TCCState* S, ASMOperand *operands, · 87 unmodified lines
1424 }1424 }
1425 break;1425 break;
1426 default:1426 default:
1427 tcc_error(S, "asm constraint %d ('%s') could not be satisfied",1427 tcc_error("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(TCCState* S, 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(S, "could not find free output register for reloading");1450 tcc_error("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(TCCState* S, 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(S, op->id, NULL) : "",1464 op->id ? get_tok_str(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(TCCState* S, ASMOperand *operands, · 3 unmodified lines
1471#endif1471#endif
1472}1472}
1473 1473
1474ST_FUNC void subst_asm_operand(TCCState* S, CString *add_str,1474ST_FUNC void subst_asm_operand(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(TCCState* S, 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(S, add_str, '$');1484 cstr_ccat(add_str, '$');
1485 if (r & VT_SYM) {1485 if (r & VT_SYM) {
1486 const char *name = get_tok_str(S, sv->sym->v, NULL);1486 const char *name = get_tok_str(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(S, tok_alloc_const(S, name), sv->sym);1493 get_asm_sym(tok_alloc_const(name), sv->sym);
1494 }1494 }
1495 if (S->leading_underscore)1495 if (tcc_state->leading_underscore)
1496 cstr_ccat(S, add_str, '_');1496 cstr_ccat(add_str, '_');
1497 cstr_cat(S, add_str, name, -1);1497 cstr_cat(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(S, add_str, '+');1500 cstr_ccat(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(S, add_str, buf, -1);1506 cstr_cat(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(S, add_str, "(%rip)", -1);1510 cstr_cat(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(TCCState* S, 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(S, add_str, buf, -1);1518 cstr_cat(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(S, "");1522 tcc_internal_error("");
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(S, TOK_ASM_rax + reg, NULL)1525 get_tok_str(TOK_ASM_rax + reg, NULL)
1526#else1526#else
1527 get_tok_str(S, TOK_ASM_eax + reg, NULL)1527 get_tok_str(TOK_ASM_eax + reg, NULL)
1528#endif1528#endif
1529 );1529 );
1530 cstr_cat(S, add_str, buf, -1);1530 cstr_cat(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(S, "");1535 tcc_internal_error("");
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(TCCState* S, 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(S, "cannot use byte register");1555 tcc_error("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(S, "cannot use byte register");1559 tcc_error("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(TCCState* S, CString *add_str, · 24 unmodified lines
1587 break;1587 break;
1588#endif1588#endif
1589 }1589 }
1590 snprintf(buf, sizeof(buf), "%%%s", get_tok_str(S, reg, NULL));1590 snprintf(buf, sizeof(buf), "%%%s", get_tok_str(reg, NULL));
1591 cstr_cat(S, add_str, buf, -1);1591 cstr_cat(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(TCCState* S, ASMOperand *operands, int nb_operands,1596ST_FUNC void asm_gen_code(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(TCCState* S, 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(S, 0x41), reg-=8;1630 g(0x41), reg-=8;
1631 g(S, 0x50 + reg);1631 g(0x50 + reg);
1632 }1632 }
1633 }1633 }
1634 1634
@@ -1644,15 +1644,15 @@ ST_FUNC void asm_gen_code(TCCState* S, 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(S, op->reg, &sv);1647 load(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(S, op->reg, op->vt);1650 load(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(S, TREG_XDX, &sv);1655 load(TREG_XDX, &sv);
1656 }1656 }
1657 }1657 }
1658 }1658 }
@@ -1668,19 +1668,19 @@ ST_FUNC void asm_gen_code(TCCState* S, 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(S, out_reg, &sv);1671 load(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(S, op->reg, &sv);1675 store(op->reg, &sv);
1676 }1676 }
1677 } else {1677 } else {
1678 store(S, op->reg, op->vt);1678 store(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(S, TREG_XDX, &sv);1683 store(TREG_XDX, &sv);
1684 }1684 }
1685 }1685 }
1686 }1686 }
@@ -1690,14 +1690,14 @@ ST_FUNC void asm_gen_code(TCCState* S, 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(S, 0x41), reg-=8;1693 g(0x41), reg-=8;
1694 g(S, 0x58 + reg);1694 g(0x58 + reg);
1695 }1695 }
1696 }1696 }
1697 }1697 }
1698}1698}
1699 1699
1700ST_FUNC void asm_clobber(TCCState* S, uint8_t *clobber_regs, const char *str)1700ST_FUNC void asm_clobber(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(TCCState* S, 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(S, str);1711 reg = tok_alloc_const(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(TCCState* S, 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(S, reg, &type)) >= 0) {1719 } else if ((reg = asm_parse_numeric_reg(reg, &type)) >= 0) {
1720 ;1720 ;
1721#endif1721#endif
1722 } else {1722 } else {
1723 tcc_error(S, "invalid clobber register '%s'", str);1723 tcc_error("invalid clobber register '%s'", str);
1724 }1724 }
1725 clobber_regs[reg] = 1;1725 clobber_regs[reg] = 1;
1726}1726}
i386-gen.c+368−365
@@ -100,47 +100,50 @@ 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 void gen_bounds_prolog(TCCState* S);103static addr_t func_bound_offset;
104static void gen_bounds_epilog(TCCState* S);104static unsigned long func_bound_ind;
105ST_DATA int func_bound_add_epilog;
106static void gen_bounds_prolog(void);
107static void gen_bounds_epilog(void);
105#endif108#endif
106 109
107/* XXX: make it faster ? */110/* XXX: make it faster ? */
108ST_FUNC void g(TCCState* S, int c)111ST_FUNC void g(int c)
109{112{
110 int ind1;113 int ind1;
111 if (S->tccgen_nocode_wanted)114 if (nocode_wanted)
112 return;115 return;
113 ind1 = S->tccgen_ind + 1;116 ind1 = ind + 1;
114 if (ind1 > cur_text_section->data_allocated)117 if (ind1 > cur_text_section->data_allocated)
115 section_realloc(S, cur_text_section, ind1);118 section_realloc(cur_text_section, ind1);
116 cur_text_section->data[S->tccgen_ind] = c;119 cur_text_section->data[ind] = c;
117 S->tccgen_ind = ind1;120 ind = ind1;
118}121}
119 122
120ST_FUNC void o(TCCState* S, unsigned int c)123ST_FUNC void o(unsigned int c)
121{124{
122 while (c) {125 while (c) {
123 g(S, c);126 g(c);
124 c = c >> 8;127 c = c >> 8;
125 }128 }
126}129}
127 130
128ST_FUNC void gen_le16(TCCState* S, int v)131ST_FUNC void gen_le16(int v)
129{132{
130 g(S, v);133 g(v);
131 g(S, v >> 8);134 g(v >> 8);
132}135}
133 136
134ST_FUNC void gen_le32(TCCState* S, int c)137ST_FUNC void gen_le32(int c)
135{138{
136 g(S, c);139 g(c);
137 g(S, c >> 8);140 g(c >> 8);
138 g(S, c >> 16);141 g(c >> 16);
139 g(S, c >> 24);142 g(c >> 24);
140}143}
141 144
142/* output a symbol and patch all calls to it */145/* output a symbol and patch all calls to it */
143ST_FUNC void gsym_addr(TCCState* S, int t, int a)146ST_FUNC void gsym_addr(int t, int a)
144{147{
145 while (t) {148 while (t) {
146 unsigned char *ptr = cur_text_section->data + t;149 unsigned char *ptr = cur_text_section->data + t;
@@ -151,73 +154,73 @@ ST_FUNC void gsym_addr(TCCState* S, int t, int a) · 4 unmodified lines
151}154}
152 155
153/* instruction + 4 bytes data. Return the address of the data */156/* instruction + 4 bytes data. Return the address of the data */
154static int oad(TCCState* S, int c, int s)157static int oad(int c, int s)
155{158{
156 int t;159 int t;
157 if (S->tccgen_nocode_wanted)160 if (nocode_wanted)
158 return s;161 return s;
159 o(S, c);162 o(c);
160 t = S->tccgen_ind;163 t = ind;
161 gen_le32(S, s);164 gen_le32(s);
162 return t;165 return t;
163}166}
164 167
165ST_FUNC void gen_fill_nops(TCCState* S, int bytes)168ST_FUNC void gen_fill_nops(int bytes)
166{169{
167 while (bytes--)170 while (bytes--)
168 g(S, 0x90);171 g(0x90);
169}172}
170 173
171/* generate jmp to a label */174/* generate jmp to a label */
172#define gjmp2(s, instr,lbl) oad(s, instr,lbl)175#define gjmp2(instr,lbl) oad(instr,lbl)
173 176
174/* output constant with relocation if 'r & VT_SYM' is true */177/* output constant with relocation if 'r & VT_SYM' is true */
175ST_FUNC void gen_addr32(TCCState* S, int r, Sym *sym, int c)178ST_FUNC void gen_addr32(int r, Sym *sym, int c)
176{179{
177 if (r & VT_SYM)180 if (r & VT_SYM)
178 greloc(S, cur_text_section, sym, S->tccgen_ind, R_386_32);181 greloc(cur_text_section, sym, ind, R_386_32);
179 gen_le32(S, c);182 gen_le32(c);
180}183}
181 184
182ST_FUNC void gen_addrpc32(TCCState* S, int r, Sym *sym, int c)185ST_FUNC void gen_addrpc32(int r, Sym *sym, int c)
183{186{
184 if (r & VT_SYM)187 if (r & VT_SYM)
185 greloc(S, cur_text_section, sym, S->tccgen_ind, R_386_PC32);188 greloc(cur_text_section, sym, ind, R_386_PC32);
186 gen_le32(S, c - 4);189 gen_le32(c - 4);
187}190}
188 191
189/* generate a modrm reference. 'op_reg' contains the additional 3192/* generate a modrm reference. 'op_reg' contains the additional 3
190 opcode bits */193 opcode bits */
191static void gen_modrm(TCCState* S, int op_reg, int r, Sym *sym, int c)194static void gen_modrm(int op_reg, int r, Sym *sym, int c)
192{195{
193 op_reg = op_reg << 3;196 op_reg = op_reg << 3;
194 if ((r & VT_VALMASK) == VT_CONST) {197 if ((r & VT_VALMASK) == VT_CONST) {
195 /* constant memory reference */198 /* constant memory reference */
196 o(S, 0x05 | op_reg);199 o(0x05 | op_reg);
197 gen_addr32(S, r, sym, c);200 gen_addr32(r, sym, c);
198 } else if ((r & VT_VALMASK) == VT_LOCAL) {201 } else if ((r & VT_VALMASK) == VT_LOCAL) {
199 /* currently, we use only ebp as base */202 /* currently, we use only ebp as base */
200 if (c == (char)c) {203 if (c == (char)c) {
201 /* short reference */204 /* short reference */
202 o(S, 0x45 | op_reg);205 o(0x45 | op_reg);
203 g(S, c);206 g(c);
204 } else {207 } else {
205 oad(S, 0x85 | op_reg, c);208 oad(0x85 | op_reg, c);
206 }209 }
207 } else {210 } else {
208 g(S, 0x00 | op_reg | (r & VT_VALMASK));211 g(0x00 | op_reg | (r & VT_VALMASK));
209 }212 }
210}213}
211 214
212/* load 'r' from value 'sv' */215/* load 'r' from value 'sv' */
213ST_FUNC void load(TCCState* S, int r, SValue *sv)216ST_FUNC void load(int r, SValue *sv)
214{217{
215 int v, t, ft, fc, fr;218 int v, t, ft, fc, fr;
216 SValue v1;219 SValue v1;
217 220
218#ifdef TCC_TARGET_PE221#ifdef TCC_TARGET_PE
219 SValue v2;222 SValue v2;
220 sv = pe_getimport(S, sv, &v2);223 sv = pe_getimport(sv, &v2);
221#endif224#endif
222 225
223 fr = sv->r;226 fr = sv->r;
@@ -235,68 +238,68 @@ ST_FUNC void load(TCCState* S, int r, SValue *sv) · 11 unmodified lines
235 v1.sym = NULL;238 v1.sym = NULL;
236 fr = r;239 fr = r;
237 if (!(reg_classes[fr] & RC_INT))240 if (!(reg_classes[fr] & RC_INT))
238 fr = get_reg(S, RC_INT);241 fr = get_reg(RC_INT);
239 load(S, fr, &v1);242 load(fr, &v1);
240 }243 }
241 if ((ft & VT_BTYPE) == VT_FLOAT) {244 if ((ft & VT_BTYPE) == VT_FLOAT) {
242 o(S, 0xd9); /* flds */245 o(0xd9); /* flds */
243 r = 0;246 r = 0;
244 } else if ((ft & VT_BTYPE) == VT_DOUBLE) {247 } else if ((ft & VT_BTYPE) == VT_DOUBLE) {
245 o(S, 0xdd); /* fldl */248 o(0xdd); /* fldl */
246 r = 0;249 r = 0;
247 } else if ((ft & VT_BTYPE) == VT_LDOUBLE) {250 } else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
248 o(S, 0xdb); /* fldt */251 o(0xdb); /* fldt */
249 r = 5;252 r = 5;
250 } else if ((ft & VT_TYPE) == VT_BYTE || (ft & VT_TYPE) == VT_BOOL) {253 } else if ((ft & VT_TYPE) == VT_BYTE || (ft & VT_TYPE) == VT_BOOL) {
251 o(S, 0xbe0f); /* movsbl */254 o(0xbe0f); /* movsbl */
252 } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {255 } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
253 o(S, 0xb60f); /* movzbl */256 o(0xb60f); /* movzbl */
254 } else if ((ft & VT_TYPE) == VT_SHORT) {257 } else if ((ft & VT_TYPE) == VT_SHORT) {
255 o(S, 0xbf0f); /* movswl */258 o(0xbf0f); /* movswl */
256 } else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) {259 } else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) {
257 o(S, 0xb70f); /* movzwl */260 o(0xb70f); /* movzwl */
258 } else {261 } else {
259 o(S, 0x8b); /* movl */262 o(0x8b); /* movl */
260 }263 }
261 gen_modrm(S, r, fr, sv->sym, fc);264 gen_modrm(r, fr, sv->sym, fc);
262 } else {265 } else {
263 if (v == VT_CONST) {266 if (v == VT_CONST) {
264 o(S, 0xb8 + r); /* mov $xx, r */267 o(0xb8 + r); /* mov $xx, r */
265 gen_addr32(S, fr, sv->sym, fc);268 gen_addr32(fr, sv->sym, fc);
266 } else if (v == VT_LOCAL) {269 } else if (v == VT_LOCAL) {
267 if (fc) {270 if (fc) {
268 o(S, 0x8d); /* lea xxx(%ebp), r */271 o(0x8d); /* lea xxx(%ebp), r */
269 gen_modrm(S, r, VT_LOCAL, sv->sym, fc);272 gen_modrm(r, VT_LOCAL, sv->sym, fc);
270 } else {273 } else {
271 o(S, 0x89);274 o(0x89);
272 o(S, 0xe8 + r); /* mov %ebp, r */275 o(0xe8 + r); /* mov %ebp, r */
273 }276 }
274 } else if (v == VT_CMP) {277 } else if (v == VT_CMP) {
275 o(S, 0x0f); /* setxx %br */278 o(0x0f); /* setxx %br */
276 o(S, fc);279 o(fc);
277 o(S, 0xc0 + r);280 o(0xc0 + r);
278 o(S, 0xc0b60f + r * 0x90000); /* movzbl %al, %eax */281 o(0xc0b60f + r * 0x90000); /* movzbl %al, %eax */
279 } else if (v == VT_JMP || v == VT_JMPI) {282 } else if (v == VT_JMP || v == VT_JMPI) {
280 t = v & 1;283 t = v & 1;
281 oad(S, 0xb8 + r, t); /* mov $1, r */284 oad(0xb8 + r, t); /* mov $1, r */
282 o(S, 0x05eb); /* jmp after */285 o(0x05eb); /* jmp after */
283 gsym(S, fc);286 gsym(fc);
284 oad(S, 0xb8 + r, t ^ 1); /* mov $0, r */287 oad(0xb8 + r, t ^ 1); /* mov $0, r */
285 } else if (v != r) {288 } else if (v != r) {
286 o(S, 0x89);289 o(0x89);
287 o(S, 0xc0 + r + v * 8); /* mov v, r */290 o(0xc0 + r + v * 8); /* mov v, r */
288 }291 }
289 }292 }
290}293}
291 294
292/* store register 'r' in lvalue 'v' */295/* store register 'r' in lvalue 'v' */
293ST_FUNC void store(TCCState* S, int r, SValue *v)296ST_FUNC void store(int r, SValue *v)
294{297{
295 int fr, bt, ft, fc;298 int fr, bt, ft, fc;
296 299
297#ifdef TCC_TARGET_PE300#ifdef TCC_TARGET_PE
298 SValue v2;301 SValue v2;
299 v = pe_getimport(S, v, &v2);302 v = pe_getimport(v, &v2);
300#endif303#endif
301 304
302 ft = v->type.t;305 ft = v->type.t;
@@ -306,66 +309,66 @@ ST_FUNC void store(TCCState* S, int r, SValue *v) · 3 unmodified lines
306 bt = ft & VT_BTYPE;309 bt = ft & VT_BTYPE;
307 /* XXX: incorrect if float reg to reg */310 /* XXX: incorrect if float reg to reg */
308 if (bt == VT_FLOAT) {311 if (bt == VT_FLOAT) {
309 o(S, 0xd9); /* fsts */312 o(0xd9); /* fsts */
310 r = 2;313 r = 2;
311 } else if (bt == VT_DOUBLE) {314 } else if (bt == VT_DOUBLE) {
312 o(S, 0xdd); /* fstpl */315 o(0xdd); /* fstpl */
313 r = 2;316 r = 2;
314 } else if (bt == VT_LDOUBLE) {317 } else if (bt == VT_LDOUBLE) {
315 o(S, 0xc0d9); /* fld %st(0) */318 o(0xc0d9); /* fld %st(0) */
316 o(S, 0xdb); /* fstpt */319 o(0xdb); /* fstpt */
317 r = 7;320 r = 7;
318 } else {321 } else {
319 if (bt == VT_SHORT)322 if (bt == VT_SHORT)
320 o(S, 0x66);323 o(0x66);
321 if (bt == VT_BYTE || bt == VT_BOOL)324 if (bt == VT_BYTE || bt == VT_BOOL)
322 o(S, 0x88);325 o(0x88);
323 else326 else
324 o(S, 0x89);327 o(0x89);
325 }328 }
326 if (fr == VT_CONST ||329 if (fr == VT_CONST ||
327 fr == VT_LOCAL ||330 fr == VT_LOCAL ||
328 (v->r & VT_LVAL)) {331 (v->r & VT_LVAL)) {
329 gen_modrm(S, r, v->r, v->sym, fc);332 gen_modrm(r, v->r, v->sym, fc);
330 } else if (fr != r) {333 } else if (fr != r) {
331 o(S, 0xc0 + fr + r * 8); /* mov r, fr */334 o(0xc0 + fr + r * 8); /* mov r, fr */
332 }335 }
333}336}
334 337
335static void gadd_sp(TCCState* S, int val)338static void gadd_sp(int val)
336{339{
337 if (val == (char)val) {340 if (val == (char)val) {
338 o(S, 0xc483);341 o(0xc483);
339 g(S, val);342 g(val);
340 } else {343 } else {
341 oad(S, 0xc481, val); /* add $xxx, %esp */344 oad(0xc481, val); /* add $xxx, %esp */
342 }345 }
343}346}
344 347
345#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_PE348#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_PE
346static void gen_static_call(TCCState* S, int v)349static void gen_static_call(int v)
347{350{
348 Sym *sym;351 Sym *sym;
349 352
350 sym = external_helper_sym(S, v);353 sym = external_helper_sym(v);
351 oad(S, 0xe8, -4);354 oad(0xe8, -4);
352 greloc(S, cur_text_section, sym, S->tccgen_ind-4, R_386_PC32);355 greloc(cur_text_section, sym, ind-4, R_386_PC32);
353}356}
354#endif357#endif
355 358
356/* 'is_jmp' is '1' if it is a jump */359/* 'is_jmp' is '1' if it is a jump */
357static void gcall_or_jmp(TCCState* S, int is_jmp)360static void gcall_or_jmp(int is_jmp)
358{361{
359 int r;362 int r;
360 if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (S->tccgen_vtop->r & VT_SYM)) {363 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (vtop->r & VT_SYM)) {
361 /* constant and relocation case */364 /* constant and relocation case */
362 greloc(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind + 1, R_386_PC32);365 greloc(cur_text_section, vtop->sym, ind + 1, R_386_PC32);
363 oad(S, 0xe8 + is_jmp, S->tccgen_vtop->c.i - 4); /* call/jmp im */366 oad(0xe8 + is_jmp, vtop->c.i - 4); /* call/jmp im */
364 } else {367 } else {
365 /* otherwise, indirect call */368 /* otherwise, indirect call */
366 r = gv(S, RC_INT);369 r = gv(RC_INT);
367 o(S, 0xff); /* call/jmp *r */370 o(0xff); /* call/jmp *r */
368 o(S, 0xd0 + r + (is_jmp << 4));371 o(0xd0 + r + (is_jmp << 4));
369 }372 }
370}373}
371 374
@@ -402,75 +405,75 @@ ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int · 30 unmodified lines
402/* Generate function call. The function address is pushed first, then405/* Generate function call. The function address is pushed first, then
403 all the parameters in call order. This functions pops all the406 all the parameters in call order. This functions pops all the
404 parameters and the function address. */407 parameters and the function address. */
405ST_FUNC void gfunc_call(TCCState* S, int nb_args)408ST_FUNC void gfunc_call(int nb_args)
406{409{
407 int size, align, r, args_size, i, func_call;410 int size, align, r, args_size, i, func_call;
408 Sym *func_sym;411 Sym *func_sym;
409 412
410#ifdef CONFIG_TCC_BCHECK413#ifdef CONFIG_TCC_BCHECK
411 if (S->do_bounds_check)414 if (tcc_state->do_bounds_check)
412 gbound_args(S, nb_args);415 gbound_args(nb_args);
413#endif416#endif
414 417
415 args_size = 0;418 args_size = 0;
416 for(i = 0;i < nb_args; i++) {419 for(i = 0;i < nb_args; i++) {
417 if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_STRUCT) {420 if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
418 size = type_size(&S->tccgen_vtop->type, &align);421 size = type_size(&vtop->type, &align);
419 /* align to stack align size */422 /* align to stack align size */
420 size = (size + 3) & ~3;423 size = (size + 3) & ~3;
421 /* allocate the necessary size on stack */424 /* allocate the necessary size on stack */
422#ifdef TCC_TARGET_PE425#ifdef TCC_TARGET_PE
423 if (size >= 4096) {426 if (size >= 4096) {
424 r = get_reg(S, RC_EAX);427 r = get_reg(RC_EAX);
425 oad(S, 0x68, size); // push size428 oad(0x68, size); // push size
426 /* cannot call normal 'alloca' with bound checking */429 /* cannot call normal 'alloca' with bound checking */
427 gen_static_call(S, tok_alloc_const(S, "__alloca"));430 gen_static_call(tok_alloc_const("__alloca"));
428 gadd_sp(S, 4);431 gadd_sp(4);
429 } else432 } else
430#endif433#endif
431 {434 {
432 oad(S, 0xec81, size); /* sub $xxx, %esp */435 oad(0xec81, size); /* sub $xxx, %esp */
433 /* generate structure store */436 /* generate structure store */
434 r = get_reg(S, RC_INT);437 r = get_reg(RC_INT);
435 o(S, 0xe089 + (r << 8)); /* mov %esp, r */438 o(0xe089 + (r << 8)); /* mov %esp, r */
436 }439 }
437 vset(S, &S->tccgen_vtop->type, r | VT_LVAL, 0);440 vset(&vtop->type, r | VT_LVAL, 0);
438 vswap(S);441 vswap();
439 vstore(S);442 vstore();
440 args_size += size;443 args_size += size;
441 } else if (is_float(S->tccgen_vtop->type.t)) {444 } else if (is_float(vtop->type.t)) {
442 gv(S, RC_FLOAT); /* only one float register */445 gv(RC_FLOAT); /* only one float register */
443 if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_FLOAT)446 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT)
444 size = 4;447 size = 4;
445 else if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_DOUBLE)448 else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
446 size = 8;449 size = 8;
447 else450 else
448 size = 12;451 size = 12;
449 oad(S, 0xec81, size); /* sub $xxx, %esp */452 oad(0xec81, size); /* sub $xxx, %esp */
450 if (size == 12)453 if (size == 12)
451 o(S, 0x7cdb);454 o(0x7cdb);
452 else455 else
453 o(S, 0x5cd9 + size - 4); /* fstp[s|l] 0(%esp) */456 o(0x5cd9 + size - 4); /* fstp[s|l] 0(%esp) */
454 g(S, 0x24);457 g(0x24);
455 g(S, 0x00);458 g(0x00);
456 args_size += size;459 args_size += size;
457 } else {460 } else {
458 /* simple type (currently always same size) */461 /* simple type (currently always same size) */
459 /* XXX: implicit cast ? */462 /* XXX: implicit cast ? */
460 r = gv(S, RC_INT);463 r = gv(RC_INT);
461 if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG) {464 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
462 size = 8;465 size = 8;
463 o(S, 0x50 + S->tccgen_vtop->r2); /* push r */466 o(0x50 + vtop->r2); /* push r */
464 } else {467 } else {
465 size = 4;468 size = 4;
466 }469 }
467 o(S, 0x50 + r); /* push r */470 o(0x50 + r); /* push r */
468 args_size += size;471 args_size += size;
469 }472 }
470 S->tccgen_vtop--;473 vtop--;
471 }474 }
472 save_regs(S, 0); /* save used temporary registers */475 save_regs(0); /* save used temporary registers */
473 func_sym = S->tccgen_vtop->type.ref;476 func_sym = vtop->type.ref;
474 func_call = func_sym->f.func_call;477 func_call = func_sym->f.func_call;
475 /* fast call case */478 /* fast call case */
476 if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) ||479 if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) ||
@@ -487,21 +490,21 @@ ST_FUNC void gfunc_call(TCCState* S, int nb_args) · 10 unmodified lines
487 for(i = 0;i < fastcall_nb_regs; i++) {490 for(i = 0;i < fastcall_nb_regs; i++) {
488 if (args_size <= 0)491 if (args_size <= 0)
489 break;492 break;
490 o(S, 0x58 + fastcall_regs_ptr[i]); /* pop r */493 o(0x58 + fastcall_regs_ptr[i]); /* pop r */
491 /* XXX: incorrect for struct/floats */494 /* XXX: incorrect for struct/floats */
492 args_size -= 4;495 args_size -= 4;
493 }496 }
494 }497 }
495#if !defined(TCC_TARGET_PE) && !TARGETOS_FreeBSD || TARGETOS_OpenBSD498#if !defined(TCC_TARGET_PE) && !TARGETOS_FreeBSD || TARGETOS_OpenBSD
496 else if ((S->tccgen_vtop->type.ref->type.t & VT_BTYPE) == VT_STRUCT)499 else if ((vtop->type.ref->type.t & VT_BTYPE) == VT_STRUCT)
497 args_size -= 4;500 args_size -= 4;
498#endif501#endif
499 502
500 gcall_or_jmp(S, 0);503 gcall_or_jmp(0);
501 504
502 if (args_size && func_call != FUNC_STDCALL && func_call != FUNC_FASTCALLW)505 if (args_size && func_call != FUNC_STDCALL && func_call != FUNC_FASTCALLW)
503 gadd_sp(S, args_size);506 gadd_sp(args_size);
504 S->tccgen_vtop--;507 vtop--;
505}508}
506 509
507#ifdef TCC_TARGET_PE510#ifdef TCC_TARGET_PE
@@ -511,7 +514,7 @@ ST_FUNC void gfunc_call(TCCState* S, int nb_args) · 3 unmodified lines
511#endif514#endif
512 515
513/* generate function prolog of type 't' */516/* generate function prolog of type 't' */
514ST_FUNC void gfunc_prolog(TCCState* S, Sym *func_sym)517ST_FUNC void gfunc_prolog(Sym *func_sym)
515{518{
516 CType *func_type = &func_sym->type;519 CType *func_type = &func_sym->type;
517 int addr, align, size, func_call, fastcall_nb_regs;520 int addr, align, size, func_call, fastcall_nb_regs;
@@ -523,8 +526,8 @@ ST_FUNC void gfunc_prolog(TCCState* S, Sym *func_sym) · 5 unmodified lines
523 sym = func_type->ref;526 sym = func_type->ref;
524 func_call = sym->f.func_call;527 func_call = sym->f.func_call;
525 addr = 8;528 addr = 8;
526 S->tccgen_loc = 0;529 loc = 0;
527 S->tccgen_func_vc = 0;530 func_vc = 0;
528 531
529 if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {532 if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
530 fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;533 fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
@@ -538,19 +541,19 @@ ST_FUNC void gfunc_prolog(TCCState* S, Sym *func_sym) · 7 unmodified lines
538 }541 }
539 param_index = 0;542 param_index = 0;
540 543
541 S->tccgen_ind += FUNC_PROLOG_SIZE;544 ind += FUNC_PROLOG_SIZE;
542 func_sub_sp_offset = S->tccgen_ind;545 func_sub_sp_offset = ind;
543 /* if the function returns a structure, then add an546 /* if the function returns a structure, then add an
544 implicit pointer parameter */547 implicit pointer parameter */
545#if defined(TCC_TARGET_PE) || TARGETOS_FreeBSD || TARGETOS_OpenBSD548#if defined(TCC_TARGET_PE) || TARGETOS_FreeBSD || TARGETOS_OpenBSD
546 size = type_size(&S->tccgen_func_vt,&align);549 size = type_size(&func_vt,&align);
547 if (((S->tccgen_func_vt.t & VT_BTYPE) == VT_STRUCT)550 if (((func_vt.t & VT_BTYPE) == VT_STRUCT)
548 && (size > 8 || (size & (size - 1)))) {551 && (size > 8 || (size & (size - 1)))) {
549#else552#else
550 if ((S->tccgen_func_vt.t & VT_BTYPE) == VT_STRUCT) {553 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
551#endif554#endif
552 /* XXX: fastcall case ? */555 /* XXX: fastcall case ? */
553 S->tccgen_func_vc = addr;556 func_vc = addr;
554 addr += 4;557 addr += 4;
555 param_index++;558 param_index++;
556 }559 }
@@ -567,15 +570,15 @@ ST_FUNC void gfunc_prolog(TCCState* S, Sym *func_sym) · 10 unmodified lines
567#endif570#endif
568 if (param_index < fastcall_nb_regs) {571 if (param_index < fastcall_nb_regs) {
569 /* save FASTCALL register */572 /* save FASTCALL register */
570 S->tccgen_loc -= 4;573 loc -= 4;
571 o(S, 0x89); /* movl */574 o(0x89); /* movl */
572 gen_modrm(S, fastcall_regs_ptr[param_index], VT_LOCAL, NULL, S->tccgen_loc);575 gen_modrm(fastcall_regs_ptr[param_index], VT_LOCAL, NULL, loc);
573 param_addr = S->tccgen_loc;576 param_addr = loc;
574 } else {577 } else {
575 param_addr = addr;578 param_addr = addr;
576 addr += size;579 addr += size;
577 }580 }
578 sym_push(S, sym->v & ~SYM_FIELD, type,581 sym_push(sym->v & ~SYM_FIELD, type,
579 VT_LOCAL | VT_LVAL, param_addr);582 VT_LOCAL | VT_LVAL, param_addr);
580 param_index++;583 param_index++;
581 }584 }
@@ -584,94 +587,94 @@ ST_FUNC void gfunc_prolog(TCCState* S, Sym *func_sym) · 2 unmodified lines
584 if (func_call == FUNC_STDCALL || func_call == FUNC_FASTCALLW)587 if (func_call == FUNC_STDCALL || func_call == FUNC_FASTCALLW)
585 func_ret_sub = addr - 8;588 func_ret_sub = addr - 8;
586#if !defined(TCC_TARGET_PE) && !TARGETOS_FreeBSD || TARGETOS_OpenBSD589#if !defined(TCC_TARGET_PE) && !TARGETOS_FreeBSD || TARGETOS_OpenBSD
587 else if (S->tccgen_func_vc)590 else if (func_vc)
588 func_ret_sub = 4;591 func_ret_sub = 4;
589#endif592#endif
590 593
591#ifdef CONFIG_TCC_BCHECK594#ifdef CONFIG_TCC_BCHECK
592 if (S->do_bounds_check)595 if (tcc_state->do_bounds_check)
593 gen_bounds_prolog(S);596 gen_bounds_prolog();
594#endif597#endif
595}598}
596 599
597/* generate function epilog */600/* generate function epilog */
598ST_FUNC void gfunc_epilog(TCCState* S)601ST_FUNC void gfunc_epilog(void)
599{602{
600 addr_t v, saved_ind;603 addr_t v, saved_ind;
601 604
602#ifdef CONFIG_TCC_BCHECK605#ifdef CONFIG_TCC_BCHECK
603 if (S->do_bounds_check)606 if (tcc_state->do_bounds_check)
604 gen_bounds_epilog(S);607 gen_bounds_epilog();
605#endif608#endif
606 609
607 /* align local size to word & save local variables */610 /* align local size to word & save local variables */
608 v = (-S->tccgen_loc + 3) & -4;611 v = (-loc + 3) & -4;
609 612
610#if USE_EBX613#if USE_EBX
611 o(S, 0x8b);614 o(0x8b);
612 gen_modrm(S, TREG_EBX, VT_LOCAL, NULL, -(v+4));615 gen_modrm(TREG_EBX, VT_LOCAL, NULL, -(v+4));
613#endif616#endif
614 617
615 o(S, 0xc9); /* leave */618 o(0xc9); /* leave */
616 if (func_ret_sub == 0) {619 if (func_ret_sub == 0) {
617 o(S, 0xc3); /* ret */620 o(0xc3); /* ret */
618 } else {621 } else {
619 o(S, 0xc2); /* ret n */622 o(0xc2); /* ret n */
620 g(S, func_ret_sub);623 g(func_ret_sub);
621 g(S, func_ret_sub >> 8);624 g(func_ret_sub >> 8);
622 }625 }
623 saved_ind = S->tccgen_ind;626 saved_ind = ind;
624 S->tccgen_ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;627 ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
625#ifdef TCC_TARGET_PE628#ifdef TCC_TARGET_PE
626 if (v >= 4096) {629 if (v >= 4096) {
627 oad(S, 0xb8, v); /* mov stacksize, %eax */630 oad(0xb8, v); /* mov stacksize, %eax */
628 gen_static_call(S, TOK___chkstk); /* call __chkstk, (does the stackframe too) */631 gen_static_call(TOK___chkstk); /* call __chkstk, (does the stackframe too) */
629 } else632 } else
630#endif633#endif
631 {634 {
632 o(S, 0xe58955); /* push %ebp, mov %esp, %ebp */635 o(0xe58955); /* push %ebp, mov %esp, %ebp */
633 o(S, 0xec81); /* sub esp, stacksize */636 o(0xec81); /* sub esp, stacksize */
634 gen_le32(S, v);637 gen_le32(v);
635#ifdef TCC_TARGET_PE638#ifdef TCC_TARGET_PE
636 o(S, 0x90); /* adjust to FUNC_PROLOG_SIZE */639 o(0x90); /* adjust to FUNC_PROLOG_SIZE */
637#endif640#endif
638 }641 }
639 o(S, 0x53 * USE_EBX); /* push ebx */642 o(0x53 * USE_EBX); /* push ebx */
640 S->tccgen_ind = saved_ind;643 ind = saved_ind;
641}644}
642 645
643/* generate a jump to a label */646/* generate a jump to a label */
644ST_FUNC int gjmp(TCCState* S, int t)647ST_FUNC int gjmp(int t)
645{648{
646 return gjmp2(S, 0xe9, t);649 return gjmp2(0xe9, t);
647}650}
648 651
649/* generate a jump to a fixed address */652/* generate a jump to a fixed address */
650ST_FUNC void gjmp_addr(TCCState* S, int a)653ST_FUNC void gjmp_addr(int a)
651{654{
652 int r;655 int r;
653 r = a - S->tccgen_ind - 2;656 r = a - ind - 2;
654 if (r == (char)r) {657 if (r == (char)r) {
655 g(S, 0xeb);658 g(0xeb);
656 g(S, r);659 g(r);
657 } else {660 } else {
658 oad(S, 0xe9, a - S->tccgen_ind - 5);661 oad(0xe9, a - ind - 5);
659 }662 }
660}663}
661 664
662#if 0665#if 0
663/* generate a jump to a fixed address */666/* generate a jump to a fixed address */
664ST_FUNC void gjmp_cond_addr(TCCState* S, int a, int op)667ST_FUNC void gjmp_cond_addr(int a, int op)
665{668{
666 int r = a - S->tccgen_ind - 2;669 int r = a - ind - 2;
667 if (r == (char)r)670 if (r == (char)r)
668 g(S, op - 32), g(r);671 g(op - 32), g(r);
669 else672 else
670 g(S, 0x0f), gjmp2(S, op - 16, r - 4);673 g(0x0f), gjmp2(op - 16, r - 4);
671}674}
672#endif675#endif
673 676
674ST_FUNC int gjmp_append(TCCState* S, int n, int t)677ST_FUNC int gjmp_append(int n, int t)
675{678{
676 void *p;679 void *p;
677 /* insert vtop->c jump list in t */680 /* insert vtop->c jump list in t */
@@ -685,14 +688,14 @@ ST_FUNC int gjmp_append(TCCState* S, int n, int t) · 7 unmodified lines
685 return t;688 return t;
686}689}
687 690
688ST_FUNC int gjmp_cond(TCCState* S, int op, int t)691ST_FUNC int gjmp_cond(int op, int t)
689{692{
690 g(S, 0x0f);693 g(0x0f);
691 t = gjmp2(S, op - 16, t);694 t = gjmp2(op - 16, t);
692 return t;695 return t;
693}696}
694 697
695ST_FUNC void gen_opi(TCCState* S, int op)698ST_FUNC void gen_opi(int op)
696{699{
697 int r, fr, opc, c;700 int r, fr, opc, c;
698 701
@@ -701,36 +704,36 @@ ST_FUNC void gen_opi(TCCState* S, int op) · 2 unmodified lines
701 case TOK_ADDC1: /* add with carry generation */704 case TOK_ADDC1: /* add with carry generation */
702 opc = 0;705 opc = 0;
703 gen_op8:706 gen_op8:
704 if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {707 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
705 /* constant case */708 /* constant case */
706 vswap(S);709 vswap();
707 r = gv(S, RC_INT);710 r = gv(RC_INT);
708 vswap(S);711 vswap();
709 c = S->tccgen_vtop->c.i;712 c = vtop->c.i;
710 if (c == (char)c) {713 if (c == (char)c) {
711 /* generate inc and dec for smaller code */714 /* generate inc and dec for smaller code */
712 if ((c == 1 || c == -1) && (op == '+' || op == '-')) {715 if ((c == 1 || c == -1) && (op == '+' || op == '-')) {
713 opc = (c == 1) ^ (op == '+');716 opc = (c == 1) ^ (op == '+');
714 o(S, 0x40 | (opc << 3) | r); // inc,dec717 o (0x40 | (opc << 3) | r); // inc,dec
715 } else {718 } else {
716 o(S, 0x83);719 o(0x83);
717 o(S, 0xc0 | (opc << 3) | r);720 o(0xc0 | (opc << 3) | r);
718 g(S, c);721 g(c);
719 }722 }
720 } else {723 } else {
721 o(S, 0x81);724 o(0x81);
722 oad(S, 0xc0 | (opc << 3) | r, c);725 oad(0xc0 | (opc << 3) | r, c);
723 }726 }
724 } else {727 } else {
725 gv2(S, RC_INT, RC_INT);728 gv2(RC_INT, RC_INT);
726 r = S->tccgen_vtop[-1].r;729 r = vtop[-1].r;
727 fr = S->tccgen_vtop[0].r;730 fr = vtop[0].r;
728 o(S, (opc << 3) | 0x01);731 o((opc << 3) | 0x01);
729 o(S, 0xc0 + r + fr * 8); 732 o(0xc0 + r + fr * 8);
730 }733 }
731 S->tccgen_vtop--;734 vtop--;
732 if (op >= TOK_ULT && op <= TOK_GT)735 if (op >= TOK_ULT && op <= TOK_GT)
733 vset_VT_CMP(S, op);736 vset_VT_CMP(op);
734 break;737 break;
735 case '-':738 case '-':
736 case TOK_SUBC1: /* sub with carry generation */739 case TOK_SUBC1: /* sub with carry generation */
@@ -752,12 +755,12 @@ ST_FUNC void gen_opi(TCCState* S, int op) · 15 unmodified lines
752 opc = 1;755 opc = 1;
753 goto gen_op8;756 goto gen_op8;
754 case '*':757 case '*':
755 gv2(S, RC_INT, RC_INT);758 gv2(RC_INT, RC_INT);
756 r = S->tccgen_vtop[-1].r;759 r = vtop[-1].r;
757 fr = S->tccgen_vtop[0].r;760 fr = vtop[0].r;
758 S->tccgen_vtop--;761 vtop--;
759 o(S, 0xaf0f); /* imul fr, r */762 o(0xaf0f); /* imul fr, r */
760 o(S, 0xc0 + fr + r * 8);763 o(0xc0 + fr + r * 8);
761 break;764 break;
762 case TOK_SHL:765 case TOK_SHL:
763 opc = 4;766 opc = 4;
@@ -769,23 +772,23 @@ ST_FUNC void gen_opi(TCCState* S, int op) · 5 unmodified lines
769 opc = 7;772 opc = 7;
770 gen_shift:773 gen_shift:
771 opc = 0xc0 | (opc << 3);774 opc = 0xc0 | (opc << 3);
772 if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {775 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
773 /* constant case */776 /* constant case */
774 vswap(S);777 vswap();
775 r = gv(S, RC_INT);778 r = gv(RC_INT);
776 vswap(S);779 vswap();
777 c = S->tccgen_vtop->c.i & 0x1f;780 c = vtop->c.i & 0x1f;
778 o(S, 0xc1); /* shl/shr/sar $xxx, r */781 o(0xc1); /* shl/shr/sar $xxx, r */
779 o(S, opc | r);782 o(opc | r);
780 g(S, c);783 g(c);
781 } else {784 } else {
782 /* we generate the shift in ecx */785 /* we generate the shift in ecx */
783 gv2(S, RC_INT, RC_ECX);786 gv2(RC_INT, RC_ECX);
784 r = S->tccgen_vtop[-1].r;787 r = vtop[-1].r;
785 o(S, 0xd3); /* shl/shr/sar %cl, r */788 o(0xd3); /* shl/shr/sar %cl, r */
786 o(S, opc | r);789 o(opc | r);
787 }790 }
788 S->tccgen_vtop--;791 vtop--;
789 break;792 break;
790 case '/':793 case '/':
791 case TOK_UDIV:794 case TOK_UDIV:
@@ -795,32 +798,32 @@ ST_FUNC void gen_opi(TCCState* S, int op) · 3 unmodified lines
795 case TOK_UMULL:798 case TOK_UMULL:
796 /* first operand must be in eax */799 /* first operand must be in eax */
797 /* XXX: need better constraint for second operand */800 /* XXX: need better constraint for second operand */
798 gv2(S, RC_EAX, RC_ECX);801 gv2(RC_EAX, RC_ECX);
799 r = S->tccgen_vtop[-1].r;802 r = vtop[-1].r;
800 fr = S->tccgen_vtop[0].r;803 fr = vtop[0].r;
801 S->tccgen_vtop--;804 vtop--;
802 save_reg(S, TREG_EDX);805 save_reg(TREG_EDX);
803 /* save EAX too if used otherwise */806 /* save EAX too if used otherwise */
804 save_reg_upstack(S, TREG_EAX, 1);807 save_reg_upstack(TREG_EAX, 1);
805 if (op == TOK_UMULL) {808 if (op == TOK_UMULL) {
806 o(S, 0xf7); /* mul fr */809 o(0xf7); /* mul fr */
807 o(S, 0xe0 + fr);810 o(0xe0 + fr);
808 S->tccgen_vtop->r2 = TREG_EDX;811 vtop->r2 = TREG_EDX;
809 r = TREG_EAX;812 r = TREG_EAX;
810 } else {813 } else {
811 if (op == TOK_UDIV || op == TOK_UMOD) {814 if (op == TOK_UDIV || op == TOK_UMOD) {
812 o(S, 0xf7d231); /* xor %edx, %edx, div fr, %eax */815 o(0xf7d231); /* xor %edx, %edx, div fr, %eax */
813 o(S, 0xf0 + fr);816 o(0xf0 + fr);
814 } else {817 } else {
815 o(S, 0xf799); /* cltd, idiv fr, %eax */818 o(0xf799); /* cltd, idiv fr, %eax */
816 o(S, 0xf8 + fr);819 o(0xf8 + fr);
817 }820 }
818 if (op == '%' || op == TOK_UMOD)821 if (op == '%' || op == TOK_UMOD)
819 r = TREG_EDX;822 r = TREG_EDX;
820 else823 else
821 r = TREG_EAX;824 r = TREG_EAX;
822 }825 }
823 S->tccgen_vtop->r = r;826 vtop->r = r;
824 break;827 break;
825 default:828 default:
826 opc = 7;829 opc = 7;
@@ -831,74 +834,74 @@ ST_FUNC void gen_opi(TCCState* S, int op) · 4 unmodified lines
831/* generate a floating point operation 'v = t1 op t2' instruction. The834/* generate a floating point operation 'v = t1 op t2' instruction. The
832 two operands are guaranteed to have the same floating point type */835 two operands are guaranteed to have the same floating point type */
833/* XXX: need to use ST1 too */836/* XXX: need to use ST1 too */
834ST_FUNC void gen_opf(TCCState* S, int op)837ST_FUNC void gen_opf(int op)
835{838{
836 int a, ft, fc, swapped, r;839 int a, ft, fc, swapped, r;
837 840
838 if (op == TOK_NEG) { /* unary minus */841 if (op == TOK_NEG) { /* unary minus */
839 gv(S, RC_FLOAT);842 gv(RC_FLOAT);
840 o(S, 0xe0d9); /* fchs */843 o(0xe0d9); /* fchs */
841 return;844 return;
842 }845 }
843 846
844 /* convert constants to memory references */847 /* convert constants to memory references */
845 if ((S->tccgen_vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {848 if ((vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
846 vswap(S);849 vswap();
847 gv(S, RC_FLOAT);850 gv(RC_FLOAT);
848 vswap(S);851 vswap();
849 }852 }
850 if ((S->tccgen_vtop[0].r & (VT_VALMASK | VT_LVAL)) == VT_CONST)853 if ((vtop[0].r & (VT_VALMASK | VT_LVAL)) == VT_CONST)
851 gv(S, RC_FLOAT);854 gv(RC_FLOAT);
852 855
853 /* must put at least one value in the floating point register */856 /* must put at least one value in the floating point register */
854 if ((S->tccgen_vtop[-1].r & VT_LVAL) &&857 if ((vtop[-1].r & VT_LVAL) &&
855 (S->tccgen_vtop[0].r & VT_LVAL)) {858 (vtop[0].r & VT_LVAL)) {
856 vswap(S);859 vswap();
857 gv(S, RC_FLOAT);860 gv(RC_FLOAT);
858 vswap(S);861 vswap();
859 }862 }
860 swapped = 0;863 swapped = 0;
861 /* swap the stack if needed so that t1 is the register and t2 is864 /* swap the stack if needed so that t1 is the register and t2 is
862 the memory reference */865 the memory reference */
863 if (S->tccgen_vtop[-1].r & VT_LVAL) {866 if (vtop[-1].r & VT_LVAL) {
864 vswap(S);867 vswap();
865 swapped = 1;868 swapped = 1;
866 }869 }
867 if (op >= TOK_ULT && op <= TOK_GT) {870 if (op >= TOK_ULT && op <= TOK_GT) {
868 /* load on stack second operand */871 /* load on stack second operand */
869 load(S, TREG_ST0, S->tccgen_vtop);872 load(TREG_ST0, vtop);
870 save_reg(S, TREG_EAX); /* eax is used by FP comparison code */873 save_reg(TREG_EAX); /* eax is used by FP comparison code */
871 if (op == TOK_GE || op == TOK_GT)874 if (op == TOK_GE || op == TOK_GT)
872 swapped = !swapped;875 swapped = !swapped;
873 else if (op == TOK_EQ || op == TOK_NE)876 else if (op == TOK_EQ || op == TOK_NE)
874 swapped = 0;877 swapped = 0;
875 if (swapped)878 if (swapped)
876 o(S, 0xc9d9); /* fxch %st(1) */879 o(0xc9d9); /* fxch %st(1) */
877 if (op == TOK_EQ || op == TOK_NE)880 if (op == TOK_EQ || op == TOK_NE)
878 o(S, 0xe9da); /* fucompp */881 o(0xe9da); /* fucompp */
879 else882 else
880 o(S, 0xd9de); /* fcompp */883 o(0xd9de); /* fcompp */
881 o(S, 0xe0df); /* fnstsw %ax */884 o(0xe0df); /* fnstsw %ax */
882 if (op == TOK_EQ) {885 if (op == TOK_EQ) {
883 o(S, 0x45e480); /* and $0x45, %ah */886 o(0x45e480); /* and $0x45, %ah */
884 o(S, 0x40fC80); /* cmp $0x40, %ah */887 o(0x40fC80); /* cmp $0x40, %ah */
885 } else if (op == TOK_NE) {888 } else if (op == TOK_NE) {
886 o(S, 0x45e480); /* and $0x45, %ah */889 o(0x45e480); /* and $0x45, %ah */
887 o(S, 0x40f480); /* xor $0x40, %ah */890 o(0x40f480); /* xor $0x40, %ah */
888 op = TOK_NE;891 op = TOK_NE;
889 } else if (op == TOK_GE || op == TOK_LE) {892 } else if (op == TOK_GE || op == TOK_LE) {
890 o(S, 0x05c4f6); /* test $0x05, %ah */893 o(0x05c4f6); /* test $0x05, %ah */
891 op = TOK_EQ;894 op = TOK_EQ;
892 } else {895 } else {
893 o(S, 0x45c4f6); /* test $0x45, %ah */896 o(0x45c4f6); /* test $0x45, %ah */
894 op = TOK_EQ;897 op = TOK_EQ;
895 }898 }
896 S->tccgen_vtop--;899 vtop--;
897 vset_VT_CMP(S, op);900 vset_VT_CMP(op);
898 } else {901 } else {
899 /* no memory reference possible for long double operations */902 /* no memory reference possible for long double operations */
900 if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {903 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
901 load(S, TREG_ST0, S->tccgen_vtop);904 load(TREG_ST0, vtop);
902 swapped = !swapped;905 swapped = !swapped;
903 }906 }
904 907
@@ -921,213 +924,213 @@ ST_FUNC void gen_opf(TCCState* S, int op) · 16 unmodified lines
921 a++;924 a++;
922 break;925 break;
923 }926 }
924 ft = S->tccgen_vtop->type.t;927 ft = vtop->type.t;
925 fc = S->tccgen_vtop->c.i;928 fc = vtop->c.i;
926 if ((ft & VT_BTYPE) == VT_LDOUBLE) {929 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
927 o(S, 0xde); /* fxxxp %st, %st(1) */930 o(0xde); /* fxxxp %st, %st(1) */
928 o(S, 0xc1 + (a << 3));931 o(0xc1 + (a << 3));
929 } else {932 } else {
930 /* if saved lvalue, then we must reload it */933 /* if saved lvalue, then we must reload it */
931 r = S->tccgen_vtop->r;934 r = vtop->r;
932 if ((r & VT_VALMASK) == VT_LLOCAL) {935 if ((r & VT_VALMASK) == VT_LLOCAL) {
933 SValue v1;936 SValue v1;
934 r = get_reg(S, RC_INT);937 r = get_reg(RC_INT);
935 v1.type.t = VT_INT;938 v1.type.t = VT_INT;
936 v1.r = VT_LOCAL | VT_LVAL;939 v1.r = VT_LOCAL | VT_LVAL;
937 v1.c.i = fc;940 v1.c.i = fc;
938 v1.sym = NULL;941 v1.sym = NULL;
939 load(S, r, &v1);942 load(r, &v1);
940 fc = 0;943 fc = 0;
941 }944 }
942 945
943 if ((ft & VT_BTYPE) == VT_DOUBLE)946 if ((ft & VT_BTYPE) == VT_DOUBLE)
944 o(S, 0xdc);947 o(0xdc);
945 else948 else
946 o(S, 0xd8);949 o(0xd8);
947 gen_modrm(S, a, r, S->tccgen_vtop->sym, fc);950 gen_modrm(a, r, vtop->sym, fc);
948 }951 }
949 S->tccgen_vtop--;952 vtop--;
950 }953 }
951}954}
952 955
953/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'956/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
954 and 'long long' cases. */957 and 'long long' cases. */
955ST_FUNC void gen_cvt_itof(TCCState* S, int t)958ST_FUNC void gen_cvt_itof(int t)
956{959{
957 save_reg(S, TREG_ST0);960 save_reg(TREG_ST0);
958 gv(S, RC_INT);961 gv(RC_INT);
959 if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG) {962 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
960 /* signed long long to float/double/long double (unsigned case963 /* signed long long to float/double/long double (unsigned case
961 is handled generically) */964 is handled generically) */
962 o(S, 0x50 + S->tccgen_vtop->r2); /* push r2 */965 o(0x50 + vtop->r2); /* push r2 */
963 o(S, 0x50 + (S->tccgen_vtop->r & VT_VALMASK)); /* push r */966 o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
964 o(S, 0x242cdf); /* fildll (%esp) */967 o(0x242cdf); /* fildll (%esp) */
965 o(S, 0x08c483); /* add $8, %esp */968 o(0x08c483); /* add $8, %esp */
966 S->tccgen_vtop->r2 = VT_CONST;969 vtop->r2 = VT_CONST;
967 } else if ((S->tccgen_vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == 970 } else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
968 (VT_INT | VT_UNSIGNED)) {971 (VT_INT | VT_UNSIGNED)) {
969 /* unsigned int to float/double/long double */972 /* unsigned int to float/double/long double */
970 o(S, 0x6a); /* push $0 */973 o(0x6a); /* push $0 */
971 g(S, 0x00);974 g(0x00);
972 o(S, 0x50 + (S->tccgen_vtop->r & VT_VALMASK)); /* push r */975 o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
973 o(S, 0x242cdf); /* fildll (%esp) */976 o(0x242cdf); /* fildll (%esp) */
974 o(S, 0x08c483); /* add $8, %esp */977 o(0x08c483); /* add $8, %esp */
975 } else {978 } else {
976 /* int to float/double/long double */979 /* int to float/double/long double */
977 o(S, 0x50 + (S->tccgen_vtop->r & VT_VALMASK)); /* push r */980 o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
978 o(S, 0x2404db); /* fildl (%esp) */981 o(0x2404db); /* fildl (%esp) */
979 o(S, 0x04c483); /* add $4, %esp */982 o(0x04c483); /* add $4, %esp */
980 }983 }
981 S->tccgen_vtop->r2 = VT_CONST;984 vtop->r2 = VT_CONST;
982 S->tccgen_vtop->r = TREG_ST0;985 vtop->r = TREG_ST0;
983}986}
984 987
985/* convert fp to int 't' type */988/* convert fp to int 't' type */
986ST_FUNC void gen_cvt_ftoi(TCCState* S, int t)989ST_FUNC void gen_cvt_ftoi(int t)
987{990{
988 int bt = S->tccgen_vtop->type.t & VT_BTYPE;991 int bt = vtop->type.t & VT_BTYPE;
989 if (bt == VT_FLOAT)992 if (bt == VT_FLOAT)
990 vpush_helper_func(S, TOK___fixsfdi);993 vpush_helper_func(TOK___fixsfdi);
991 else if (bt == VT_LDOUBLE)994 else if (bt == VT_LDOUBLE)
992 vpush_helper_func(S, TOK___fixxfdi);995 vpush_helper_func(TOK___fixxfdi);
993 else996 else
994 vpush_helper_func(S, TOK___fixdfdi);997 vpush_helper_func(TOK___fixdfdi);
995 vswap(S);998 vswap();
996 gfunc_call(S, 1);999 gfunc_call(1);
997 vpushi(S, 0);1000 vpushi(0);
998 S->tccgen_vtop->r = REG_IRET;1001 vtop->r = REG_IRET;
999 if ((t & VT_BTYPE) == VT_LLONG)1002 if ((t & VT_BTYPE) == VT_LLONG)
1000 S->tccgen_vtop->r2 = REG_IRE2;1003 vtop->r2 = REG_IRE2;
1001}1004}
1002 1005
1003/* convert from one floating point type to another */1006/* convert from one floating point type to another */
1004ST_FUNC void gen_cvt_ftof(TCCState* S, int t)1007ST_FUNC void gen_cvt_ftof(int t)
1005{1008{
1006 /* all we have to do on i386 is to put the float in a register */1009 /* all we have to do on i386 is to put the float in a register */
1007 gv(S, RC_FLOAT);1010 gv(RC_FLOAT);
1008}1011}
1009 1012
1010/* char/short to int conversion */1013/* char/short to int conversion */
1011ST_FUNC void gen_cvt_csti(TCCState* S, int t)1014ST_FUNC void gen_cvt_csti(int t)
1012{1015{
1013 int r, sz, xl;1016 int r, sz, xl;
1014 r = gv(S, RC_INT);1017 r = gv(RC_INT);
1015 sz = !(t & VT_UNSIGNED);1018 sz = !(t & VT_UNSIGNED);
1016 xl = (t & VT_BTYPE) == VT_SHORT;1019 xl = (t & VT_BTYPE) == VT_SHORT;
1017 o(S, 0xc0b60f /* mov[sz] %a[xl], %eax */1020 o(0xc0b60f /* mov[sz] %a[xl], %eax */
1018 | (sz << 3 | xl) << 81021 | (sz << 3 | xl) << 8
1019 | (r << 3 | r) << 161022 | (r << 3 | r) << 16
1020 );1023 );
1021}1024}
1022 1025
1023/* increment tcov counter */1026/* increment tcov counter */
1024ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv)1027ST_FUNC void gen_increment_tcov (SValue *sv)
1025{1028{
1026 o(S, 0x0583); /* addl $1, xxx */1029 o(0x0583); /* addl $1, xxx */
1027 greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_386_32);1030 greloc(cur_text_section, sv->sym, ind, R_386_32);
1028 gen_le32(S, 0);1031 gen_le32(0);
1029 o(S, 1);1032 o(1);
1030 o(S, 0x1583); /* addcl $0, xxx */1033 o(0x1583); /* addcl $0, xxx */
1031 greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_386_32);1034 greloc(cur_text_section, sv->sym, ind, R_386_32);
1032 gen_le32(S, 4);1035 gen_le32(4);
1033 g(S, 0);1036 g(0);
1034}1037}
1035 1038
1036/* computed goto support */1039/* computed goto support */
1037ST_FUNC void ggoto(TCCState* S)1040ST_FUNC void ggoto(void)
1038{1041{
1039 gcall_or_jmp(S, 1);1042 gcall_or_jmp(1);
1040 S->tccgen_vtop--;1043 vtop--;
1041}1044}
1042 1045
1043/* bound check support functions */1046/* bound check support functions */
1044#ifdef CONFIG_TCC_BCHECK1047#ifdef CONFIG_TCC_BCHECK
1045 1048
1046static void gen_bounds_prolog(TCCState* S)1049static void gen_bounds_prolog(void)
1047{1050{
1048 /* leave some room for bound checking code */1051 /* leave some room for bound checking code */
1049 S->func_bound_offset = lbounds_section->data_offset;1052 func_bound_offset = lbounds_section->data_offset;
1050 S->func_bound_ind = S->tccgen_ind;1053 func_bound_ind = ind;
1051 S->func_bound_add_epilog = 0;1054 func_bound_add_epilog = 0;
1052 oad(S, 0xb8, 0); /* lbound section pointer */1055 oad(0xb8, 0); /* lbound section pointer */
1053 oad(S, 0xb8, 0); /* call to function */1056 oad(0xb8, 0); /* call to function */
1054}1057}
1055 1058
1056static void gen_bounds_epilog(TCCState* S)1059static void gen_bounds_epilog(void)
1057{1060{
1058 addr_t saved_ind;1061 addr_t saved_ind;
1059 addr_t *bounds_ptr;1062 addr_t *bounds_ptr;
1060 Sym *sym_data;1063 Sym *sym_data;
1061 int offset_modified = S->func_bound_offset != lbounds_section->data_offset;1064 int offset_modified = func_bound_offset != lbounds_section->data_offset;
1062 1065
1063 if (!offset_modified && !S->func_bound_add_epilog)1066 if (!offset_modified && !func_bound_add_epilog)
1064 return;1067 return;
1065 1068
1066 /* add end of table info */1069 /* add end of table info */
1067 bounds_ptr = section_ptr_add(S, lbounds_section, sizeof(addr_t));1070 bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));
1068 *bounds_ptr = 0;1071 *bounds_ptr = 0;
1069 1072
1070 sym_data = get_sym_ref(S, &S->tccgen_char_pointer_type, lbounds_section,1073 sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
1071 S->func_bound_offset, lbounds_section->data_offset);1074 func_bound_offset, lbounds_section->data_offset);
1072 1075
1073 /* generate bound local allocation */1076 /* generate bound local allocation */
1074 if (offset_modified) {1077 if (offset_modified) {
1075 saved_ind = S->tccgen_ind;1078 saved_ind = ind;
1076 S->tccgen_ind = S->func_bound_ind;1079 ind = func_bound_ind;
1077 greloc(S, cur_text_section, sym_data, S->tccgen_ind + 1, R_386_32);1080 greloc(cur_text_section, sym_data, ind + 1, R_386_32);
1078 S->tccgen_ind = S->tccgen_ind + 5;1081 ind = ind + 5;
1079 gen_static_call(S, TOK___bound_local_new);1082 gen_static_call(TOK___bound_local_new);
1080 S->tccgen_ind = saved_ind;1083 ind = saved_ind;
1081 }1084 }
1082 1085
1083 /* generate bound check local freeing */1086 /* generate bound check local freeing */
1084 o(S, 0x5250); /* save returned value, if any */1087 o(0x5250); /* save returned value, if any */
1085 greloc(S, cur_text_section, sym_data, S->tccgen_ind + 1, R_386_32);1088 greloc(cur_text_section, sym_data, ind + 1, R_386_32);
1086 oad(S, 0xb8, 0); /* mov %eax, xxx */1089 oad(0xb8, 0); /* mov %eax, xxx */
1087 gen_static_call(S, TOK___bound_local_delete);1090 gen_static_call(TOK___bound_local_delete);
1088 o(S, 0x585a); /* restore returned value, if any */1091 o(0x585a); /* restore returned value, if any */
1089}1092}
1090#endif1093#endif
1091 1094
1092/* Save the stack pointer onto the stack */1095/* Save the stack pointer onto the stack */
1093ST_FUNC void gen_vla_sp_save(TCCState* S, int addr) {1096ST_FUNC void gen_vla_sp_save(int addr) {
1094 /* mov %esp,addr(%ebp)*/1097 /* mov %esp,addr(%ebp)*/
1095 o(S, 0x89);1098 o(0x89);
1096 gen_modrm(S, TREG_ESP, VT_LOCAL, NULL, addr);1099 gen_modrm(TREG_ESP, VT_LOCAL, NULL, addr);
1097}1100}
1098 1101
1099/* Restore the SP from a location on the stack */1102/* Restore the SP from a location on the stack */
1100ST_FUNC void gen_vla_sp_restore(TCCState* S, int addr) {1103ST_FUNC void gen_vla_sp_restore(int addr) {
1101 o(S, 0x8b);1104 o(0x8b);
1102 gen_modrm(S, TREG_ESP, VT_LOCAL, NULL, addr);1105 gen_modrm(TREG_ESP, VT_LOCAL, NULL, addr);
1103}1106}
1104 1107
1105/* Subtract from the stack pointer, and push the resulting value onto the stack */1108/* Subtract from the stack pointer, and push the resulting value onto the stack */
1106ST_FUNC void gen_vla_alloc(TCCState* S, CType *type, int align) {1109ST_FUNC void gen_vla_alloc(CType *type, int align) {
1107 int use_call = 0;1110 int use_call = 0;
1108 1111
1109#if defined(CONFIG_TCC_BCHECK)1112#if defined(CONFIG_TCC_BCHECK)
1110 use_call = S->do_bounds_check;1113 use_call = tcc_state->do_bounds_check;
1111#endif1114#endif
1112#ifdef TCC_TARGET_PE /* alloca does more than just adjust %rsp on Windows */1115#ifdef TCC_TARGET_PE /* alloca does more than just adjust %rsp on Windows */
1113 use_call = 1;1116 use_call = 1;
1114#endif1117#endif
1115 if (use_call)1118 if (use_call)
1116 {1119 {
1117 vpush_helper_func(S, TOK_alloca);1120 vpush_helper_func(TOK_alloca);
1118 vswap(S); /* Move alloca ref past allocation size */1121 vswap(); /* Move alloca ref past allocation size */
1119 gfunc_call(S, 1);1122 gfunc_call(1);
1120 }1123 }
1121 else {1124 else {
1122 int r;1125 int r;
1123 r = gv(S, RC_INT); /* allocation size */1126 r = gv(RC_INT); /* allocation size */
1124 /* sub r,%rsp */1127 /* sub r,%rsp */
1125 o(S, 0x2b);1128 o(0x2b);
1126 o(S, 0xe0 | r);1129 o(0xe0 | r);
1127 /* We align to 16 bytes rather than align */1130 /* We align to 16 bytes rather than align */
1128 /* and ~15, %esp */1131 /* and ~15, %esp */
1129 o(S, 0xf0e483);1132 o(0xf0e483);
1130 vpop(S);1133 vpop();
1131 }1134 }
1132}1135}
1133 1136
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 *S, unsigned got_offset, struct sym_attr *attr)94ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
95{95{
96 Section *plt = S->plt;96 Section *plt = s1->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 (S->output_type == TCC_OUTPUT_DLL)102 if (s1->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 *S, unsigned got_offset, struct sym_a · 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(S, plt, 16);111 p = section_ptr_add(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 *S, unsigned got_offset, struct sym_a · 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 = S->plt->reloc ? S->plt->reloc->data_offset : 0;124 relofs = s1->plt->reloc ? s1->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(S, plt, 16);127 p = section_ptr_add(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 *S, unsigned got_offset, struct sym_a · 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 *S)140ST_FUNC void relocate_plt(TCCState *s1)
141{141{
142 uint8_t *p, *p_end;142 uint8_t *p, *p_end;
143 143
144 if (!S->plt)144 if (!s1->plt)
145 return;145 return;
146 146
147 p = S->plt->data;147 p = s1->plt->data;
148 p_end = p + S->plt->data_offset;148 p_end = p + s1->plt->data_offset;
149 149
150 if (S->output_type != TCC_OUTPUT_DLL && p < p_end) {150 if (s1->output_type != TCC_OUTPUT_DLL && p < p_end) {
151 add32le(p + 2, S->got->sh_addr);151 add32le(p + 2, s1->got->sh_addr);
152 add32le(p + 8, S->got->sh_addr);152 add32le(p + 8, s1->got->sh_addr);
153 p += 16;153 p += 16;
154 while (p < p_end) {154 while (p < p_end) {
155 add32le(p + 2, S->got->sh_addr);155 add32le(p + 2, s1->got->sh_addr);
156 p += 16;156 p += 16;
157 }157 }
158 }158 }
159 159
160 if (S->plt->reloc) {160 if (s1->plt->reloc) {
161 ElfW_Rel *rel;161 ElfW_Rel *rel;
162 int x = S->plt->sh_addr + 16 + 6;162 int x = s1->plt->sh_addr + 16 + 6;
163 p = S->got->data;163 p = s1->got->data;
164 for_each_elem(S->plt->reloc, 0, rel, ElfW_Rel) {164 for_each_elem(s1->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 *S) · 1 unmodified line
169}169}
170#endif170#endif
171 171
172void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)172void relocate(TCCState *s1, 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 *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a · 1 unmodified line
177 177
178 switch (type) {178 switch (type) {
179 case R_386_32:179 case R_386_32:
180 if (S->output_type == TCC_OUTPUT_DLL) {180 if (s1->output_type == TCC_OUTPUT_DLL) {
181 esym_index = get_sym_attr(S, sym_index, 0)->dyn_index;181 esym_index = get_sym_attr(s1, 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 *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a · 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 (S->output_type == TCC_OUTPUT_DLL) {195 if (s1->output_type == TCC_OUTPUT_DLL) {
196 /* DLL relocation */196 /* DLL relocation */
197 esym_index = get_sym_attr(S, sym_index, 0)->dyn_index;197 esym_index = get_sym_attr(s1, 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 *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a · 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, S->got->sh_addr - addr);215 add32le(ptr, s1->got->sh_addr - addr);
216 return;216 return;
217 case R_386_GOTOFF:217 case R_386_GOTOFF:
218 add32le(ptr, val - S->got->sh_addr);218 add32le(ptr, val - s1->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(S, sym_index, 0)->got_offset);223 add32le(ptr, get_sym_attr(s1, sym_index, 0)->got_offset);
224 return;224 return;
225 case R_386_16:225 case R_386_16:
226 if (S->output_format != TCC_OUTPUT_FORMAT_BINARY) {226 if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) {
227 output_file:227 output_file:
228 tcc_error(S, "can only produce 16-bit binary files");228 tcc_error("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 (S->output_format != TCC_OUTPUT_FORMAT_BINARY)233 if (s1->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 - S->pe_imagebase);239 add32le(ptr, val - s1->pe_imagebase);
240#endif240#endif
241 /* do nothing */241 /* do nothing */
242 return;242 return;
@@ -267,12 +267,12 @@ void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a · 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 = S->sections[sym->st_shndx];270 sec = s1->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(S, "unexpected R_386_TLS_GD pattern");275 tcc_error("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 *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a · 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(S, "unexpected R_386_TLS_LDM pattern");298 tcc_error("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 *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a · 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 = S->sections[sym->st_shndx];309 sec = s1->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+393−470
@@ -65,6 +65,7 @@ · 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;
68TCC_SEM(static tcc_compile_sem);69TCC_SEM(static tcc_compile_sem);
69 70
70#ifdef MEM_DEBUG71#ifdef MEM_DEBUG
@@ -110,11 +111,11 @@ static inline char *config_tccdir_w32(char *path) · 39 unmodified lines
110#endif111#endif
111 112
112#ifdef TCC_TARGET_PE113#ifdef TCC_TARGET_PE
113static void tcc_add_systemdir(TCCState *S)114static void tcc_add_systemdir(TCCState *s)
114{115{
115 char buf[1000];116 char buf[1000];
116 GetSystemDirectory(buf, sizeof buf);117 GetSystemDirectory(buf, sizeof buf);
117 tcc_add_library_path(S, normalize_slashes(buf));118 tcc_add_library_path(s, normalize_slashes(buf));
118}119}
119#endif120#endif
120#endif121#endif
@@ -159,19 +160,19 @@ ST_FUNC void post_sem(TCCSem *p) · 38 unmodified lines
159#endif160#endif
160#endif161#endif
161 162
162PUB_FUNC void tcc_enter_state(TCCState *S)163PUB_FUNC void tcc_enter_state(TCCState *s1)
163{164{
164 if (S->error_set_jmp_enabled)165 if (s1->error_set_jmp_enabled)
165 return;166 return;
166 WAIT_SEM(&tcc_compile_sem);167 WAIT_SEM(&tcc_compile_sem);
167 /*S = S;*/168 tcc_state = s1;
168}169}
169 170
170PUB_FUNC void tcc_exit_state(TCCState *S)171PUB_FUNC void tcc_exit_state(TCCState *s1)
171{172{
172 if (S->error_set_jmp_enabled)173 if (s1->error_set_jmp_enabled)
173 return;174 return;
174 S = NULL;175 tcc_state = NULL;
175 POST_SEM(&tcc_compile_sem);176 POST_SEM(&tcc_compile_sem);
176}177}
177 178
@@ -233,10 +234,10 @@ PUB_FUNC char *tcc_fileextension (const char *name) · 55 unmodified lines
233 return e ? e : strchr(b, 0);234 return e ? e : strchr(b, 0);
234}235}
235 236
236ST_FUNC char *tcc_load_text(TCCState* S, int fd)237ST_FUNC char *tcc_load_text(int fd)
237{238{
238 int len = lseek(fd, 0, SEEK_END);239 int len = lseek(fd, 0, SEEK_END);
239 char *buf = load_data(S, fd, 0, len + 1);240 char *buf = load_data(fd, 0, len + 1);
240 buf[len] = 0;241 buf[len] = 0;
241 return buf;242 return buf;
242}243}
@@ -248,69 +249,44 @@ ST_FUNC char *tcc_load_text(TCCState* S, int fd) · 5 unmodified lines
248#undef malloc249#undef malloc
249#undef realloc250#undef realloc
250 251
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
276#ifndef MEM_DEBUG252#ifndef MEM_DEBUG
277 253
278PUB_FUNC void tcc_free(TCCState* S, void *ptr)254PUB_FUNC void tcc_free(void *ptr)
279{255{
280 free(ptr);256 free(ptr);
281}257}
282 258
283PUB_FUNC void *tcc_malloc(TCCState* S, unsigned long size)259PUB_FUNC void *tcc_malloc(unsigned long size)
284{260{
285 void *ptr;261 void *ptr;
286 ptr = malloc(size);262 ptr = malloc(size);
287 if (!ptr && size)263 if (!ptr && size)
288 _tcc_error(S, "memory full (malloc)");264 _tcc_error("memory full (malloc)");
289 return ptr;265 return ptr;
290}266}
291 267
292PUB_FUNC void *tcc_mallocz(TCCState* S, unsigned long size)268PUB_FUNC void *tcc_mallocz(unsigned long size)
293{269{
294 void *ptr;270 void *ptr;
295 ptr = tcc_malloc(S, size);271 ptr = tcc_malloc(size);
296 if (size)272 if (size)
297 memset(ptr, 0, size);273 memset(ptr, 0, size);
298 return ptr;274 return ptr;
299}275}
300 276
301PUB_FUNC void *tcc_realloc(TCCState* S, void *ptr, unsigned long size)277PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size)
302{278{
303 void *ptr1;279 void *ptr1;
304 ptr1 = realloc(ptr, size);280 ptr1 = realloc(ptr, size);
305 if (!ptr1 && size)281 if (!ptr1 && size)
306 _tcc_error(S, "memory full (realloc)");282 _tcc_error("memory full (realloc)");
307 return ptr1;283 return ptr1;
308}284}
309 285
310PUB_FUNC char *tcc_strdup(TCCState* S, const char *str)286PUB_FUNC char *tcc_strdup(const char *str)
311{287{
312 char *ptr;288 char *ptr;
313 ptr = tcc_malloc(S, strlen(str) + 1);289 ptr = tcc_malloc(strlen(str) + 1);
314 strcpy(ptr, str);290 strcpy(ptr, str);
315 return ptr;291 return ptr;
316}292}
@@ -361,14 +337,14 @@ static mem_debug_header_t *malloc_check(void *ptr, const char *msg) · 44 unmodified lines
361 return header;337 return header;
362}338}
363 339
364PUB_FUNC void *tcc_malloc_debug(TCCState* S, unsigned long size, const char *file, int line)340PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line)
365{341{
366 int ofs;342 int ofs;
367 mem_debug_header_t *header;343 mem_debug_header_t *header;
368 344
369 header = malloc(sizeof(mem_debug_header_t) + size);345 header = malloc(sizeof(mem_debug_header_t) + size);
370 if (!header)346 if (!header)
371 _tcc_error(S, "memory full (malloc)");347 _tcc_error("memory full (malloc)");
372 348
373 header->magic1 = MEM_DEBUG_MAGIC1;349 header->magic1 = MEM_DEBUG_MAGIC1;
374 header->magic2 = MEM_DEBUG_MAGIC2;350 header->magic2 = MEM_DEBUG_MAGIC2;
@@ -392,7 +368,7 @@ PUB_FUNC void *tcc_malloc_debug(TCCState* S, unsigned long size, const char *fil · 17 unmodified lines
392 return MEM_USER_PTR(header);368 return MEM_USER_PTR(header);
393}369}
394 370
395PUB_FUNC void tcc_free_debug(TCCState* S, void *ptr)371PUB_FUNC void tcc_free_debug(void *ptr)
396{372{
397 mem_debug_header_t *header;373 mem_debug_header_t *header;
398 if (!ptr)374 if (!ptr)
@@ -409,26 +385,26 @@ PUB_FUNC void tcc_free_debug(TCCState* S, void *ptr) · 10 unmodified lines
409 free(header);385 free(header);
410}386}
411 387
412PUB_FUNC void *tcc_mallocz_debug(TCCState* S, unsigned long size, const char *file, int line)388PUB_FUNC void *tcc_mallocz_debug(unsigned long size, const char *file, int line)
413{389{
414 void *ptr;390 void *ptr;
415 ptr = tcc_malloc_debug(S, size,file,line);391 ptr = tcc_malloc_debug(size,file,line);
416 memset(ptr, 0, size);392 memset(ptr, 0, size);
417 return ptr;393 return ptr;
418}394}
419 395
420PUB_FUNC void *tcc_realloc_debug(TCCState* S, void *ptr, unsigned long size, const char *file, int line)396PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file, int line)
421{397{
422 mem_debug_header_t *header;398 mem_debug_header_t *header;
423 int mem_debug_chain_update = 0;399 int mem_debug_chain_update = 0;
424 if (!ptr)400 if (!ptr)
425 return tcc_malloc_debug(S, size, file, line);401 return tcc_malloc_debug(size, file, line);
426 header = malloc_check(ptr, "tcc_realloc");402 header = malloc_check(ptr, "tcc_realloc");
427 mem_cur_size -= header->size;403 mem_cur_size -= header->size;
428 mem_debug_chain_update = (header == mem_debug_chain);404 mem_debug_chain_update = (header == mem_debug_chain);
429 header = realloc(header, sizeof(mem_debug_header_t) + size);405 header = realloc(header, sizeof(mem_debug_header_t) + size);
430 if (!header)406 if (!header)
431 _tcc_error(S, "memory full (realloc)");407 _tcc_error("memory full (realloc)");
432 header->size = size;408 header->size = size;
433 write32le(MEM_DEBUG_CHECK3(header), MEM_DEBUG_MAGIC3);409 write32le(MEM_DEBUG_CHECK3(header), MEM_DEBUG_MAGIC3);
434 if (header->next)410 if (header->next)
@@ -443,10 +419,10 @@ PUB_FUNC void *tcc_realloc_debug(TCCState* S, void *ptr, unsigned long size, con · 8 unmodified lines
443 return MEM_USER_PTR(header);419 return MEM_USER_PTR(header);
444}420}
445 421
446PUB_FUNC char *tcc_strdup_debug(TCCState* S, const char *str, const char *file, int line)422PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line)
447{423{
448 char *ptr;424 char *ptr;
449 ptr = tcc_malloc_debug(S, strlen(str) + 1, file, line);425 ptr = tcc_malloc_debug(strlen(str) + 1, file, line);
450 strcpy(ptr, str);426 strcpy(ptr, str);
451 return ptr;427 return ptr;
452}428}
@@ -473,66 +449,10 @@ PUB_FUNC void tcc_memcheck(void) · 20 unmodified lines
473#define malloc(s) use_tcc_malloc(s)449#define malloc(s) use_tcc_malloc(s)
474#define realloc(p, s) use_tcc_realloc(p, s)450#define realloc(p, s) use_tcc_realloc(p, s)
475 451
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
532/********************************************************/452/********************************************************/
533/* dynarrays */453/* dynarrays */
534 454
535ST_FUNC void dynarray_add(TCCState* S, void *ptab, int *nb_ptr, void *data)455ST_FUNC void dynarray_add(void *ptab, int *nb_ptr, void *data)
536{456{
537 int nb, nb_alloc;457 int nb, nb_alloc;
538 void **pp;458 void **pp;
@@ -545,54 +465,54 @@ ST_FUNC void dynarray_add(TCCState* S, void *ptab, int *nb_ptr, void *data) · 6 unmodified lines
545 nb_alloc = 1;465 nb_alloc = 1;
546 else466 else
547 nb_alloc = nb * 2;467 nb_alloc = nb * 2;
548 pp = tcc_realloc(S, pp, nb_alloc * sizeof(void *));468 pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
549 *(void***)ptab = pp;469 *(void***)ptab = pp;
550 }470 }
551 pp[nb++] = data;471 pp[nb++] = data;
552 *nb_ptr = nb;472 *nb_ptr = nb;
553}473}
554 474
555ST_FUNC void dynarray_reset(TCCState* S, void *pp, int *n)475ST_FUNC void dynarray_reset(void *pp, int *n)
556{476{
557 void **p;477 void **p;
558 for (p = *(void***)pp; *n; ++p, --*n)478 for (p = *(void***)pp; *n; ++p, --*n)
559 if (*p)479 if (*p)
560 tcc_free(S, *p);480 tcc_free(*p);
561 tcc_free(S, *(void**)pp);481 tcc_free(*(void**)pp);
562 *(void**)pp = NULL;482 *(void**)pp = NULL;
563}483}
564 484
565static void tcc_split_path(TCCState *S, void *p_ary, int *p_nb_ary, const char *in)485static void tcc_split_path(TCCState *s, void *p_ary, int *p_nb_ary, const char *in)
566{486{
567 const char *p;487 const char *p;
568 do {488 do {
569 int c;489 int c;
570 CString str;490 CString str;
571 491
572 cstr_new(S, &str);492 cstr_new(&str);
573 for (p = in; c = *p, c != '\0' && c != PATHSEP[0]; ++p) {493 for (p = in; c = *p, c != '\0' && c != PATHSEP[0]; ++p) {
574 if (c == '{' && p[1] && p[2] == '}') {494 if (c == '{' && p[1] && p[2] == '}') {
575 c = p[1], p += 2;495 c = p[1], p += 2;
576 if (c == 'B')496 if (c == 'B')
577 cstr_cat(S, &str, S->tcc_lib_path, -1);497 cstr_cat(&str, s->tcc_lib_path, -1);
578 if (c == 'f' && S->tccpp_file) {498 if (c == 'f' && file) {
579 /* substitute current file's dir */499 /* substitute current file's dir */
580 const char *f = S->tccpp_file->true_filename;500 const char *f = file->true_filename;
581 const char *b = tcc_basename(f);501 const char *b = tcc_basename(f);
582 if (b > f)502 if (b > f)
583 cstr_cat(S, &str, f, b - f - 1);503 cstr_cat(&str, f, b - f - 1);
584 else504 else
585 cstr_cat(S, &str, ".", 1);505 cstr_cat(&str, ".", 1);
586 }506 }
587 } else {507 } else {
588 cstr_ccat(S, &str, c);508 cstr_ccat(&str, c);
589 }509 }
590 }510 }
591 if (str.size) {511 if (str.size) {
592 cstr_ccat(S, &str, '\0');512 cstr_ccat(&str, '\0');
593 dynarray_add(S, p_ary, p_nb_ary, tcc_strdup(S, str.data));513 dynarray_add(p_ary, p_nb_ary, tcc_strdup(str.data));
594 }514 }
595 cstr_free(S, &str);515 cstr_free(&str);
596 in = p+1;516 in = p+1;
597 } while (*p);517 } while (*p);
598}518}
@@ -608,26 +528,27 @@ static void tcc_split_path(TCCState *S, void *p_ary, int *p_nb_ary, const char * · 9 unmodified lines
608/* error1() modes */528/* error1() modes */
609enum { ERROR_WARN, ERROR_NOABORT, ERROR_ERROR };529enum { ERROR_WARN, ERROR_NOABORT, ERROR_ERROR };
610 530
611static void error1(TCCState* S, int mode, const char *fmt, va_list ap)531static void error1(int mode, const char *fmt, va_list ap)
612{532{
613 BufferedFile **pf, *f;533 BufferedFile **pf, *f;
534 TCCState *s1 = tcc_state;
614 CString cs;535 CString cs;
615 536
616 cstr_new(S, &cs);537 cstr_new(&cs);
617 538
618 if (S == NULL)539 if (s1 == NULL)
619 /* can happen only if called from tcc_malloc(): 'out of memory' */540 /* can happen only if called from tcc_malloc(): 'out of memory' */
620 goto no_file;541 goto no_file;
621 542
622 tcc_exit_state(S);543 tcc_exit_state(s1);
623 544
624 if (mode == ERROR_WARN) {545 if (mode == ERROR_WARN) {
625 if (S->warn_error)546 if (s1->warn_error)
626 mode = ERROR_ERROR;547 mode = ERROR_ERROR;
627 if (S->warn_num) {548 if (s1->warn_num) {
628 /* handle tcc_warning_c(warn_option)(fmt, ...) */549 /* handle tcc_warning_c(warn_option)(fmt, ...) */
629 int wopt = *(&S->warn_none + S->warn_num);550 int wopt = *(&s1->warn_none + s1->warn_num);
630 S->warn_num = 0;551 s1->warn_num = 0;
631 if (0 == (wopt & WARN_ON))552 if (0 == (wopt & WARN_ON))
632 return;553 return;
633 if (wopt & WARN_ERR)554 if (wopt & WARN_ERR)
@@ -635,102 +556,102 @@ static void error1(TCCState* S, int mode, const char *fmt, va_list ap) · 1 unmodified line
635 if (wopt & WARN_NOE)556 if (wopt & WARN_NOE)
636 mode = ERROR_WARN;557 mode = ERROR_WARN;
637 }558 }
638 if (S->warn_none)559 if (s1->warn_none)
639 return;560 return;
640 }561 }
641 562
642 f = NULL;563 f = NULL;
643 if (S->error_set_jmp_enabled) { /* we're called while parsing a file */564 if (s1->error_set_jmp_enabled) { /* we're called while parsing a file */
644 /* use upper file if inline ":asm:" or token ":paste:" */565 /* use upper file if inline ":asm:" or token ":paste:" */
645 for (f = S->tccpp_file; f && f->filename[0] == ':'; f = f->prev)566 for (f = file; f && f->filename[0] == ':'; f = f->prev)
646 ;567 ;
647 }568 }
648 if (f) {569 if (f) {
649 for(pf = S->include_stack; pf < S->include_stack_ptr; pf++)570 for(pf = s1->include_stack; pf < s1->include_stack_ptr; pf++)
650 cstr_printf(S, &cs, "In file included from %s:%d:\n",571 cstr_printf(&cs, "In file included from %s:%d:\n",
651 (*pf)->filename, (*pf)->line_num);572 (*pf)->filename, (*pf)->line_num);
652 cstr_printf(S, &cs, "%s:%d: ",573 cstr_printf(&cs, "%s:%d: ",
653 f->filename, (*pf)->line_num - !!(S->tccpp_tok_flags & TOK_FLAG_BOL));574 f->filename, f->line_num - !!(tok_flags & TOK_FLAG_BOL));
654 } else if (S->current_filename) {575 } else if (s1->current_filename) {
655 cstr_printf(S, &cs, "%s: ", S->current_filename);576 cstr_printf(&cs, "%s: ", s1->current_filename);
656 }577 }
657 578
658no_file:579no_file:
659 if (0 == cs.size)580 if (0 == cs.size)
660 cstr_printf(S, &cs, "tcc: ");581 cstr_printf(&cs, "tcc: ");
661 cstr_printf(S, &cs, mode == ERROR_WARN ? "warning: " : "error: ");582 cstr_printf(&cs, mode == ERROR_WARN ? "warning: " : "error: ");
662 cstr_vprintf(S, &cs, fmt, ap);583 cstr_vprintf(&cs, fmt, ap);
663 if (!S || !S->error_func) {584 if (!s1 || !s1->error_func) {
664 /* default case: stderr */585 /* default case: stderr */
665 if (S && S->output_type == TCC_OUTPUT_PREPROCESS && S->ppfp == stdout)586 if (s1 && s1->output_type == TCC_OUTPUT_PREPROCESS && s1->ppfp == stdout)
666 printf("\n"); /* print a newline during tcc -E */587 printf("\n"); /* print a newline during tcc -E */
667 fflush(stdout); /* flush -v output */588 fflush(stdout); /* flush -v output */
668 fprintf(stderr, "%s\n", (char*)cs.data);589 fprintf(stderr, "%s\n", (char*)cs.data);
669 fflush(stderr); /* print error/warning now (win32) */590 fflush(stderr); /* print error/warning now (win32) */
670 } else {591 } else {
671 S->error_func(S->error_opaque, (char*)cs.data);592 s1->error_func(s1->error_opaque, (char*)cs.data);
672 }593 }
673 cstr_free(S, &cs);594 cstr_free(&cs);
674 if (S) {595 if (s1) {
675 if (mode != ERROR_WARN)596 if (mode != ERROR_WARN)
676 S->nb_errors++;597 s1->nb_errors++;
677 if (mode != ERROR_ERROR)598 if (mode != ERROR_ERROR)
678 return;599 return;
679 if (S->error_set_jmp_enabled)600 if (s1->error_set_jmp_enabled)
680 longjmp(S->error_jmp_buf, 1);601 longjmp(s1->error_jmp_buf, 1);
681 }602 }
682 exit(1);603 exit(1);
683}604}
684 605
685LIBTCCAPI void tcc_set_error_func(TCCState *S, void *error_opaque, TCCErrorFunc error_func)606LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque, TCCErrorFunc error_func)
686{607{
687 S->error_opaque = error_opaque;608 s->error_opaque = error_opaque;
688 S->error_func = error_func;609 s->error_func = error_func;
689}610}
690 611
691LIBTCCAPI TCCErrorFunc tcc_get_error_func(TCCState *S)612LIBTCCAPI TCCErrorFunc tcc_get_error_func(TCCState *s)
692{613{
693 return S->error_func;614 return s->error_func;
694}615}
695 616
696LIBTCCAPI void *tcc_get_error_opaque(TCCState *S)617LIBTCCAPI void *tcc_get_error_opaque(TCCState *s)
697{618{
698 return S->error_opaque;619 return s->error_opaque;
699}620}
700 621
701/* error without aborting current compilation */622/* error without aborting current compilation */
702PUB_FUNC void _tcc_error_noabort(TCCState* S, const char *fmt, ...)623PUB_FUNC void _tcc_error_noabort(const char *fmt, ...)
703{624{
704 va_list ap;625 va_list ap;
705 va_start(ap, fmt);626 va_start(ap, fmt);
706 error1(S, ERROR_NOABORT, fmt, ap);627 error1(ERROR_NOABORT, fmt, ap);
707 va_end(ap);628 va_end(ap);
708}629}
709 630
710PUB_FUNC void _tcc_error(TCCState* S, const char *fmt, ...)631PUB_FUNC void _tcc_error(const char *fmt, ...)
711{632{
712 va_list ap;633 va_list ap;
713 va_start(ap, fmt);634 va_start(ap, fmt);
714 for (;;) error1(S, ERROR_ERROR, fmt, ap);635 for (;;) error1(ERROR_ERROR, fmt, ap);
715}636}
716 637
717PUB_FUNC void _tcc_warning(TCCState* S, const char *fmt, ...)638PUB_FUNC void _tcc_warning(const char *fmt, ...)
718{639{
719 va_list ap;640 va_list ap;
720 va_start(ap, fmt);641 va_start(ap, fmt);
721 error1(S, ERROR_WARN, fmt, ap);642 error1(ERROR_WARN, fmt, ap);
722 va_end(ap);643 va_end(ap);
723}644}
724 645
725/********************************************************/646/********************************************************/
726/* I/O layer */647/* I/O layer */
727 648
728ST_FUNC void tcc_open_bf(TCCState *S, const char *filename, int initlen)649ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen)
729{650{
730 BufferedFile *bf;651 BufferedFile *bf;
731 int buflen = initlen ? initlen : IO_BUF_SIZE;652 int buflen = initlen ? initlen : IO_BUF_SIZE;
732 653
733 bf = tcc_mallocz(S, sizeof(BufferedFile) + buflen);654 bf = tcc_mallocz(sizeof(BufferedFile) + buflen);
734 bf->buf_ptr = bf->buffer;655 bf->buf_ptr = bf->buffer;
735 bf->buf_end = bf->buffer + initlen;656 bf->buf_end = bf->buffer + initlen;
736 bf->buf_end[0] = CH_EOB; /* put eob symbol */657 bf->buf_end[0] = CH_EOB; /* put eob symbol */
@@ -740,51 +661,52 @@ ST_FUNC void tcc_open_bf(TCCState *S, const char *filename, int initlen) · 3 unmodified lines
740#endif661#endif
741 bf->true_filename = bf->filename;662 bf->true_filename = bf->filename;
742 bf->line_num = 1;663 bf->line_num = 1;
743 bf->ifdef_stack_ptr = S->ifdef_stack_ptr;664 bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
744 bf->fd = -1;665 bf->fd = -1;
745 bf->prev = S->tccpp_file;666 bf->prev = file;
746 S->tccpp_file = bf;667 file = bf;
747 S->tccpp_tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;668 tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
748}669}
749 670
750ST_FUNC void tcc_close(TCCState* S)671ST_FUNC void tcc_close(void)
751{672{
752 BufferedFile *bf = S->tccpp_file;673 TCCState *s1 = tcc_state;
674 BufferedFile *bf = file;
753 if (bf->fd > 0) {675 if (bf->fd > 0) {
754 close(bf->fd);676 close(bf->fd);
755 total_lines += bf->line_num;677 total_lines += bf->line_num;
756 }678 }
757 if (bf->true_filename != bf->filename)679 if (bf->true_filename != bf->filename)
758 tcc_free(S, bf->true_filename);680 tcc_free(bf->true_filename);
759 S->tccpp_file = bf->prev;681 file = bf->prev;
760 tcc_free(S, bf);682 tcc_free(bf);
761}683}
762 684
763static int _tcc_open(TCCState *S, const char *filename)685static int _tcc_open(TCCState *s1, const char *filename)
764{686{
765 int fd;687 int fd;
766 if (strcmp(filename, "-") == 0)688 if (strcmp(filename, "-") == 0)
767 fd = 0, filename = "<stdin>";689 fd = 0, filename = "<stdin>";
768 else690 else
769 fd = open(filename, O_RDONLY | O_BINARY);691 fd = open(filename, O_RDONLY | O_BINARY);
770 if ((S->verbose == 2 && fd >= 0) || S->verbose == 3)692 if ((s1->verbose == 2 && fd >= 0) || s1->verbose == 3)
771 printf("%s %*s%s\n", fd < 0 ? "nf":"->",693 printf("%s %*s%s\n", fd < 0 ? "nf":"->",
772 (int)(S->include_stack_ptr - S->include_stack), "", filename);694 (int)(s1->include_stack_ptr - s1->include_stack), "", filename);
773 return fd;695 return fd;
774}696}
775 697
776ST_FUNC int tcc_open(TCCState *S, const char *filename)698ST_FUNC int tcc_open(TCCState *s1, const char *filename)
777{699{
778 int fd = _tcc_open(S, filename);700 int fd = _tcc_open(s1, filename);
779 if (fd < 0)701 if (fd < 0)
780 return -1;702 return -1;
781 tcc_open_bf(S, filename, 0);703 tcc_open_bf(s1, filename, 0);
782 S->tccpp_file->fd = fd;704 file->fd = fd;
783 return 0;705 return 0;
784}706}
785 707
786/* compile the file opened in 'file'. Return non zero if errors. */708/* compile the file opened in 'file'. Return non zero if errors. */
787static int tcc_compile(TCCState *S, int filetype, const char *str, int fd)709static int tcc_compile(TCCState *s1, int filetype, const char *str, int fd)
788{710{
789 /* Here we enter the code section where we use the global variables for711 /* Here we enter the code section where we use the global variables for
790 parsing and code generation (tccpp.c, tccgen.c, <target>-gen.c).712 parsing and code generation (tccpp.c, tccgen.c, <target>-gen.c).
@@ -793,62 +715,62 @@ static int tcc_compile(TCCState *S, int filetype, const char *str, int fd) · 2 unmodified lines
793 Alternatively we could use thread local storage for those global715 Alternatively we could use thread local storage for those global
794 variables, which may or may not have advantages */716 variables, which may or may not have advantages */
795 717
796 tcc_enter_state(S);718 tcc_enter_state(s1);
797 S->error_set_jmp_enabled = 1;719 s1->error_set_jmp_enabled = 1;
798 720
799 if (setjmp(S->error_jmp_buf) == 0) {721 if (setjmp(s1->error_jmp_buf) == 0) {
800 S->nb_errors = 0;722 s1->nb_errors = 0;
801 723
802 if (fd == -1) {724 if (fd == -1) {
803 int len = strlen(str);725 int len = strlen(str);
804 tcc_open_bf(S, "<string>", len);726 tcc_open_bf(s1, "<string>", len);
805 memcpy(S->tccpp_file->buffer, str, len);727 memcpy(file->buffer, str, len);
806 } else {728 } else {
807 tcc_open_bf(S, str, 0);729 tcc_open_bf(s1, str, 0);
808 S->tccpp_file->fd = fd;730 file->fd = fd;
809 }731 }
810 732
811 tccelf_begin_file(S);733 tccelf_begin_file(s1);
812 preprocess_start(S, filetype);734 preprocess_start(s1, filetype);
813 tccgen_init(S);735 tccgen_init(s1);
814 if (S->output_type == TCC_OUTPUT_PREPROCESS) {736 if (s1->output_type == TCC_OUTPUT_PREPROCESS) {
815 tcc_preprocess(S);737 tcc_preprocess(s1);
816 } else if (filetype & (AFF_TYPE_ASM | AFF_TYPE_ASMPP)) {738 } else if (filetype & (AFF_TYPE_ASM | AFF_TYPE_ASMPP)) {
817 tcc_assemble(S, !!(filetype & AFF_TYPE_ASMPP));739 tcc_assemble(s1, !!(filetype & AFF_TYPE_ASMPP));
818 } else {740 } else {
819 tccgen_compile(S);741 tccgen_compile(s1);
820 }742 }
821 }743 }
822 tccgen_finish(S);744 tccgen_finish(s1);
823 preprocess_end(S);745 preprocess_end(s1);
824 746
825 S->error_set_jmp_enabled = 0;747 s1->error_set_jmp_enabled = 0;
826 tcc_exit_state(S);748 tcc_exit_state(s1);
827 749
828 tccelf_end_file(S);750 tccelf_end_file(s1);
829 return S->nb_errors != 0 ? -1 : 0;751 return s1->nb_errors != 0 ? -1 : 0;
830}752}
831 753
832LIBTCCAPI int tcc_compile_string(TCCState *S, const char *str)754LIBTCCAPI int tcc_compile_string(TCCState *s, const char *str)
833{755{
834 return tcc_compile(S, S->filetype, str, -1);756 return tcc_compile(s, s->filetype, str, -1);
835}757}
836 758
837/* define a preprocessor symbol. value can be NULL, sym can be "sym=val" */759/* define a preprocessor symbol. value can be NULL, sym can be "sym=val" */
838LIBTCCAPI void tcc_define_symbol(TCCState *S, const char *sym, const char *value)760LIBTCCAPI void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
839{761{
840 const char *eq;762 const char *eq;
841 if (NULL == (eq = strchr(sym, '=')))763 if (NULL == (eq = strchr(sym, '=')))
842 eq = strchr(sym, 0);764 eq = strchr(sym, 0);
843 if (NULL == value)765 if (NULL == value)
844 value = *eq ? eq + 1 : "1";766 value = *eq ? eq + 1 : "1";
845 cstr_printf(S, &S->cmdline_defs, "#define %.*s %s\n", (int)(eq-sym), sym, value);767 cstr_printf(&s1->cmdline_defs, "#define %.*s %s\n", (int)(eq-sym), sym, value);
846}768}
847 769
848/* undefine a preprocessor symbol */770/* undefine a preprocessor symbol */
849LIBTCCAPI void tcc_undefine_symbol(TCCState *S, const char *sym)771LIBTCCAPI void tcc_undefine_symbol(TCCState *s1, const char *sym)
850{772{
851 cstr_printf(S, &S->cmdline_defs, "#undef %s\n", sym);773 cstr_printf(&s1->cmdline_defs, "#undef %s\n", sym);
852}774}
853 775
854 776
@@ -856,7 +778,7 @@ LIBTCCAPI TCCState *tcc_new(void) · 1 unmodified line
856{778{
857 TCCState *s;779 TCCState *s;
858 780
859 s = tcc_mallocz_base(sizeof(TCCState));781 s = tcc_mallocz(sizeof(TCCState));
860 if (!s)782 if (!s)
861 return NULL;783 return NULL;
862#ifdef MEM_DEBUG784#ifdef MEM_DEBUG
@@ -898,153 +820,153 @@ LIBTCCAPI TCCState *tcc_new(void) · 35 unmodified lines
898 return s;820 return s;
899}821}
900 822
901LIBTCCAPI void tcc_delete(TCCState *S)823LIBTCCAPI void tcc_delete(TCCState *s1)
902{824{
903 /* free sections */825 /* free sections */
904 tccelf_delete(S);826 tccelf_delete(s1);
905 827
906 /* free library paths */828 /* free library paths */
907 dynarray_reset(S, &S->library_paths, &S->nb_library_paths);829 dynarray_reset(&s1->library_paths, &s1->nb_library_paths);
908 dynarray_reset(S, &S->crt_paths, &S->nb_crt_paths);830 dynarray_reset(&s1->crt_paths, &s1->nb_crt_paths);
909 831
910 /* free include paths */832 /* free include paths */
911 dynarray_reset(S, &S->include_paths, &S->nb_include_paths);833 dynarray_reset(&s1->include_paths, &s1->nb_include_paths);
912 dynarray_reset(S, &S->sysinclude_paths, &S->nb_sysinclude_paths);834 dynarray_reset(&s1->sysinclude_paths, &s1->nb_sysinclude_paths);
913 835
914 tcc_free(S, S->tcc_lib_path);836 tcc_free(s1->tcc_lib_path);
915 tcc_free(S, S->soname);837 tcc_free(s1->soname);
916 tcc_free(S, S->rpath);838 tcc_free(s1->rpath);
917 tcc_free(S, S->init_symbol);839 tcc_free(s1->init_symbol);
918 tcc_free(S, S->fini_symbol);840 tcc_free(s1->fini_symbol);
919 tcc_free(S, S->outfile);841 tcc_free(s1->outfile);
920 tcc_free(S, S->deps_outfile);842 tcc_free(s1->deps_outfile);
921 dynarray_reset(S, &S->files, &S->nb_files);843 dynarray_reset(&s1->files, &s1->nb_files);
922 dynarray_reset(S, &S->target_deps, &S->nb_target_deps);844 dynarray_reset(&s1->target_deps, &s1->nb_target_deps);
923 dynarray_reset(S, &S->pragma_libs, &S->nb_pragma_libs);845 dynarray_reset(&s1->pragma_libs, &s1->nb_pragma_libs);
924 dynarray_reset(S, &S->argv, &S->argc);846 dynarray_reset(&s1->argv, &s1->argc);
925 cstr_free(S, &S->cmdline_defs);847 cstr_free(&s1->cmdline_defs);
926 cstr_free(S, &S->cmdline_incl);848 cstr_free(&s1->cmdline_incl);
927#ifdef TCC_IS_NATIVE849#ifdef TCC_IS_NATIVE
928 /* free runtime memory */850 /* free runtime memory */
929 tcc_run_free(S);851 tcc_run_free(s1);
930#endif852#endif
931 853
932 tcc_free_base(S);854 tcc_free(s1);
933#ifdef MEM_DEBUG855#ifdef MEM_DEBUG
934 if (0 == --nb_states)856 if (0 == --nb_states)
935 tcc_memcheck();857 tcc_memcheck();
936#endif858#endif
937}859}
938 860
939LIBTCCAPI int tcc_set_output_type(TCCState *S, int output_type)861LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
940{862{
941 S->output_type = output_type;863 s->output_type = output_type;
942 864
943 if (!S->nostdinc) {865 if (!s->nostdinc) {
944 /* default include paths */866 /* default include paths */
945 /* -isystem paths have already been handled */867 /* -isystem paths have already been handled */
946 tcc_add_sysinclude_path(S, CONFIG_TCC_SYSINCLUDEPATHS);868 tcc_add_sysinclude_path(s, CONFIG_TCC_SYSINCLUDEPATHS);
947 }869 }
948#ifdef CONFIG_TCC_BCHECK870#ifdef CONFIG_TCC_BCHECK
949 if (S->do_bounds_check) {871 if (s->do_bounds_check) {
950 /* if bound checking, then add corresponding sections */872 /* if bound checking, then add corresponding sections */
951 tccelf_bounds_new(S);873 tccelf_bounds_new(s);
952 }874 }
953#endif875#endif
954 if (S->do_debug) {876 if (s->do_debug) {
955 /* add debug sections */877 /* add debug sections */
956 tccelf_stab_new(S);878 tccelf_stab_new(s);
957 }879 }
958 if (output_type == TCC_OUTPUT_OBJ) {880 if (output_type == TCC_OUTPUT_OBJ) {
959 /* always elf for objects */881 /* always elf for objects */
960 S->output_format = TCC_OUTPUT_FORMAT_ELF;882 s->output_format = TCC_OUTPUT_FORMAT_ELF;
961 return 0;883 return 0;
962 }884 }
963 885
964 tcc_add_library_path(S, CONFIG_TCC_LIBPATHS);886 tcc_add_library_path(s, CONFIG_TCC_LIBPATHS);
965 887
966#ifdef TCC_TARGET_PE888#ifdef TCC_TARGET_PE
967# ifdef _WIN32889# ifdef _WIN32
968 /* allow linking with system dll's directly */890 /* allow linking with system dll's directly */
969 tcc_add_systemdir(S);891 tcc_add_systemdir(s);
970# endif892# endif
971 /* target PE has its own startup code in libtcc1.a */893 /* target PE has its own startup code in libtcc1.a */
972 return 0;894 return 0;
973 895
974#elif defined TCC_TARGET_MACHO896#elif defined TCC_TARGET_MACHO
975# ifdef TCC_IS_NATIVE897# ifdef TCC_IS_NATIVE
976 tcc_add_macos_sdkpath(S);898 tcc_add_macos_sdkpath(s);
977# endif899# endif
978 /* Mach-O with LC_MAIN doesn't need any crt startup code. */900 /* Mach-O with LC_MAIN doesn't need any crt startup code. */
979 return 0;901 return 0;
980 902
981#else903#else
982 /* paths for crt objects */904 /* paths for crt objects */
983 tcc_split_path(S, &S->crt_paths, &S->nb_crt_paths, CONFIG_TCC_CRTPREFIX);905 tcc_split_path(s, &s->crt_paths, &s->nb_crt_paths, CONFIG_TCC_CRTPREFIX);
984 /* add libc crt1/crti objects */906 /* add libc crt1/crti objects */
985 if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) &&907 if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) &&
986 !S->nostdlib) {908 !s->nostdlib) {
987#if TARGETOS_OpenBSD909#if TARGETOS_OpenBSD
988 if (output_type != TCC_OUTPUT_DLL)910 if (output_type != TCC_OUTPUT_DLL)
989 tcc_add_crt(S, "crt0.o");911 tcc_add_crt(s, "crt0.o");
990 if (output_type == TCC_OUTPUT_DLL)912 if (output_type == TCC_OUTPUT_DLL)
991 tcc_add_crt(S, "crtbeginS.o");913 tcc_add_crt(s, "crtbeginS.o");
992 else914 else
993 tcc_add_crt(S, "crtbegin.o");915 tcc_add_crt(s, "crtbegin.o");
994#elif TARGETOS_FreeBSD916#elif TARGETOS_FreeBSD
995 if (output_type != TCC_OUTPUT_DLL)917 if (output_type != TCC_OUTPUT_DLL)
996 tcc_add_crt(S, "crt1.o");918 tcc_add_crt(s, "crt1.o");
997 tcc_add_crt(S, "crti.o");919 tcc_add_crt(s, "crti.o");
998 if (S->static_link)920 if (s->static_link)
999 tcc_add_crt(S, "crtbeginT.o");921 tcc_add_crt(s, "crtbeginT.o");
1000 else if (output_type == TCC_OUTPUT_DLL)922 else if (output_type == TCC_OUTPUT_DLL)
1001 tcc_add_crt(S, "crtbeginS.o");923 tcc_add_crt(s, "crtbeginS.o");
1002 else924 else
1003 tcc_add_crt(S, "crtbegin.o");925 tcc_add_crt(s, "crtbegin.o");
1004#elif TARGETOS_NetBSD926#elif TARGETOS_NetBSD
1005 if (output_type != TCC_OUTPUT_DLL)927 if (output_type != TCC_OUTPUT_DLL)
1006 tcc_add_crt(S, "crt0.o");928 tcc_add_crt(s, "crt0.o");
1007 tcc_add_crt(S, "crti.o");929 tcc_add_crt(s, "crti.o");
1008 if (S->static_link)930 if (s->static_link)
1009 tcc_add_crt(S, "crtbeginT.o");931 tcc_add_crt(s, "crtbeginT.o");
1010 else if (output_type == TCC_OUTPUT_DLL)932 else if (output_type == TCC_OUTPUT_DLL)
1011 tcc_add_crt(S, "crtbeginS.o");933 tcc_add_crt(s, "crtbeginS.o");
1012 else934 else
1013 tcc_add_crt(S, "crtbegin.o");935 tcc_add_crt(s, "crtbegin.o");
1014#else936#else
1015 if (output_type != TCC_OUTPUT_DLL)937 if (output_type != TCC_OUTPUT_DLL)
1016 tcc_add_crt(S, "crt1.o");938 tcc_add_crt(s, "crt1.o");
1017 tcc_add_crt(S, "crti.o");939 tcc_add_crt(s, "crti.o");
1018#endif940#endif
1019 }941 }
1020 return 0;942 return 0;
1021#endif943#endif
1022}944}
1023 945
1024LIBTCCAPI int tcc_add_include_path(TCCState *S, const char *pathname)946LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname)
1025{947{
1026 tcc_split_path(S, &S->include_paths, &S->nb_include_paths, pathname);948 tcc_split_path(s, &s->include_paths, &s->nb_include_paths, pathname);
1027 return 0;949 return 0;
1028}950}
1029 951
1030LIBTCCAPI int tcc_add_sysinclude_path(TCCState *S, const char *pathname)952LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname)
1031{953{
1032 tcc_split_path(S, &S->sysinclude_paths, &S->nb_sysinclude_paths, pathname);954 tcc_split_path(s, &s->sysinclude_paths, &s->nb_sysinclude_paths, pathname);
1033 return 0;955 return 0;
1034}956}
1035 957
1036ST_FUNC DLLReference *tcc_add_dllref(TCCState *S, const char *dllname)958ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllname)
1037{959{
1038 DLLReference *ref = tcc_mallocz(S, sizeof(DLLReference) + strlen(dllname));960 DLLReference *ref = tcc_mallocz(sizeof(DLLReference) + strlen(dllname));
1039 strcpy(ref->name, dllname);961 strcpy(ref->name, dllname);
1040 dynarray_add(S, &S->loaded_dlls, &S->nb_loaded_dlls, ref);962 dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, ref);
1041 return ref;963 return ref;
1042}964}
1043 965
1044/* OpenBSD: choose latest from libxxx.so.x.y versions */966/* OpenBSD: choose latest from libxxx.so.x.y versions */
1045#if defined TARGETOS_OpenBSD && !defined _WIN32967#if defined TARGETOS_OpenBSD && !defined _WIN32
1046#include <glob.h>968#include <glob.h>
1047static int tcc_glob_so(TCCState *S, const char *pattern, char *buf, int size)969static int tcc_glob_so(TCCState *s1, const char *pattern, char *buf, int size)
1048{970{
1049 const char *star;971 const char *star;
1050 glob_t g;972 glob_t g;
@@ -1066,25 +988,25 @@ static int tcc_glob_so(TCCState *S, const char *pattern, char *buf, int size) · 15 unmodified lines
1066}988}
1067#endif989#endif
1068 990
1069ST_FUNC int tcc_add_file_internal(TCCState *S, const char *filename, int flags)991ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
1070{992{
1071 int fd, ret = -1;993 int fd, ret = -1;
1072 994
1073#if defined TARGETOS_OpenBSD && !defined _WIN32995#if defined TARGETOS_OpenBSD && !defined _WIN32
1074 char buf[1024];996 char buf[1024];
1075 if (tcc_glob_so(S, filename, buf, sizeof buf) >= 0)997 if (tcc_glob_so(s1, filename, buf, sizeof buf) >= 0)
1076 filename = buf;998 filename = buf;
1077#endif999#endif
1078 1000
1079 /* open the file */1001 /* open the file */
1080 fd = _tcc_open(S, filename);1002 fd = _tcc_open(s1, filename);
1081 if (fd < 0) {1003 if (fd < 0) {
1082 if (flags & AFF_PRINT_ERROR)1004 if (flags & AFF_PRINT_ERROR)
1083 tcc_error_noabort(S, "file '%s' not found", filename);1005 tcc_error_noabort("file '%s' not found", filename);
1084 return ret;1006 return ret;
1085 }1007 }
1086 1008
1087 S->current_filename = filename;1009 s1->current_filename = filename;
1088 if (flags & AFF_TYPE_BIN) {1010 if (flags & AFF_TYPE_BIN) {
1089 ElfW(Ehdr) ehdr;1011 ElfW(Ehdr) ehdr;
1090 int obj_type;1012 int obj_type;
@@ -1095,22 +1017,22 @@ ST_FUNC int tcc_add_file_internal(TCCState *S, const char *filename, int flags) · 4 unmodified lines
1095 switch (obj_type) {1017 switch (obj_type) {
1096 1018
1097 case AFF_BINTYPE_REL:1019 case AFF_BINTYPE_REL:
1098 ret = tcc_load_object_file(S, fd, 0);1020 ret = tcc_load_object_file(s1, fd, 0);
1099 break;1021 break;
1100 1022
1101 case AFF_BINTYPE_AR:1023 case AFF_BINTYPE_AR:
1102 ret = tcc_load_archive(S, fd, !(flags & AFF_WHOLE_ARCHIVE));1024 ret = tcc_load_archive(s1, fd, !(flags & AFF_WHOLE_ARCHIVE));
1103 break;1025 break;
1104 1026
1105#ifdef TCC_TARGET_PE1027#ifdef TCC_TARGET_PE
1106 default:1028 default:
1107 ret = pe_load_file(S, fd, filename);1029 ret = pe_load_file(s1, fd, filename);
1108 goto check_success;1030 goto check_success;
1109 1031
1110#elif defined TCC_TARGET_MACHO1032#elif defined TCC_TARGET_MACHO
1111 case AFF_BINTYPE_DYN:1033 case AFF_BINTYPE_DYN:
1112 case_dyn_or_tbd:1034 case_dyn_or_tbd:
1113 if (S->output_type == TCC_OUTPUT_MEMORY) {1035 if (s1->output_type == TCC_OUTPUT_MEMORY) {
1114#ifdef TCC_IS_NATIVE1036#ifdef TCC_IS_NATIVE
1115 void* dl;1037 void* dl;
1116 const char* soname = filename;1038 const char* soname = filename;
@@ -1118,14 +1040,14 @@ ST_FUNC int tcc_add_file_internal(TCCState *S, const char *filename, int flags) · 1 unmodified line
1118 soname = macho_tbd_soname(filename);1040 soname = macho_tbd_soname(filename);
1119 dl = dlopen(soname, RTLD_GLOBAL | RTLD_LAZY);1041 dl = dlopen(soname, RTLD_GLOBAL | RTLD_LAZY);
1120 if (dl)1042 if (dl)
1121 tcc_add_dllref(S, soname)->handle = dl, ret = 0;1043 tcc_add_dllref(s1, soname)->handle = dl, ret = 0;
1122 if (filename != soname)1044 if (filename != soname)
1123 tcc_free(S, (void *)soname);1045 tcc_free((void *)soname);
1124#endif1046#endif
1125 } else if (obj_type == AFF_BINTYPE_DYN) {1047 } else if (obj_type == AFF_BINTYPE_DYN) {
1126 ret = macho_load_dll(S, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);1048 ret = macho_load_dll(s1, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);
1127 } else {1049 } else {
1128 ret = macho_load_tbd(S, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);1050 ret = macho_load_tbd(s1, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);
1129 }1051 }
1130 break;1052 break;
1131 default:1053 default:
@@ -1142,47 +1064,47 @@ ST_FUNC int tcc_add_file_internal(TCCState *S, const char *filename, int flags) · 10 unmodified lines
1142 1064
1143#else /* unix */1065#else /* unix */
1144 case AFF_BINTYPE_DYN:1066 case AFF_BINTYPE_DYN:
1145 if (S->output_type == TCC_OUTPUT_MEMORY) {1067 if (s1->output_type == TCC_OUTPUT_MEMORY) {
1146#ifdef TCC_IS_NATIVE1068#ifdef TCC_IS_NATIVE
1147 void* dl = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY);1069 void* dl = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY);
1148 if (dl)1070 if (dl)
1149 tcc_add_dllref(S, filename)->handle = dl, ret = 0;1071 tcc_add_dllref(s1, filename)->handle = dl, ret = 0;
1150#endif1072#endif
1151 } else1073 } else
1152 ret = tcc_load_dll(S, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);1074 ret = tcc_load_dll(s1, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);
1153 break;1075 break;
1154 1076
1155 default:1077 default:
1156 /* as GNU ld, consider it is an ld script if not recognized */1078 /* as GNU ld, consider it is an ld script if not recognized */
1157 ret = tcc_load_ldscript(S, fd);1079 ret = tcc_load_ldscript(s1, fd);
1158 goto check_success;1080 goto check_success;
1159 1081
1160#endif /* pe / macos / unix */1082#endif /* pe / macos / unix */
1161 1083
1162check_success:1084check_success:
1163 if (ret < 0)1085 if (ret < 0)
1164 tcc_error_noabort(S, "%s: unrecognized file type", filename);1086 tcc_error_noabort("%s: unrecognized file type", filename);
1165 break;1087 break;
1166 1088
1167#ifdef TCC_TARGET_COFF1089#ifdef TCC_TARGET_COFF
1168 case AFF_BINTYPE_C67:1090 case AFF_BINTYPE_C67:
1169 ret = tcc_load_coff(S, fd);1091 ret = tcc_load_coff(s1, fd);
1170 break;1092 break;
1171#endif1093#endif
1172 }1094 }
1173 close(fd);1095 close(fd);
1174 } else {1096 } else {
1175 /* update target deps */1097 /* update target deps */
1176 dynarray_add(S, &S->target_deps, &S->nb_target_deps, tcc_strdup(S, filename));1098 dynarray_add(&s1->target_deps, &s1->nb_target_deps, tcc_strdup(filename));
1177 ret = tcc_compile(S, flags, filename, fd);1099 ret = tcc_compile(s1, flags, filename, fd);
1178 }1100 }
1179 S->current_filename = NULL;1101 s1->current_filename = NULL;
1180 return ret;1102 return ret;
1181}1103}
1182 1104
1183LIBTCCAPI int tcc_add_file(TCCState *S, const char *filename)1105LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename)
1184{1106{
1185 int filetype = S->filetype;1107 int filetype = s->filetype;
1186 if (0 == (filetype & AFF_TYPE_MASK)) {1108 if (0 == (filetype & AFF_TYPE_MASK)) {
1187 /* use a file extension to detect a filetype */1109 /* use a file extension to detect a filetype */
1188 const char *ext = tcc_fileextension(filename);1110 const char *ext = tcc_fileextension(filename);
@@ -1202,16 +1124,16 @@ LIBTCCAPI int tcc_add_file(TCCState *S, const char *filename) · 13 unmodified lines
1202 filetype = AFF_TYPE_C;1124 filetype = AFF_TYPE_C;
1203 }1125 }
1204 }1126 }
1205 return tcc_add_file_internal(S, filename, filetype | AFF_PRINT_ERROR);1127 return tcc_add_file_internal(s, filename, filetype | AFF_PRINT_ERROR);
1206}1128}
1207 1129
1208LIBTCCAPI int tcc_add_library_path(TCCState *S, const char *pathname)1130LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname)
1209{1131{
1210 tcc_split_path(S, &S->library_paths, &S->nb_library_paths, pathname);1132 tcc_split_path(s, &s->library_paths, &s->nb_library_paths, pathname);
1211 return 0;1133 return 0;
1212}1134}
1213 1135
1214static int tcc_add_library_internal(TCCState *S, const char *fmt,1136static int tcc_add_library_internal(TCCState *s, const char *fmt,
1215 const char *filename, int flags, char **paths, int nb_paths)1137 const char *filename, int flags, char **paths, int nb_paths)
1216{1138{
1217 char buf[1024];1139 char buf[1024];
@@ -1219,7 +1141,7 @@ static int tcc_add_library_internal(TCCState *S, const char *fmt, · 1 unmodified line
1219 1141
1220 for(i = 0; i < nb_paths; i++) {1142 for(i = 0; i < nb_paths; i++) {
1221 snprintf(buf, sizeof(buf), fmt, paths[i], filename);1143 snprintf(buf, sizeof(buf), fmt, paths[i], filename);
1222 if (tcc_add_file_internal(S, buf, flags | AFF_TYPE_BIN) == 0)1144 if (tcc_add_file_internal(s, buf, flags | AFF_TYPE_BIN) == 0)
1223 return 0;1145 return 0;
1224 }1146 }
1225 return -1;1147 return -1;
@@ -1228,87 +1150,87 @@ static int tcc_add_library_internal(TCCState *S, const char *fmt, · 2 unmodified lines
1228#ifndef TCC_TARGET_MACHO1150#ifndef TCC_TARGET_MACHO
1229/* find and load a dll. Return non zero if not found */1151/* find and load a dll. Return non zero if not found */
1230/* XXX: add '-rpath' option support ? */1152/* XXX: add '-rpath' option support ? */
1231ST_FUNC int tcc_add_dll(TCCState *S, const char *filename, int flags)1153ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags)
1232{1154{
1233 return tcc_add_library_internal(S, "%s/%s", filename, flags,1155 return tcc_add_library_internal(s, "%s/%s", filename, flags,
1234 S->library_paths, S->nb_library_paths);1156 s->library_paths, s->nb_library_paths);
1235}1157}
1236#endif1158#endif
1237 1159
1238#if !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO1160#if !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO
1239ST_FUNC int tcc_add_crt(TCCState *S, const char *filename)1161ST_FUNC int tcc_add_crt(TCCState *s1, const char *filename)
1240{1162{
1241 if (-1 == tcc_add_library_internal(S, "%s/%s",1163 if (-1 == tcc_add_library_internal(s1, "%s/%s",
1242 filename, 0, S->crt_paths, S->nb_crt_paths))1164 filename, 0, s1->crt_paths, s1->nb_crt_paths))
1243 tcc_error_noabort(S, "file '%s' not found", filename);1165 tcc_error_noabort("file '%s' not found", filename);
1244 return 0;1166 return 0;
1245}1167}
1246#endif1168#endif
1247 1169
1248/* the library name is the same as the argument of the '-l' option */1170/* the library name is the same as the argument of the '-l' option */
1249LIBTCCAPI int tcc_add_library(TCCState *S, const char *libraryname)1171LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname)
1250{1172{
1251#if defined TCC_TARGET_PE1173#if defined TCC_TARGET_PE
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 };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 };
1253 const char * const *pp = S->static_link ? libs + 4 : libs;1175 const char * const *pp = s->static_link ? libs + 4 : libs;
1254#elif defined TCC_TARGET_MACHO1176#elif defined TCC_TARGET_MACHO
1255 static const char * const libs[] = { "%s/lib%s.dylib", "%s/lib%s.tbd", "%s/lib%s.a", NULL };1177 static const char * const libs[] = { "%s/lib%s.dylib", "%s/lib%s.tbd", "%s/lib%s.a", NULL };
1256 const char * const *pp = S->static_link ? libs + 2 : libs;1178 const char * const *pp = s->static_link ? libs + 2 : libs;
1257#elif defined TARGETOS_OpenBSD1179#elif defined TARGETOS_OpenBSD
1258 static const char * const libs[] = { "%s/lib%s.so.*", "%s/lib%s.a", NULL };1180 static const char * const libs[] = { "%s/lib%s.so.*", "%s/lib%s.a", NULL };
1259 const char * const *pp = S->static_link ? libs + 1 : libs;1181 const char * const *pp = s->static_link ? libs + 1 : libs;
1260#else1182#else
1261 static const char * const libs[] = { "%s/lib%s.so", "%s/lib%s.a", NULL };1183 static const char * const libs[] = { "%s/lib%s.so", "%s/lib%s.a", NULL };
1262 const char * const *pp = S->static_link ? libs + 1 : libs;1184 const char * const *pp = s->static_link ? libs + 1 : libs;
1263#endif1185#endif
1264 int flags = S->filetype & AFF_WHOLE_ARCHIVE;1186 int flags = s->filetype & AFF_WHOLE_ARCHIVE;
1265 while (*pp) {1187 while (*pp) {
1266 if (0 == tcc_add_library_internal(S, *pp,1188 if (0 == tcc_add_library_internal(s, *pp,
1267 libraryname, flags, S->library_paths, S->nb_library_paths))1189 libraryname, flags, s->library_paths, s->nb_library_paths))
1268 return 0;1190 return 0;
1269 ++pp;1191 ++pp;
1270 }1192 }
1271 return -1;1193 return -1;
1272}1194}
1273 1195
1274PUB_FUNC int tcc_add_library_err(TCCState *S, const char *libname)1196PUB_FUNC int tcc_add_library_err(TCCState *s1, const char *libname)
1275{1197{
1276 int ret = tcc_add_library(S, libname);1198 int ret = tcc_add_library(s1, libname);
1277 if (ret < 0)1199 if (ret < 0)
1278 tcc_error_noabort(S, "library '%s' not found", libname);1200 tcc_error_noabort("library '%s' not found", libname);
1279 return ret;1201 return ret;
1280}1202}
1281 1203
1282/* handle #pragma comment(lib,) */1204/* handle #pragma comment(lib,) */
1283ST_FUNC void tcc_add_pragma_libs(TCCState *S)1205ST_FUNC void tcc_add_pragma_libs(TCCState *s1)
1284{1206{
1285 int i;1207 int i;
1286 for (i = 0; i < S->nb_pragma_libs; i++)1208 for (i = 0; i < s1->nb_pragma_libs; i++)
1287 tcc_add_library_err(S, S->pragma_libs[i]);1209 tcc_add_library_err(s1, s1->pragma_libs[i]);
1288}1210}
1289 1211
1290LIBTCCAPI int tcc_add_symbol(TCCState *S, const char *name, const void *val)1212LIBTCCAPI int tcc_add_symbol(TCCState *s1, const char *name, const void *val)
1291{1213{
1292#ifdef TCC_TARGET_PE1214#ifdef TCC_TARGET_PE
1293 /* On x86_64 'val' might not be reachable with a 32bit offset.1215 /* On x86_64 'val' might not be reachable with a 32bit offset.
1294 So it is handled here as if it were in a DLL. */1216 So it is handled here as if it were in a DLL. */
1295 pe_putimport(S, 0, name, (uintptr_t)val);1217 pe_putimport(s1, 0, name, (uintptr_t)val);
1296#else1218#else
1297 char buf[256];1219 char buf[256];
1298 if (S->leading_underscore) {1220 if (s1->leading_underscore) {
1299 buf[0] = '_';1221 buf[0] = '_';
1300 pstrcpy(buf + 1, sizeof(buf) - 1, name);1222 pstrcpy(buf + 1, sizeof(buf) - 1, name);
1301 name = buf;1223 name = buf;
1302 }1224 }
1303 set_global_sym(S, name, NULL, (addr_t)(uintptr_t)val); /* NULL: SHN_ABS */1225 set_global_sym(s1, name, NULL, (addr_t)(uintptr_t)val); /* NULL: SHN_ABS */
1304#endif1226#endif
1305 return 0;1227 return 0;
1306}1228}
1307 1229
1308LIBTCCAPI void tcc_set_lib_path(TCCState *S, const char *path)1230LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path)
1309{1231{
1310 tcc_free(S, S->tcc_lib_path);1232 tcc_free(s->tcc_lib_path);
1311 S->tcc_lib_path = tcc_strdup(S, path);1233 s->tcc_lib_path = tcc_strdup(path);
1312}1234}
1313 1235
1314/********************************************************/1236/********************************************************/
@@ -1388,7 +1310,7 @@ static const char *skip_linker_arg(const char **str) · 73 unmodified lines
1388 return s2;1310 return s2;
1389}1311}
1390 1312
1391static void copy_linker_arg(TCCState* S, char **pp, const char *s, int sep)1313static void copy_linker_arg(char **pp, const char *s, int sep)
1392{1314{
1393 const char *q = s;1315 const char *q = s;
1394 char *p = *pp;1316 char *p = *pp;
@@ -1396,12 +1318,13 @@ static void copy_linker_arg(TCCState* S, char **pp, const char *s, int sep) · 1 unmodified line
1396 if (p && sep)1318 if (p && sep)
1397 p[l = strlen(p)] = sep, ++l;1319 p[l = strlen(p)] = sep, ++l;
1398 skip_linker_arg(&q);1320 skip_linker_arg(&q);
1399 pstrncpy(l + (*pp = tcc_realloc(S, p, q - s + l + 1)), s, q - s);1321 pstrncpy(l + (*pp = tcc_realloc(p, q - s + l + 1)), s, q - s);
1400}1322}
1401 1323
1402/* set linker options */1324/* set linker options */
1403static int tcc_set_linker(TCCState *S, const char *option)1325static int tcc_set_linker(TCCState *s, const char *option)
1404{1326{
1327 TCCState *s1 = s;
1405 while (*option) {1328 while (*option) {
1406 1329
1407 const char *p = NULL;1330 const char *p = NULL;
@@ -1410,18 +1333,18 @@ static int tcc_set_linker(TCCState *S, const char *option) · 2 unmodified lines
1410 int ret;1333 int ret;
1411 1334
1412 if (link_option(option, "Bsymbolic", &p)) {1335 if (link_option(option, "Bsymbolic", &p)) {
1413 S->symbolic = 1;1336 s->symbolic = 1;
1414 } else if (link_option(option, "nostdlib", &p)) {1337 } else if (link_option(option, "nostdlib", &p)) {
1415 S->nostdlib = 1;1338 s->nostdlib = 1;
1416 } else if (link_option(option, "fini=", &p)) {1339 } else if (link_option(option, "fini=", &p)) {
1417 copy_linker_arg(S, &S->fini_symbol, p, 0);1340 copy_linker_arg(&s->fini_symbol, p, 0);
1418 ignoring = 1;1341 ignoring = 1;
1419 } else if (link_option(option, "image-base=", &p)1342 } else if (link_option(option, "image-base=", &p)
1420 || link_option(option, "Ttext=", &p)) {1343 || link_option(option, "Ttext=", &p)) {
1421 S->text_addr = strtoull(p, &end, 16);1344 s->text_addr = strtoull(p, &end, 16);
1422 S->has_text_addr = 1;1345 s->has_text_addr = 1;
1423 } else if (link_option(option, "init=", &p)) {1346 } else if (link_option(option, "init=", &p)) {
1424 copy_linker_arg(S, &S->init_symbol, p, 0);1347 copy_linker_arg(&s->init_symbol, p, 0);
1425 ignoring = 1;1348 ignoring = 1;
1426 } else if (link_option(option, "oformat=", &p)) {1349 } else if (link_option(option, "oformat=", &p)) {
1427#if defined(TCC_TARGET_PE)1350#if defined(TCC_TARGET_PE)
@@ -1431,12 +1354,12 @@ static int tcc_set_linker(TCCState *S, const char *option) · 3 unmodified lines
1431#else1354#else
1432 if (strstart("elf32-", &p)) {1355 if (strstart("elf32-", &p)) {
1433#endif1356#endif
1434 S->output_format = TCC_OUTPUT_FORMAT_ELF;1357 s->output_format = TCC_OUTPUT_FORMAT_ELF;
1435 } else if (!strcmp(p, "binary")) {1358 } else if (!strcmp(p, "binary")) {
1436 S->output_format = TCC_OUTPUT_FORMAT_BINARY;1359 s->output_format = TCC_OUTPUT_FORMAT_BINARY;
1437#ifdef TCC_TARGET_COFF1360#ifdef TCC_TARGET_COFF
1438 } else if (!strcmp(p, "coff")) {1361 } else if (!strcmp(p, "coff")) {
1439 S->output_format = TCC_OUTPUT_FORMAT_COFF;1362 s->output_format = TCC_OUTPUT_FORMAT_COFF;
1440#endif1363#endif
1441 } else1364 } else
1442 goto err;1365 goto err;
@@ -1446,64 +1369,64 @@ static int tcc_set_linker(TCCState *S, const char *option) · 3 unmodified lines
1446 } else if (link_option(option, "O", &p)) {1369 } else if (link_option(option, "O", &p)) {
1447 ignoring = 1;1370 ignoring = 1;
1448 } else if (link_option(option, "export-all-symbols", &p)) {1371 } else if (link_option(option, "export-all-symbols", &p)) {
1449 S->rdynamic = 1;1372 s->rdynamic = 1;
1450 } else if (link_option(option, "export-dynamic", &p)) {1373 } else if (link_option(option, "export-dynamic", &p)) {
1451 S->rdynamic = 1;1374 s->rdynamic = 1;
1452 } else if (link_option(option, "rpath=", &p)) {1375 } else if (link_option(option, "rpath=", &p)) {
1453 copy_linker_arg(S, &S->rpath, p, ':');1376 copy_linker_arg(&s->rpath, p, ':');
1454 } else if (link_option(option, "enable-new-dtags", &p)) {1377 } else if (link_option(option, "enable-new-dtags", &p)) {
1455 S->enable_new_dtags = 1;1378 s->enable_new_dtags = 1;
1456 } else if (link_option(option, "section-alignment=", &p)) {1379 } else if (link_option(option, "section-alignment=", &p)) {
1457 S->section_align = strtoul(p, &end, 16);1380 s->section_align = strtoul(p, &end, 16);
1458 } else if (link_option(option, "soname=", &p)) {1381 } else if (link_option(option, "soname=", &p)) {
1459 copy_linker_arg(S, &S->soname, p, 0);1382 copy_linker_arg(&s->soname, p, 0);
1460#ifdef TCC_TARGET_PE1383#ifdef TCC_TARGET_PE
1461 } else if (link_option(option, "large-address-aware", &p)) {1384 } else if (link_option(option, "large-address-aware", &p)) {
1462 S->pe_characteristics |= 0x20;1385 s->pe_characteristics |= 0x20;
1463 } else if (link_option(option, "file-alignment=", &p)) {1386 } else if (link_option(option, "file-alignment=", &p)) {
1464 S->pe_file_align = strtoul(p, &end, 16);1387 s->pe_file_align = strtoul(p, &end, 16);
1465 } else if (link_option(option, "stack=", &p)) {1388 } else if (link_option(option, "stack=", &p)) {
1466 S->pe_stack_size = strtoul(p, &end, 10);1389 s->pe_stack_size = strtoul(p, &end, 10);
1467 } else if (link_option(option, "subsystem=", &p)) {1390 } else if (link_option(option, "subsystem=", &p)) {
1468#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)1391#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1469 if (!strcmp(p, "native")) {1392 if (!strcmp(p, "native")) {
1470 S->pe_subsystem = 1;1393 s->pe_subsystem = 1;
1471 } else if (!strcmp(p, "console")) {1394 } else if (!strcmp(p, "console")) {
1472 S->pe_subsystem = 3;1395 s->pe_subsystem = 3;
1473 } else if (!strcmp(p, "gui") || !strcmp(p, "windows")) {1396 } else if (!strcmp(p, "gui") || !strcmp(p, "windows")) {
1474 S->pe_subsystem = 2;1397 s->pe_subsystem = 2;
1475 } else if (!strcmp(p, "posix")) {1398 } else if (!strcmp(p, "posix")) {
1476 S->pe_subsystem = 7;1399 s->pe_subsystem = 7;
1477 } else if (!strcmp(p, "efiapp")) {1400 } else if (!strcmp(p, "efiapp")) {
1478 S->pe_subsystem = 10;1401 s->pe_subsystem = 10;
1479 } else if (!strcmp(p, "efiboot")) {1402 } else if (!strcmp(p, "efiboot")) {
1480 S->pe_subsystem = 11;1403 s->pe_subsystem = 11;
1481 } else if (!strcmp(p, "efiruntime")) {1404 } else if (!strcmp(p, "efiruntime")) {
1482 S->pe_subsystem = 12;1405 s->pe_subsystem = 12;
1483 } else if (!strcmp(p, "efirom")) {1406 } else if (!strcmp(p, "efirom")) {
1484 S->pe_subsystem = 13;1407 s->pe_subsystem = 13;
1485#elif defined(TCC_TARGET_ARM)1408#elif defined(TCC_TARGET_ARM)
1486 if (!strcmp(p, "wince")) {1409 if (!strcmp(p, "wince")) {
1487 S->pe_subsystem = 9;1410 s->pe_subsystem = 9;
1488#endif1411#endif
1489 } else1412 } else
1490 goto err;1413 goto err;
1491#endif1414#endif
1492 } else if (ret = link_option(option, "?whole-archive", &p), ret) {1415 } else if (ret = link_option(option, "?whole-archive", &p), ret) {
1493 if (ret > 0)1416 if (ret > 0)
1494 S->filetype |= AFF_WHOLE_ARCHIVE;1417 s->filetype |= AFF_WHOLE_ARCHIVE;
1495 else1418 else
1496 S->filetype &= ~AFF_WHOLE_ARCHIVE;1419 s->filetype &= ~AFF_WHOLE_ARCHIVE;
1497 } else if (link_option(option, "z=", &p)) {1420 } else if (link_option(option, "z=", &p)) {
1498 ignoring = 1;1421 ignoring = 1;
1499 } else if (p) {1422 } else if (p) {
1500 return 0;1423 return 0;
1501 } else {1424 } else {
1502 err:1425 err:
1503 tcc_error(S, "unsupported linker option '%s'", option);1426 tcc_error("unsupported linker option '%s'", option);
1504 }1427 }
1505 if (ignoring)1428 if (ignoring)
1506 tcc_warning_c(warn_unsupported)(S, "unsupported linker option '%s'", option);1429 tcc_warning_c(warn_unsupported)("unsupported linker option '%s'", option);
1507 option = skip_linker_arg(&p);1430 option = skip_linker_arg(&p);
1508 }1431 }
1509 return 1;1432 return 1;
@@ -1681,7 +1604,7 @@ static const FlagDef options_m[] = { · 171 unmodified lines
1681 { 0, 0, NULL }1604 { 0, 0, NULL }
1682};1605};
1683 1606
1684static int set_flag(TCCState *S, const FlagDef *flags, const char *name)1607static int set_flag(TCCState *s, const FlagDef *flags, const char *name)
1685{1608{
1686 int value, mask, ret;1609 int value, mask, ret;
1687 const FlagDef *p;1610 const FlagDef *p;
@@ -1703,7 +1626,7 @@ static int set_flag(TCCState *S, const FlagDef *flags, const char *name) · 15 unmodified lines
1703 continue;1626 continue;
1704 }1627 }
1705 1628
1706 f = (unsigned char *)S + p->offset;1629 f = (unsigned char *)s + p->offset;
1707 *f = (*f & mask) | (value ^ !!(p->flags & FD_INVERT));1630 *f = (*f & mask) | (value ^ !!(p->flags & FD_INVERT));
1708 1631
1709 if (ret) {1632 if (ret) {
@@ -1715,15 +1638,15 @@ static int set_flag(TCCState *S, const FlagDef *flags, const char *name) · 5 unmodified lines
1715 return ret;1638 return ret;
1716}1639}
1717 1640
1718static void args_parser_add_file(TCCState *S, const char* filename, int filetype)1641static void args_parser_add_file(TCCState *s, const char* filename, int filetype)
1719{1642{
1720 struct filespec *f = tcc_malloc(S, sizeof *f + strlen(filename));1643 struct filespec *f = tcc_malloc(sizeof *f + strlen(filename));
1721 f->type = filetype;1644 f->type = filetype;
1722 strcpy(f->name, filename);1645 strcpy(f->name, filename);
1723 dynarray_add(S, &S->files, &S->nb_files, f);1646 dynarray_add(&s->files, &s->nb_files, f);
1724}1647}
1725 1648
1726static int args_parser_make_argv(TCCState* S, const char *r, int *argc, char ***argv)1649static int args_parser_make_argv(const char *r, int *argc, char ***argv)
1727{1650{
1728 int ret = 0, q, c;1651 int ret = 0, q, c;
1729 CString str;1652 CString str;
@@ -1733,7 +1656,7 @@ static int args_parser_make_argv(TCCState* S, const char *r, int *argc, char *** · 3 unmodified lines
1733 if (c == 0)1656 if (c == 0)
1734 break;1657 break;
1735 q = 0;1658 q = 0;
1736 cstr_new(S, &str);1659 cstr_new(&str);
1737 while (c = (unsigned char)*r, c) {1660 while (c = (unsigned char)*r, c) {
1738 ++r;1661 ++r;
1739 if (c == '\\' && (*r == '"' || *r == '\\')) {1662 if (c == '\\' && (*r == '"' || *r == '\\')) {
@@ -1744,21 +1667,22 @@ static int args_parser_make_argv(TCCState* S, const char *r, int *argc, char *** · 4 unmodified lines
1744 } else if (q == 0 && c <= ' ') {1667 } else if (q == 0 && c <= ' ') {
1745 break;1668 break;
1746 }1669 }
1747 cstr_ccat(S, &str, c);1670 cstr_ccat(&str, c);
1748 }1671 }
1749 cstr_ccat(S, &str, 0);1672 cstr_ccat(&str, 0);
1750 //printf("<%s>\n", str.data), fflush(stdout);1673 //printf("<%s>\n", str.data), fflush(stdout);
1751 dynarray_add(S, argv, argc, tcc_strdup(S, str.data));1674 dynarray_add(argv, argc, tcc_strdup(str.data));
1752 cstr_free(S, &str);1675 cstr_free(&str);
1753 ++ret;1676 ++ret;
1754 }1677 }
1755 return ret;1678 return ret;
1756}1679}
1757 1680
1758/* read list file */1681/* read list file */
1759static void args_parser_listfile(TCCState *S,1682static void args_parser_listfile(TCCState *s,
1760 const char *filename, int optind, int *pargc, char ***pargv)1683 const char *filename, int optind, int *pargc, char ***pargv)
1761{1684{
1685 TCCState *s1 = s;
1762 int fd, i;1686 int fd, i;
1763 char *p;1687 char *p;
1764 int argc = 0;1688 int argc = 0;
@@ -1766,22 +1690,23 @@ static void args_parser_listfile(TCCState *S, · 1 unmodified line
1766 1690
1767 fd = open(filename, O_RDONLY | O_BINARY);1691 fd = open(filename, O_RDONLY | O_BINARY);
1768 if (fd < 0)1692 if (fd < 0)
1769 tcc_error(S, "listfile '%s' not found", filename);1693 tcc_error("listfile '%s' not found", filename);
1770 1694
1771 p = tcc_load_text(S, fd);1695 p = tcc_load_text(fd);
1772 for (i = 0; i < *pargc; ++i)1696 for (i = 0; i < *pargc; ++i)
1773 if (i == optind)1697 if (i == optind)
1774 args_parser_make_argv(S, p, &argc, &argv);1698 args_parser_make_argv(p, &argc, &argv);
1775 else1699 else
1776 dynarray_add(S, &argv, &argc, tcc_strdup(S, (*pargv)[i]));1700 dynarray_add(&argv, &argc, tcc_strdup((*pargv)[i]));
1777 1701
1778 tcc_free(S, p);1702 tcc_free(p);
1779 dynarray_reset(S, &S->argv, &S->argc);1703 dynarray_reset(&s->argv, &s->argc);
1780 *pargc = S->argc = argc, *pargv = S->argv = argv;1704 *pargc = s->argc = argc, *pargv = s->argv = argv;
1781}1705}
1782 1706
1783PUB_FUNC int tcc_parse_args(TCCState *S, int *pargc, char ***pargv, int optind)1707PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind)
1784{1708{
1709 TCCState *s1 = s;
1785 const TCCOption *popt;1710 const TCCOption *popt;
1786 const char *optarg, *r;1711 const char *optarg, *r;
1787 const char *run = NULL;1712 const char *run = NULL;
@@ -1791,26 +1716,26 @@ PUB_FUNC int tcc_parse_args(TCCState *S, int *pargc, char ***pargv, int optind) · 3 unmodified lines
1791 char **argv = *pargv;1716 char **argv = *pargv;
1792 int argc = *pargc;1717 int argc = *pargc;
1793 1718
1794 cstr_new(S, &linker_arg);1719 cstr_new(&linker_arg);
1795 1720
1796 while (optind < argc) {1721 while (optind < argc) {
1797 r = argv[optind];1722 r = argv[optind];
1798 if (r[0] == '@' && r[1] != '\0') {1723 if (r[0] == '@' && r[1] != '\0') {
1799 args_parser_listfile(S, r + 1, optind, &argc, &argv);1724 args_parser_listfile(s, r + 1, optind, &argc, &argv);
1800 continue;1725 continue;
1801 }1726 }
1802 optind++;1727 optind++;
1803 if (tool) {1728 if (tool) {
1804 if (r[0] == '-' && r[1] == 'v' && r[2] == 0)1729 if (r[0] == '-' && r[1] == 'v' && r[2] == 0)
1805 ++S->verbose;1730 ++s->verbose;
1806 continue;1731 continue;
1807 }1732 }
1808reparse:1733reparse:
1809 if (r[0] != '-' || r[1] == '\0') {1734 if (r[0] != '-' || r[1] == '\0') {
1810 if (r[0] != '@') /* allow "tcc file(s) -run @ args ..." */1735 if (r[0] != '@') /* allow "tcc file(s) -run @ args ..." */
1811 args_parser_add_file(S, r, S->filetype);1736 args_parser_add_file(s, r, s->filetype);
1812 if (run) {1737 if (run) {
1813 tcc_set_options(S, run);1738 tcc_set_options(s, run);
1814 arg_start = optind - 1;1739 arg_start = optind - 1;
1815 break;1740 break;
1816 }1741 }
@@ -1822,7 +1747,7 @@ reparse: · 5 unmodified lines
1822 const char *p1 = popt->name;1747 const char *p1 = popt->name;
1823 const char *r1 = r + 1;1748 const char *r1 = r + 1;
1824 if (p1 == NULL)1749 if (p1 == NULL)
1825 tcc_error(S, "invalid option -- '%s'", r);1750 tcc_error("invalid option -- '%s'", r);
1826 if (!strstart(p1, &r1))1751 if (!strstart(p1, &r1))
1827 continue;1752 continue;
1828 optarg = r1;1753 optarg = r1;
@@ -1830,7 +1755,7 @@ reparse: · 1 unmodified line
1830 if (*r1 == '\0' && !(popt->flags & TCC_OPTION_NOSEP)) {1755 if (*r1 == '\0' && !(popt->flags & TCC_OPTION_NOSEP)) {
1831 if (optind >= argc)1756 if (optind >= argc)
1832 arg_err:1757 arg_err:
1833 tcc_error(S, "argument to '%s' is missing", r);1758 tcc_error("argument to '%s' is missing", r);
1834 optarg = argv[optind++];1759 optarg = argv[optind++];
1835 }1760 }
1836 } else if (*r1 != '\0')1761 } else if (*r1 != '\0')
@@ -1846,132 +1771,132 @@ reparse: · 9 unmodified lines
1846 x = OPT_HELP2;1771 x = OPT_HELP2;
1847 goto extra_action;1772 goto extra_action;
1848 case TCC_OPTION_I:1773 case TCC_OPTION_I:
1849 tcc_add_include_path(S, optarg);1774 tcc_add_include_path(s, optarg);
1850 break;1775 break;
1851 case TCC_OPTION_D:1776 case TCC_OPTION_D:
1852 tcc_define_symbol(S, optarg, NULL);1777 tcc_define_symbol(s, optarg, NULL);
1853 break;1778 break;
1854 case TCC_OPTION_U:1779 case TCC_OPTION_U:
1855 tcc_undefine_symbol(S, optarg);1780 tcc_undefine_symbol(s, optarg);
1856 break;1781 break;
1857 case TCC_OPTION_L:1782 case TCC_OPTION_L:
1858 tcc_add_library_path(S, optarg);1783 tcc_add_library_path(s, optarg);
1859 break;1784 break;
1860 case TCC_OPTION_B:1785 case TCC_OPTION_B:
1861 /* set tcc utilities path (mainly for tcc development) */1786 /* set tcc utilities path (mainly for tcc development) */
1862 tcc_set_lib_path(S, optarg);1787 tcc_set_lib_path(s, optarg);
1863 break;1788 break;
1864 case TCC_OPTION_l:1789 case TCC_OPTION_l:
1865 args_parser_add_file(S, optarg, AFF_TYPE_LIB | (S->filetype & ~AFF_TYPE_MASK));1790 args_parser_add_file(s, optarg, AFF_TYPE_LIB | (s->filetype & ~AFF_TYPE_MASK));
1866 S->nb_libraries++;1791 s->nb_libraries++;
1867 break;1792 break;
1868 case TCC_OPTION_pthread:1793 case TCC_OPTION_pthread:
1869 S->option_pthread = 1;1794 s->option_pthread = 1;
1870 break;1795 break;
1871 case TCC_OPTION_bench:1796 case TCC_OPTION_bench:
1872 S->do_bench = 1;1797 s->do_bench = 1;
1873 break;1798 break;
1874#ifdef CONFIG_TCC_BACKTRACE1799#ifdef CONFIG_TCC_BACKTRACE
1875 case TCC_OPTION_bt:1800 case TCC_OPTION_bt:
1876 S->rt_num_callers = atoi(optarg);1801 s->rt_num_callers = atoi(optarg);
1877 S->do_backtrace = 1;1802 s->do_backtrace = 1;
1878 S->do_debug = 1;1803 s->do_debug = 1;
1879 break;1804 break;
1880#endif1805#endif
1881#ifdef CONFIG_TCC_BCHECK1806#ifdef CONFIG_TCC_BCHECK
1882 case TCC_OPTION_b:1807 case TCC_OPTION_b:
1883 S->do_bounds_check = 1;1808 s->do_bounds_check = 1;
1884 S->do_backtrace = 1;1809 s->do_backtrace = 1;
1885 S->do_debug = 1;1810 s->do_debug = 1;
1886 break;1811 break;
1887#endif1812#endif
1888 case TCC_OPTION_g:1813 case TCC_OPTION_g:
1889 S->do_debug = 1;1814 s->do_debug = 1;
1890 break;1815 break;
1891 case TCC_OPTION_c:1816 case TCC_OPTION_c:
1892 x = TCC_OUTPUT_OBJ;1817 x = TCC_OUTPUT_OBJ;
1893 set_output_type:1818 set_output_type:
1894 if (S->output_type)1819 if (s->output_type)
1895 tcc_warning(S, "-%s: overriding compiler action already specified", popt->name);1820 tcc_warning("-%s: overriding compiler action already specified", popt->name);
1896 S->output_type = x;1821 s->output_type = x;
1897 break;1822 break;
1898 case TCC_OPTION_d:1823 case TCC_OPTION_d:
1899 if (*optarg == 'D')1824 if (*optarg == 'D')
1900 S->dflag = TCC_OPTION_d_D;1825 s->dflag = 3;
1901 else if (*optarg == 'M')1826 else if (*optarg == 'M')
1902 S->dflag = TCC_OPTION_d_M;1827 s->dflag = 7;
1903 else if (*optarg == 't')1828 else if (*optarg == 't')
1904 S->dflag = TCC_OPTION_d_t;1829 s->dflag = 16;
1905 else if (isnum(*optarg))1830 else if (isnum(*optarg))
1906 S->g_debug |= atoi(optarg);1831 s->g_debug |= atoi(optarg);
1907 else1832 else
1908 goto unsupported_option;1833 goto unsupported_option;
1909 break;1834 break;
1910 case TCC_OPTION_static:1835 case TCC_OPTION_static:
1911 S->static_link = 1;1836 s->static_link = 1;
1912 break;1837 break;
1913 case TCC_OPTION_std:1838 case TCC_OPTION_std:
1914 if (strcmp(optarg, "=c11") == 0)1839 if (strcmp(optarg, "=c11") == 0)
1915 S->cversion = 201112;1840 s->cversion = 201112;
1916 break;1841 break;
1917 case TCC_OPTION_shared:1842 case TCC_OPTION_shared:
1918 x = TCC_OUTPUT_DLL;1843 x = TCC_OUTPUT_DLL;
1919 goto set_output_type;1844 goto set_output_type;
1920 case TCC_OPTION_soname:1845 case TCC_OPTION_soname:
1921 S->soname = tcc_strdup(S, optarg);1846 s->soname = tcc_strdup(optarg);
1922 break;1847 break;
1923 case TCC_OPTION_o:1848 case TCC_OPTION_o:
1924 if (S->outfile) {1849 if (s->outfile) {
1925 tcc_warning(S, "multiple -o option");1850 tcc_warning("multiple -o option");
1926 tcc_free(S, S->outfile);1851 tcc_free(s->outfile);
1927 }1852 }
1928 S->outfile = tcc_strdup(S, optarg);1853 s->outfile = tcc_strdup(optarg);
1929 break;1854 break;
1930 case TCC_OPTION_r:1855 case TCC_OPTION_r:
1931 /* generate a .o merging several output files */1856 /* generate a .o merging several output files */
1932 S->option_r = 1;1857 s->option_r = 1;
1933 x = TCC_OUTPUT_OBJ;1858 x = TCC_OUTPUT_OBJ;
1934 goto set_output_type;1859 goto set_output_type;
1935 case TCC_OPTION_isystem:1860 case TCC_OPTION_isystem:
1936 tcc_add_sysinclude_path(S, optarg);1861 tcc_add_sysinclude_path(s, optarg);
1937 break;1862 break;
1938 case TCC_OPTION_include:1863 case TCC_OPTION_include:
1939 cstr_printf(S, &S->cmdline_incl, "#include \"%s\"\n", optarg);1864 cstr_printf(&s->cmdline_incl, "#include \"%s\"\n", optarg);
1940 break;1865 break;
1941 case TCC_OPTION_nostdinc:1866 case TCC_OPTION_nostdinc:
1942 S->nostdinc = 1;1867 s->nostdinc = 1;
1943 break;1868 break;
1944 case TCC_OPTION_nostdlib:1869 case TCC_OPTION_nostdlib:
1945 S->nostdlib = 1;1870 s->nostdlib = 1;
1946 break;1871 break;
1947 case TCC_OPTION_run:1872 case TCC_OPTION_run:
1948#ifndef TCC_IS_NATIVE1873#ifndef TCC_IS_NATIVE
1949 tcc_error(S, "-run is not available in a cross compiler");1874 tcc_error("-run is not available in a cross compiler");
1950#endif1875#endif
1951 run = optarg;1876 run = optarg;
1952 x = TCC_OUTPUT_MEMORY;1877 x = TCC_OUTPUT_MEMORY;
1953 goto set_output_type;1878 goto set_output_type;
1954 case TCC_OPTION_v:1879 case TCC_OPTION_v:
1955 do ++S->verbose; while (*optarg++ == 'v');1880 do ++s->verbose; while (*optarg++ == 'v');
1956 ++noaction;1881 ++noaction;
1957 break;1882 break;
1958 case TCC_OPTION_f:1883 case TCC_OPTION_f:
1959 if (set_flag(S, options_f, optarg) < 0)1884 if (set_flag(s, options_f, optarg) < 0)
1960 goto unsupported_option;1885 goto unsupported_option;
1961 break;1886 break;
1962#ifdef TCC_TARGET_ARM1887#ifdef TCC_TARGET_ARM
1963 case TCC_OPTION_mfloat_abi:1888 case TCC_OPTION_mfloat_abi:
1964 /* tcc doesn't support soft float yet */1889 /* tcc doesn't support soft float yet */
1965 if (!strcmp(optarg, "softfp")) {1890 if (!strcmp(optarg, "softfp")) {
1966 S->float_abi = ARM_SOFTFP_FLOAT;1891 s->float_abi = ARM_SOFTFP_FLOAT;
1967 } else if (!strcmp(optarg, "hard"))1892 } else if (!strcmp(optarg, "hard"))
1968 S->float_abi = ARM_HARD_FLOAT;1893 s->float_abi = ARM_HARD_FLOAT;
1969 else1894 else
1970 tcc_error(S, "unsupported float abi '%s'", optarg);1895 tcc_error("unsupported float abi '%s'", optarg);
1971 break;1896 break;
1972#endif1897#endif
1973 case TCC_OPTION_m:1898 case TCC_OPTION_m:
1974 if (set_flag(S, options_m, optarg) < 0) {1899 if (set_flag(s, options_m, optarg) < 0) {
1975 if (x = atoi(optarg), x != 32 && x != 64)1900 if (x = atoi(optarg), x != 32 && x != 64)
1976 goto unsupported_option;1901 goto unsupported_option;
1977 if (PTR_SIZE != x/8)1902 if (PTR_SIZE != x/8)
@@ -1980,22 +1905,22 @@ reparse: · 2 unmodified lines
1980 }1905 }
1981 break;1906 break;
1982 case TCC_OPTION_W:1907 case TCC_OPTION_W:
1983 S->warn_none = 0;1908 s->warn_none = 0;
1984 if (optarg[0] && set_flag(S, options_W, optarg) < 0)1909 if (optarg[0] && set_flag(s, options_W, optarg) < 0)
1985 goto unsupported_option;1910 goto unsupported_option;
1986 break;1911 break;
1987 case TCC_OPTION_w:1912 case TCC_OPTION_w:
1988 S->warn_none = 1;1913 s->warn_none = 1;
1989 break;1914 break;
1990 case TCC_OPTION_rdynamic:1915 case TCC_OPTION_rdynamic:
1991 S->rdynamic = 1;1916 s->rdynamic = 1;
1992 break;1917 break;
1993 case TCC_OPTION_Wl:1918 case TCC_OPTION_Wl:
1994 if (linker_arg.size)1919 if (linker_arg.size)
1995 --linker_arg.size, cstr_ccat(S, &linker_arg, ',');1920 --linker_arg.size, cstr_ccat(&linker_arg, ',');
1996 cstr_cat(S, &linker_arg, optarg, 0);1921 cstr_cat(&linker_arg, optarg, 0);
1997 if (tcc_set_linker(S, linker_arg.data))1922 if (tcc_set_linker(s, linker_arg.data))
1998 cstr_free(S, &linker_arg);1923 cstr_free(&linker_arg);
1999 break;1924 break;
2000 case TCC_OPTION_Wp:1925 case TCC_OPTION_Wp:
2001 r = optarg;1926 r = optarg;
@@ -2004,25 +1929,25 @@ reparse: · 2 unmodified lines
2004 x = TCC_OUTPUT_PREPROCESS;1929 x = TCC_OUTPUT_PREPROCESS;
2005 goto set_output_type;1930 goto set_output_type;
2006 case TCC_OPTION_P:1931 case TCC_OPTION_P:
2007 S->Pflag = atoi(optarg) + 1;1932 s->Pflag = atoi(optarg) + 1;
2008 break;1933 break;
2009 case TCC_OPTION_M:1934 case TCC_OPTION_M:
2010 S->include_sys_deps = 1;1935 s->include_sys_deps = 1;
2011 // fall through1936 // fall through
2012 case TCC_OPTION_MM:1937 case TCC_OPTION_MM:
2013 S->just_deps = 1;1938 s->just_deps = 1;
2014 if(!S->deps_outfile)1939 if(!s->deps_outfile)
2015 S->deps_outfile = tcc_strdup(S, "-");1940 s->deps_outfile = tcc_strdup("-");
2016 // fall through1941 // fall through
2017 case TCC_OPTION_MMD:1942 case TCC_OPTION_MMD:
2018 S->gen_deps = 1;1943 s->gen_deps = 1;
2019 break;1944 break;
2020 case TCC_OPTION_MD:1945 case TCC_OPTION_MD:
2021 S->gen_deps = 1;1946 s->gen_deps = 1;
2022 S->include_sys_deps = 1;1947 s->include_sys_deps = 1;
2023 break;1948 break;
2024 case TCC_OPTION_MF:1949 case TCC_OPTION_MF:
2025 S->deps_outfile = tcc_strdup(S, optarg);1950 s->deps_outfile = tcc_strdup(optarg);
2026 break;1951 break;
2027 case TCC_OPTION_dumpversion:1952 case TCC_OPTION_dumpversion:
2028 printf ("%s\n", TCC_VERSION);1953 printf ("%s\n", TCC_VERSION);
@@ -2039,11 +1964,11 @@ reparse: · 10 unmodified lines
2039 else if (*optarg == 'n')1964 else if (*optarg == 'n')
2040 x = AFF_TYPE_NONE;1965 x = AFF_TYPE_NONE;
2041 else1966 else
2042 tcc_warning(S, "unsupported language '%s'", optarg);1967 tcc_warning("unsupported language '%s'", optarg);
2043 S->filetype = x | (S->filetype & ~AFF_TYPE_MASK);1968 s->filetype = x | (s->filetype & ~AFF_TYPE_MASK);
2044 break;1969 break;
2045 case TCC_OPTION_O:1970 case TCC_OPTION_O:
2046 S->optimize = atoi(optarg);1971 s->optimize = atoi(optarg);
2047 break;1972 break;
2048 case TCC_OPTION_print_search_dirs:1973 case TCC_OPTION_print_search_dirs:
2049 x = OPT_PRINT_DIRS;1974 x = OPT_PRINT_DIRS;
@@ -2056,12 +1981,12 @@ reparse: · 6 unmodified lines
2056 extra_action:1981 extra_action:
2057 arg_start = optind - 1;1982 arg_start = optind - 1;
2058 if (arg_start != noaction)1983 if (arg_start != noaction)
2059 tcc_error(S, "cannot parse %s here", r);1984 tcc_error("cannot parse %s here", r);
2060 tool = x;1985 tool = x;
2061 break;1986 break;
2062 default:1987 default:
2063unsupported_option:1988unsupported_option:
2064 tcc_warning_c(warn_unsupported)(S, "unsupported option '%s'", r);1989 tcc_warning_c(warn_unsupported)("unsupported option '%s'", r);
2065 break;1990 break;
2066 }1991 }
2067 }1992 }
@@ -2075,23 +2000,23 @@ unsupported_option: · 7 unmodified lines
2075 return tool;2000 return tool;
2076 if (optind != noaction)2001 if (optind != noaction)
2077 return 0;2002 return 0;
2078 if (S->verbose == 2)2003 if (s->verbose == 2)
2079 return OPT_PRINT_DIRS;2004 return OPT_PRINT_DIRS;
2080 if (S->verbose)2005 if (s->verbose)
2081 return OPT_V;2006 return OPT_V;
2082 return OPT_HELP;2007 return OPT_HELP;
2083}2008}
2084 2009
2085LIBTCCAPI void tcc_set_options(TCCState *S, const char *r)2010LIBTCCAPI void tcc_set_options(TCCState *s, const char *r)
2086{2011{
2087 char **argv = NULL;2012 char **argv = NULL;
2088 int argc = 0;2013 int argc = 0;
2089 args_parser_make_argv(S, r, &argc, &argv);2014 args_parser_make_argv(r, &argc, &argv);
2090 tcc_parse_args(S, &argc, &argv, 0);2015 tcc_parse_args(s, &argc, &argv, 0);
2091 dynarray_reset(S, &argv, &argc);2016 dynarray_reset(&argv, &argc);
2092}2017}
2093 2018
2094PUB_FUNC void tcc_print_stats(TCCState *S, unsigned total_time)2019PUB_FUNC void tcc_print_stats(TCCState *s1, unsigned total_time)
2095{2020{
2096 if (total_time < 1)2021 if (total_time < 1)
2097 total_time = 1;2022 total_time = 1;
@@ -2104,14 +2029,12 @@ PUB_FUNC void tcc_print_stats(TCCState *S, unsigned total_time) · 6 unmodified lines
2104 (unsigned)total_lines*1000/total_time,2029 (unsigned)total_lines*1000/total_time,
2105 (double)total_bytes/1000/total_time);2030 (double)total_bytes/1000/total_time);
2106 fprintf(stderr, "* text %d, data.rw %d, data.ro %d, bss %d bytes\n",2031 fprintf(stderr, "* text %d, data.rw %d, data.ro %d, bss %d bytes\n",
2107 S->total_output[0],2032 s1->total_output[0],
2108 S->total_output[1],2033 s1->total_output[1],
2109 S->total_output[2],2034 s1->total_output[2],
2110 S->total_output[3]2035 s1->total_output[3]
2111 );2036 );
2112#ifdef MEM_DEBUG2037#ifdef MEM_DEBUG
2113 fprintf(stderr, "* %d bytes memory used\n", mem_max_size);2038 fprintf(stderr, "* %d bytes memory used\n", mem_max_size);
2114#endif2039#endif
2115}2040}
2116
2117#include "tccqsort.c"
libtcc.h+21−72
@@ -15,95 +15,56 @@ 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
54/* create a new TCC compilation context */18/* create a new TCC compilation context */
55LIBTCCAPI TCCState *tcc_new(void);19LIBTCCAPI TCCState *tcc_new(void);
56 20
57/* free a TCC compilation context */21/* free a TCC compilation context */
58LIBTCCAPI void tcc_delete(TCCState *S);22LIBTCCAPI void tcc_delete(TCCState *s);
59 23
60/* set CONFIG_TCCDIR at runtime */24/* set CONFIG_TCCDIR at runtime */
61LIBTCCAPI void tcc_set_lib_path(TCCState *S, const char *path);25LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path);
62 26
63/* set error/warning display callback */27/* set error/warning display callback */
64LIBTCCAPI void tcc_set_error_func(TCCState *S, void *error_opaque, TCCErrorFunc error_func);28LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque, TCCErrorFunc error_func);
65 29
66/* return error/warning callback */30/* return error/warning callback */
67LIBTCCAPI TCCErrorFunc tcc_get_error_func(TCCState *S);31LIBTCCAPI TCCErrorFunc tcc_get_error_func(TCCState *s);
68 32
69/* return error/warning callback opaque pointer */33/* return error/warning callback opaque pointer */
70LIBTCCAPI void *tcc_get_error_opaque(TCCState *S);34LIBTCCAPI void *tcc_get_error_opaque(TCCState *s);
71 35
72/* set options as from command line (multiple supported) */36/* set options as from command line (multiple supported) */
73LIBTCCAPI void tcc_set_options(TCCState *S, const char *str);37LIBTCCAPI 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);
77 38
78/*****************************/39/*****************************/
79/* preprocessor */40/* preprocessor */
80 41
81/* add include path */42/* add include path */
82LIBTCCAPI int tcc_add_include_path(TCCState *S, const char *pathname);43LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname);
83 44
84/* add in system include path */45/* add in system include path */
85LIBTCCAPI int tcc_add_sysinclude_path(TCCState *S, const char *pathname);46LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname);
86 47
87/* define preprocessor symbol 'sym'. value can be NULL, sym can be "sym=val" */48/* define preprocessor symbol 'sym'. value can be NULL, sym can be "sym=val" */
88LIBTCCAPI void tcc_define_symbol(TCCState *S, const char *sym, const char *value);49LIBTCCAPI void tcc_define_symbol(TCCState *s, const char *sym, const char *value);
89 50
90/* undefine preprocess symbol 'sym' */51/* undefine preprocess symbol 'sym' */
91LIBTCCAPI void tcc_undefine_symbol(TCCState *S, const char *sym);52LIBTCCAPI void tcc_undefine_symbol(TCCState *s, const char *sym);
92 53
93/*****************************/54/*****************************/
94/* compiling */55/* compiling */
95 56
96/* add a file (C file, dll, object, library, ld script). Return -1 if error. */57/* add a file (C file, dll, object, library, ld script). Return -1 if error. */
97LIBTCCAPI int tcc_add_file(TCCState *S, const char *filename);58LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename);
98 59
99/* compile a string containing a C source. Return -1 if error. */60/* compile a string containing a C source. Return -1 if error. */
100LIBTCCAPI int tcc_compile_string(TCCState *S, const char *buf);61LIBTCCAPI int tcc_compile_string(TCCState *s, const char *buf);
101 62
102/*****************************/63/*****************************/
103/* linking commands */64/* linking commands */
104 65
105/* set output type. MUST BE CALLED before any compilation */66/* set output type. MUST BE CALLED before any compilation */
106LIBTCCAPI int tcc_set_output_type(TCCState *S, int output_type);67LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type);
107#define TCC_OUTPUT_MEMORY 1 /* output will be run in memory (default) */68#define TCC_OUTPUT_MEMORY 1 /* output will be run in memory (default) */
108#define TCC_OUTPUT_EXE 2 /* executable file */69#define TCC_OUTPUT_EXE 2 /* executable file */
109#define TCC_OUTPUT_DLL 3 /* dynamic library */70#define TCC_OUTPUT_DLL 3 /* dynamic library */
@@ -111,24 +72,24 @@ LIBTCCAPI int tcc_set_output_type(TCCState *S, int output_type); · 1 unmodified line
111#define TCC_OUTPUT_PREPROCESS 5 /* only preprocess (used internally) */72#define TCC_OUTPUT_PREPROCESS 5 /* only preprocess (used internally) */
112 73
113/* equivalent to -Lpath option */74/* equivalent to -Lpath option */
114LIBTCCAPI int tcc_add_library_path(TCCState *S, const char *pathname);75LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname);
115 76
116/* the library name is the same as the argument of the '-l' option */77/* the library name is the same as the argument of the '-l' option */
117LIBTCCAPI int tcc_add_library(TCCState *S, const char *libraryname);78LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname);
118 79
119/* add a symbol to the compiled program */80/* add a symbol to the compiled program */
120LIBTCCAPI int tcc_add_symbol(TCCState *S, const char *name, const void *val);81LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val);
121 82
122/* output an executable, library or object file. DO NOT call83/* output an executable, library or object file. DO NOT call
123 tcc_relocate() before. */84 tcc_relocate() before. */
124LIBTCCAPI int tcc_output_file(TCCState *S, const char *filename);85LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename);
125 86
126/* link and run main() function and return its value. DO NOT call87/* link and run main() function and return its value. DO NOT call
127 tcc_relocate() before. */88 tcc_relocate() before. */
128LIBTCCAPI int tcc_run(TCCState *S, int argc, char **argv);89LIBTCCAPI int tcc_run(TCCState *s, int argc, char **argv);
129 90
130/* do all relocations (needed before using tcc_get_symbol()) */91/* do all relocations (needed before using tcc_get_symbol()) */
131LIBTCCAPI int tcc_relocate(TCCState *S, void *ptr);92LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr);
132/* possible values for 'ptr':93/* possible values for 'ptr':
133 - TCC_RELOCATE_AUTO : Allocate and manage memory internally94 - TCC_RELOCATE_AUTO : Allocate and manage memory internally
134 - NULL : return required memory size for the step below95 - NULL : return required memory size for the step below
@@ -137,24 +98,12 @@ LIBTCCAPI int tcc_relocate(TCCState *S, void *ptr); · 2 unmodified lines
137#define TCC_RELOCATE_AUTO (void*)198#define TCC_RELOCATE_AUTO (void*)1
138 99
139/* return symbol value or NULL if not found */100/* return symbol value or NULL if not found */
140LIBTCCAPI void *tcc_get_symbol(TCCState *S, const char *name);101LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name);
141 102
142/* return symbol value or NULL if not found */103/* return symbol value or NULL if not found */
143LIBTCCAPI void tcc_list_symbols(TCCState *S, void *ctx,104LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
144 void (*symbol_cb)(void *ctx, const char *name, const void *val));105 void (*symbol_cb)(void *ctx, const char *name, const void *val));
145 106
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
158#ifdef __cplusplus107#ifdef __cplusplus
159}108}
160#endif109#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(TCCState* S, int c);12ST_FUNC void g(int c);
13ST_FUNC void gen_le16(TCCState* S, int c);13ST_FUNC void gen_le16(int c);
14ST_FUNC void gen_le32(TCCState* S, int c);14ST_FUNC void gen_le32(int c);
15 15
16/*************************************************************/16/*************************************************************/
17#else17#else
@@ -20,85 +20,85 @@ ST_FUNC void gen_le32(TCCState* S, 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(TCCState* S, int c)23ST_FUNC void g(int c)
24{24{
25 int ind1;25 int ind1;
26 if (S->tccgen_nocode_wanted)26 if (nocode_wanted)
27 return;27 return;
28 ind1 = S->tccgen_ind + 1;28 ind1 = ind + 1;
29 if (ind1 > cur_text_section->data_allocated)29 if (ind1 > cur_text_section->data_allocated)
30 section_realloc(S, cur_text_section, ind1);30 section_realloc(cur_text_section, ind1);
31 cur_text_section->data[S->tccgen_ind] = c;31 cur_text_section->data[ind] = c;
32 S->tccgen_ind = ind1;32 ind = ind1;
33}33}
34 34
35ST_FUNC void gen_le16 (TCCState* S, int i)35ST_FUNC void gen_le16 (int i)
36{36{
37 g(S, i);37 g(i);
38 g(S, i>>8);38 g(i>>8);
39}39}
40 40
41ST_FUNC void gen_le32 (TCCState* S, int i)41ST_FUNC void gen_le32 (int i)
42{42{
43 int ind1;43 int ind1;
44 if (S->tccgen_nocode_wanted)44 if (nocode_wanted)
45 return;45 return;
46 ind1 = S->tccgen_ind + 4;46 ind1 = ind + 4;
47 if (ind1 > cur_text_section->data_allocated)47 if (ind1 > cur_text_section->data_allocated)
48 section_realloc(S, cur_text_section, ind1);48 section_realloc(cur_text_section, ind1);
49 cur_text_section->data[S->tccgen_ind++] = i & 0xFF;49 cur_text_section->data[ind++] = i & 0xFF;
50 cur_text_section->data[S->tccgen_ind++] = (i >> 8) & 0xFF;50 cur_text_section->data[ind++] = (i >> 8) & 0xFF;
51 cur_text_section->data[S->tccgen_ind++] = (i >> 16) & 0xFF;51 cur_text_section->data[ind++] = (i >> 16) & 0xFF;
52 cur_text_section->data[S->tccgen_ind++] = (i >> 24) & 0xFF;52 cur_text_section->data[ind++] = (i >> 24) & 0xFF;
53}53}
54 54
55ST_FUNC void gen_expr32(TCCState* S, ExprValue *pe)55ST_FUNC void gen_expr32(ExprValue *pe)
56{56{
57 gen_le32(S, pe->v);57 gen_le32(pe->v);
58}58}
59 59
60static void asm_emit_opcode(TCCState* S, uint32_t opcode) {60static void asm_emit_opcode(uint32_t opcode) {
61 gen_le32(S, opcode);61 gen_le32(opcode);
62}62}
63 63
64static void asm_nullary_opcode(TCCState *S, int token)64static void asm_nullary_opcode(TCCState *s1, 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(S, (0x3 << 2) | 3 | (0 << 12));70 asm_emit_opcode((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(S, (0x3 << 2) | 3| (1 << 12));73 asm_emit_opcode((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(S, (0x1C << 2) | 3 | (0 << 12));79 asm_emit_opcode((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(S, (0x1C << 2) | 3 | (0 << 12) | (1 << 20));82 asm_emit_opcode((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(S, (0x1C << 2) | 3 | (0 << 20));88 asm_emit_opcode((0x1C << 2) | 3 | (0 << 20));
89 return;89 return;
90 case TOK_ASM_ebreak:90 case TOK_ASM_ebreak:
91 asm_emit_opcode(S, (0x1C << 2) | 3 | (1 << 20));91 asm_emit_opcode((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(S, (0x1C << 2) | 3 | (0x105 << 20));97 asm_emit_opcode((0x1C << 2) | 3 | (0x105 << 20));
98 return;98 return;
99 99
100 default:100 default:
101 expect(S, "nullary instruction");101 expect("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 *S, Operand *op)124static void parse_operand(TCCState *s1, 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(S, S->tccpp_tok)) != -1) {131 if ((reg = asm_parse_regvar(tok)) != -1) {
132 next(S); // skip register name132 next(); // 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 (S->tccpp_tok == '$') {136 } else if (tok == '$') {
137 /* constant value */137 /* constant value */
138 next(S); // skip '#' or '$'138 next(); // skip '#' or '$'
139 }139 }
140 asm_expr(S, &e);140 asm_expr(s1, &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(S, "operand");147 expect("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 *S, 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 *S, int token)155static void asm_unary_opcode(TCCState *s1, 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(S, &op);159 parse_operand(s1, &op);
160 if (op.type != OP_REG) {160 if (op.type != OP_REG) {
161 expect(S, "register");161 expect("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(S, opcode | (0xC00 << 20));168 asm_emit_opcode(opcode | (0xC00 << 20));
169 return;169 return;
170 case TOK_ASM_rdcycleh:170 case TOK_ASM_rdcycleh:
171 asm_emit_opcode(S, opcode | (0xC80 << 20));171 asm_emit_opcode(opcode | (0xC80 << 20));
172 return;172 return;
173 case TOK_ASM_rdtime:173 case TOK_ASM_rdtime:
174 asm_emit_opcode(S, opcode | (0xC01 << 20) | ENCODE_RD(op.reg));174 asm_emit_opcode(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(S, opcode | (0xC81 << 20) | ENCODE_RD(op.reg));177 asm_emit_opcode(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(S, opcode | (0xC02 << 20) | ENCODE_RD(op.reg));180 asm_emit_opcode(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(S, opcode | (0xC82 << 20) | ENCODE_RD(op.reg));183 asm_emit_opcode(opcode | (0xC82 << 20) | ENCODE_RD(op.reg));
184 return;184 return;
185 default:185 default:
186 expect(S, "unary instruction");186 expect("unary instruction");
187 }187 }
188}188}
189 189
190static void asm_emit_u(TCCState *S, int token, uint32_t opcode, const Operand* rd, const Operand* rs2)190static void asm_emit_u(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, "'%s': Expected destination operand that is a register", get_tok_str(S, token, NULL));193 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(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, "'%s': Expected second source operand that is an immediate value", get_tok_str(S, token, NULL));197 tcc_error("'%s': Expected second source operand that is an immediate value", get_tok_str(token, NULL));
198 return;198 return;
199 } else if (rs2->e.v >= 0x100000) {199 } else if (rs2->e.v >= 0x100000) {
200 tcc_error(S, "'%s': Expected second source operand that is an immediate value between 0 and 0xfffff", get_tok_str(S, token, NULL));200 tcc_error("'%s': Expected second source operand that is an immediate value between 0 and 0xfffff", get_tok_str(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(S, opcode | ENCODE_RD(rd->reg) | (rs2->e.v << 12));207 gen_le32(opcode | ENCODE_RD(rd->reg) | (rs2->e.v << 12));
208}208}
209 209
210static void asm_binary_opcode(TCCState* S, int token)210static void asm_binary_opcode(TCCState* s1, int token)
211{211{
212 Operand ops[2];212 Operand ops[2];
213 parse_operand(S, &ops[0]);213 parse_operand(s1, &ops[0]);
214 if (S->tccpp_tok == ',')214 if (tok == ',')
215 next(S);215 next();
216 else216 else
217 expect(S, "','");217 expect("','");
218 parse_operand(S, &ops[1]);218 parse_operand(s1, &ops[1]);
219 219
220 switch (token) {220 switch (token) {
221 case TOK_ASM_lui:221 case TOK_ASM_lui:
222 asm_emit_u(S, token, (0xD << 2) | 3, &ops[0], &ops[1]);222 asm_emit_u(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(S, token, (0x05 << 2) | 3, &ops[0], &ops[1]);225 asm_emit_u(token, (0x05 << 2) | 3, &ops[0], &ops[1]);
226 return;226 return;
227 default:227 default:
228 expect(S, "binary instruction");228 expect("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(TCCState* S, int token, uint32_t opcode, const Operand* rd, const Operand* rs1, const Operand* rs2)233static void asm_emit_r(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, "'%s': Expected destination operand that is a register", get_tok_str(S, token, NULL));236 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));
237 return;237 return;
238 }238 }
239 if (rs1->type != OP_REG) {239 if (rs1->type != OP_REG) {
240 tcc_error(S, "'%s': Expected first source operand that is a register", get_tok_str(S, token, NULL));240 tcc_error("'%s': Expected first source operand that is a register", get_tok_str(token, NULL));
241 return;241 return;
242 }242 }
243 if (rs2->type != OP_REG) {243 if (rs2->type != OP_REG) {
244 tcc_error(S, "'%s': Expected second source operand that is a register or immediate", get_tok_str(S, token, NULL));244 tcc_error("'%s': Expected second source operand that is a register or immediate", get_tok_str(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(TCCState* S, int token, uint32_t opcode, const Operand* r · 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(S, opcode | ENCODE_RD(rd->reg) | ENCODE_RS1(rs1->reg) | ENCODE_RS2(rs2->reg));254 gen_le32(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(TCCState* S, int token, uint32_t opcode, const Operand* rd, const Operand* rs1, const Operand* rs2)258static void asm_emit_i(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, "'%s': Expected destination operand that is a register", get_tok_str(S, token, NULL));261 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));
262 return;262 return;
263 }263 }
264 if (rs1->type != OP_REG) {264 if (rs1->type != OP_REG) {
265 tcc_error(S, "'%s': Expected first source operand that is a register", get_tok_str(S, token, NULL));265 tcc_error("'%s': Expected first source operand that is a register", get_tok_str(token, NULL));
266 return;266 return;
267 }267 }
268 if (rs2->type != OP_IM12S) {268 if (rs2->type != OP_IM12S) {
269 tcc_error(S, "'%s': Expected second source operand that is an immediate value between 0 and 4095", get_tok_str(S, token, NULL));269 tcc_error("'%s': Expected second source operand that is an immediate value between 0 and 4095", get_tok_str(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(TCCState* S, int token, uint32_t opcode, const Operand* r · 3 unmodified lines
276 11...7 rd276 11...7 rd
277 6...0 opcode */277 6...0 opcode */
278 278
279 gen_le32(S, opcode | ENCODE_RD(rd->reg) | ENCODE_RS1(rs1->reg) | (rs2->e.v << 20));279 gen_le32(opcode | ENCODE_RD(rd->reg) | ENCODE_RS1(rs1->reg) | (rs2->e.v << 20));
280}280}
281 281
282static void asm_shift_opcode(TCCState *S, int token)282static void asm_shift_opcode(TCCState *s1, int token)
283{283{
284 Operand ops[3];284 Operand ops[3];
285 parse_operand(S, &ops[0]);285 parse_operand(s1, &ops[0]);
286 if (S->tccpp_tok == ',')286 if (tok == ',')
287 next(S);287 next();
288 else288 else
289 expect(S, "','");289 expect("','");
290 parse_operand(S, &ops[1]);290 parse_operand(s1, &ops[1]);
291 if (S->tccpp_tok == ',')291 if (tok == ',')
292 next(S);292 next();
293 else293 else
294 expect(S, "','");294 expect("','");
295 parse_operand(S, &ops[2]);295 parse_operand(s1, &ops[2]);
296 296
297 switch (token) {297 switch (token) {
298 case TOK_ASM_sll:298 case TOK_ASM_sll:
299 asm_emit_r(S, token, (0xC << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]);299 asm_emit_r(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(S, token, (4 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]);302 asm_emit_i(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(S, token, (0xC << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]);305 asm_emit_r(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(S, token, (0x4 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);308 asm_emit_i(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(S, token, (0xC << 2) | 3 | (5 << 12) | (32 << 25), &ops[0], &ops[1], &ops[2]);311 asm_emit_r(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(S, token, (0x4 << 2) | 3 | (5 << 12) | (16 << 26), &ops[0], &ops[1], &ops[2]);314 asm_emit_i(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(S, token, (0xE << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]);317 asm_emit_r(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(S, token, (6 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]);320 asm_emit_i(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(S, token, (0xE << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);323 asm_emit_r(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(S, token, (0x6 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);326 asm_emit_i(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(S, token, (0xE << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);329 asm_emit_r(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(S, token, (0x6 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);332 asm_emit_i(token, (0x6 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);
333 return;333 return;
334 default:334 default:
335 expect(S, "shift instruction");335 expect("shift instruction");
336 }336 }
337}337}
338 338
339static void asm_data_processing_opcode(TCCState* S, int token)339static void asm_data_processing_opcode(TCCState* s1, int token)
340{340{
341 Operand ops[3];341 Operand ops[3];
342 parse_operand(S, &ops[0]);342 parse_operand(s1, &ops[0]);
343 if (S->tccpp_tok == ',')343 if (tok == ',')
344 next(S);344 next();
345 else345 else
346 expect(S, "','");346 expect("','");
347 parse_operand(S, &ops[1]);347 parse_operand(s1, &ops[1]);
348 if (S->tccpp_tok == ',')348 if (tok == ',')
349 next(S);349 next();
350 else350 else
351 expect(S, "','");351 expect("','");
352 parse_operand(S, &ops[2]);352 parse_operand(s1, &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(S, token, (0xC << 2) | 3, &ops[0], &ops[1], &ops[2]);358 asm_emit_r(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(S, token, (4 << 2) | 3, &ops[0], &ops[1], &ops[2]);361 asm_emit_i(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(S, token, (0xC << 2) | 3 | (32 << 25), &ops[0], &ops[1], &ops[2]);364 asm_emit_r(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(S, token, (0xE << 2) | 3 | (0 << 12), &ops[0], &ops[1], &ops[2]);367 asm_emit_r(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(S, token, (0x6 << 2) | 3 | (0 << 12), &ops[0], &ops[1], &ops[2]);370 asm_emit_i(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(S, token, (0xE << 2) | 3 | (0 << 12) | (32 << 25), &ops[0], &ops[1], &ops[2]);373 asm_emit_r(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(S, token, (0xC << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]);379 asm_emit_r(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(S, token, (0x4 << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]);382 asm_emit_i(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(S, token, (0xC << 2) | 3 | (6 << 12), &ops[0], &ops[1], &ops[2]);385 asm_emit_r(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(S, token, (0x4 << 2) | 3 | (6 << 12), &ops[0], &ops[1], &ops[2]);388 asm_emit_i(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(S, token, (0xC << 2) | 3 | (7 << 12), &ops[0], &ops[1], &ops[2]);391 asm_emit_r(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(S, token, (0x4 << 2) | 3 | (7 << 12), &ops[0], &ops[1], &ops[2]);394 asm_emit_i(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(S, token, (0xC << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]);400 asm_emit_r(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(S, token, (0x4 << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]);403 asm_emit_i(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(S, token, (0xC << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]);406 asm_emit_r(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(S, token, (0x4 << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]);409 asm_emit_i(token, (0x4 << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]);
410 return;410 return;
411 default:411 default:
412 expect(S, "known data processing instruction");412 expect("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(TCCState* S, int token, uint32_t opcode, const Operand* rs1, const Operand* rs2, const Operand* imm)417static void asm_emit_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, "'%s': Expected first source operand that is a register", get_tok_str(S, token, NULL));420 tcc_error("'%s': Expected first source operand that is a register", get_tok_str(token, NULL));
421 return;421 return;
422 }422 }
423 if (rs2->type != OP_REG) {423 if (rs2->type != OP_REG) {
424 tcc_error(S, "'%s': Expected second source operand that is a register", get_tok_str(S, token, NULL));424 tcc_error("'%s': Expected second source operand that is a register", get_tok_str(token, NULL));
425 return;425 return;
426 }426 }
427 if (imm->type != OP_IM12S) {427 if (imm->type != OP_IM12S) {
428 tcc_error(S, "'%s': Expected third operand that is an immediate value between 0 and 0xfff", get_tok_str(S, token, NULL));428 tcc_error("'%s': Expected third operand that is an immediate value between 0 and 0xfff", get_tok_str(token, NULL));
429 return;429 return;
430 }430 }
431 {431 {
@@ -438,112 +438,112 @@ static void asm_emit_s(TCCState* S, int token, uint32_t opcode, const Operand* r · 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(S, opcode | ENCODE_RS1(rs1->reg) | ENCODE_RS2(rs2->reg) | ((v & 0x1F) << 7) | ((v >> 5) << 25));441 gen_le32(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* S, int token)445static void asm_data_transfer_opcode(TCCState* s1, int token)
446{446{
447 Operand ops[3];447 Operand ops[3];
448 parse_operand(S, &ops[0]);448 parse_operand(s1, &ops[0]);
449 if (ops[0].type != OP_REG) {449 if (ops[0].type != OP_REG) {
450 expect(S, "register");450 expect("register");
451 return;451 return;
452 }452 }
453 if (S->tccpp_tok == ',')453 if (tok == ',')
454 next(S);454 next();
455 else455 else
456 expect(S, "','");456 expect("','");
457 parse_operand(S, &ops[1]);457 parse_operand(s1, &ops[1]);
458 if (ops[1].type != OP_REG) {458 if (ops[1].type != OP_REG) {
459 expect(S, "register");459 expect("register");
460 return;460 return;
461 }461 }
462 if (S->tccpp_tok == ',')462 if (tok == ',')
463 next(S);463 next();
464 else464 else
465 expect(S, "','");465 expect("','");
466 parse_operand(S, &ops[2]);466 parse_operand(s1, &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(S, token, (0x0 << 2) | 3, &ops[0], &ops[1], &ops[2]);472 asm_emit_i(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(S, token, (0x0 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]);475 asm_emit_i(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(S, token, (0x0 << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]);478 asm_emit_i(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(S, token, (0x0 << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]);481 asm_emit_i(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(S, token, (0x0 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);484 asm_emit_i(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(S, token, (0x0 << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]);488 asm_emit_i(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(S, token, (0x0 << 2) | 3 | (6 << 12), &ops[0], &ops[1], &ops[2]);491 asm_emit_i(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(S, token, (0x8 << 2) | 3 | (0 << 12), &ops[0], &ops[1], &ops[2]);497 asm_emit_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(S, token, (0x8 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]);500 asm_emit_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(S, token, (0x8 << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]);503 asm_emit_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(S, token, (0x8 << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]);506 asm_emit_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(S, "known data transfer instruction");510 expect("known data transfer instruction");
511 }511 }
512}512}
513 513
514static void asm_branch_opcode(TCCState* S, int token)514static void asm_branch_opcode(TCCState* s1, 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(S, &ops[0]);520 parse_operand(s1, &ops[0]);
521 if (ops[0].type != OP_REG) {521 if (ops[0].type != OP_REG) {
522 expect(S, "register");522 expect("register");
523 return;523 return;
524 }524 }
525 if (S->tccpp_tok == ',')525 if (tok == ',')
526 next(S);526 next();
527 else527 else
528 expect(S, "','");528 expect("','");
529 parse_operand(S, &ops[1]);529 parse_operand(s1, &ops[1]);
530 if (ops[1].type != OP_REG) {530 if (ops[1].type != OP_REG) {
531 expect(S, "register");531 expect("register");
532 return;532 return;
533 }533 }
534 if (S->tccpp_tok == ',')534 if (tok == ',')
535 next(S);535 next();
536 else536 else
537 expect(S, "','");537 expect("','");
538 parse_operand(S, &ops[2]);538 parse_operand(s1, &ops[2]);
539 539
540 if (ops[2].type != OP_IM12S) {540 if (ops[2].type != OP_IM12S) {
541 tcc_error(S, "'%s': Expected third operand that is an immediate value between 0 and 0xfff", get_tok_str(S, token, NULL));541 tcc_error("'%s': Expected third operand that is an immediate value between 0 and 0xfff", get_tok_str(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, "'%s': Expected third operand that is an even immediate value", get_tok_str(S, token, NULL));546 tcc_error("'%s': Expected third operand that is an even immediate value", get_tok_str(token, NULL));
547 return;547 return;
548 }548 }
549 549
@@ -567,12 +567,12 @@ static void asm_branch_opcode(TCCState* S, int token) · 17 unmodified lines
567 opcode |= 7 << 12;567 opcode |= 7 << 12;
568 break;568 break;
569 default:569 default:
570 expect(S, "known branch instruction");570 expect("known branch instruction");
571 }571 }
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));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));
573}573}
574 574
575ST_FUNC void asm_opcode(TCCState *S, int token)575ST_FUNC void asm_opcode(TCCState *s1, 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 *S, 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(S, token);588 asm_nullary_opcode(s1, 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 *S, 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(S, token);597 asm_unary_opcode(s1, 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(S, token);602 asm_binary_opcode(s1, 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 *S, 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(S, token);623 asm_shift_opcode(s1, 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 *S, 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(S, token);645 asm_data_processing_opcode(s1, 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 *S, 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(S, token);658 asm_data_transfer_opcode(s1, 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 *S, 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(S, token);667 asm_branch_opcode(s1, token);
668 return;668 return;
669 669
670 default:670 default:
671 expect(S, "known instruction");671 expect("known instruction");
672 }672 }
673}673}
674 674
675ST_FUNC void subst_asm_operand(TCCState *S, CString *add_str, SValue *sv, int modifier)675ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier)
676{676{
677 tcc_error(S, "RISCV64 asm not implemented.");677 tcc_error("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(TCCState *S, ASMOperand *operands, int nb_operands,681ST_FUNC void asm_gen_code(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(TCCState *S, ASMOperand *operands,688ST_FUNC void asm_compute_constraints(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(TCCState *S, uint8_t *clobber_regs, const char *str)695ST_FUNC void asm_clobber(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(TCCState *S, 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(S, str, strlen(str));704 ts = tok_alloc(str, strlen(str));
705 reg = asm_parse_regvar(S, ts->tok);705 reg = asm_parse_regvar(ts->tok);
706 if (reg == -1) {706 if (reg == -1) {
707 tcc_error(S, "invalid clobber register '%s'", str);707 tcc_error("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 (TCCState* S, int t)712ST_FUNC int asm_parse_regvar (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+457−451
@@ -74,6 +74,12 @@ 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
77static int ireg(int r)83static int ireg(int r)
78{84{
79 if (r == TREG_RA)85 if (r == TREG_RA)
@@ -100,46 +106,46 @@ static int is_freg(int r) · 20 unmodified lines
100 return r >= 8 && r < 16;106 return r >= 8 && r < 16;
101}107}
102 108
103ST_FUNC void o(TCCState* S, unsigned int c)109ST_FUNC void o(unsigned int c)
104{110{
105 int ind1 = S->tccgen_ind + 4;111 int ind1 = ind + 4;
106 if (S->tccgen_nocode_wanted)112 if (nocode_wanted)
107 return;113 return;
108 if (ind1 > cur_text_section->data_allocated)114 if (ind1 > cur_text_section->data_allocated)
109 section_realloc(S, cur_text_section, ind1);115 section_realloc(cur_text_section, ind1);
110 write32le(cur_text_section->data + S->tccgen_ind, c);116 write32le(cur_text_section->data + ind, c);
111 S->tccgen_ind = ind1;117 ind = ind1;
112}118}
113 119
114static void EIu(TCCState* S, uint32_t opcode, uint32_t func3,120static void EIu(uint32_t opcode, uint32_t func3,
115 uint32_t rd, uint32_t rs1, uint32_t imm)121 uint32_t rd, uint32_t rs1, uint32_t imm)
116{122{
117 o(S, opcode | (func3 << 12) | (rd << 7) | (rs1 << 15) | (imm << 20));123 o(opcode | (func3 << 12) | (rd << 7) | (rs1 << 15) | (imm << 20));
118}124}
119 125
120static void ER(TCCState* S, uint32_t opcode, uint32_t func3,126static void ER(uint32_t opcode, uint32_t func3,
121 uint32_t rd, uint32_t rs1, uint32_t rs2, uint32_t func7)127 uint32_t rd, uint32_t rs1, uint32_t rs2, uint32_t func7)
122{128{
123 o(S, opcode | func3 << 12 | rd << 7 | rs1 << 15 | rs2 << 20 | func7 << 25);129 o(opcode | func3 << 12 | rd << 7 | rs1 << 15 | rs2 << 20 | func7 << 25);
124}130}
125 131
126static void EI(TCCState* S, uint32_t opcode, uint32_t func3,132static void EI(uint32_t opcode, uint32_t func3,
127 uint32_t rd, uint32_t rs1, uint32_t imm)133 uint32_t rd, uint32_t rs1, uint32_t imm)
128{134{
129 assert(! ((imm + (1 << 11)) >> 12));135 assert(! ((imm + (1 << 11)) >> 12));
130 EIu(S, opcode, func3, rd, rs1, imm);136 EIu(opcode, func3, rd, rs1, imm);
131}137}
132 138
133static void ES(TCCState* S, uint32_t opcode, uint32_t func3,139static void ES(uint32_t opcode, uint32_t func3,
134 uint32_t rs1, uint32_t rs2, uint32_t imm)140 uint32_t rs1, uint32_t rs2, uint32_t imm)
135{141{
136 assert(! ((imm + (1 << 11)) >> 12));142 assert(! ((imm + (1 << 11)) >> 12));
137 o(S, opcode | (func3 << 12) | ((imm & 0x1f) << 7) | (rs1 << 15)143 o(opcode | (func3 << 12) | ((imm & 0x1f) << 7) | (rs1 << 15)
138 | (rs2 << 20) | ((imm >> 5) << 25));144 | (rs2 << 20) | ((imm >> 5) << 25));
139}145}
140 146
141// Patch all branches in list pointed to by t to branch to a:147// Patch all branches in list pointed to by t to branch to a:
142ST_FUNC void gsym_addr(TCCState* S, int t_, int a_)148ST_FUNC void gsym_addr(int t_, int a_)
143{149{
144 uint32_t t = t_;150 uint32_t t = t_;
145 uint32_t a = a_;151 uint32_t a = a_;
@@ -148,7 +154,7 @@ ST_FUNC void gsym_addr(TCCState* S, int t_, int a_) · 2 unmodified lines
148 uint32_t next = read32le(ptr);154 uint32_t next = read32le(ptr);
149 uint32_t r = a - t, imm;155 uint32_t r = a - t, imm;
150 if ((r + (1 << 21)) & ~((1U << 22) - 2))156 if ((r + (1 << 21)) & ~((1U << 22) - 2))
151 tcc_error(S, "out-of-range branch chain");157 tcc_error("out-of-range branch chain");
152 imm = (((r >> 12) & 0xff) << 12)158 imm = (((r >> 12) & 0xff) << 12)
153 | (((r >> 11) & 1) << 20)159 | (((r >> 11) & 1) << 20)
154 | (((r >> 1) & 0x3ff) << 21)160 | (((r >> 1) & 0x3ff) << 21)
@@ -158,7 +164,7 @@ ST_FUNC void gsym_addr(TCCState* S, int t_, int a_) · 3 unmodified lines
158 }164 }
159}165}
160 166
161static int load_symofs(TCCState* S, int r, SValue *sv, int forstore)167static int load_symofs(int r, SValue *sv, int forstore)
162{168{
163 int rr, doload = 0;169 int rr, doload = 0;
164 int fc = sv->c.i, v = sv->r & VT_VALMASK;170 int fc = sv->c.i, v = sv->r & VT_VALMASK;
@@ -166,56 +172,56 @@ static int load_symofs(TCCState* S, int r, SValue *sv, int forstore) · 1 unmodified line
166 Sym label = {0};172 Sym label = {0};
167 assert(v == VT_CONST);173 assert(v == VT_CONST);
168 if (sv->sym->type.t & VT_STATIC) { // XXX do this per linker relax174 if (sv->sym->type.t & VT_STATIC) { // XXX do this per linker relax
169 greloca(S, cur_text_section, sv->sym, S->tccgen_ind,175 greloca(cur_text_section, sv->sym, ind,
170 R_RISCV_PCREL_HI20, sv->c.i);176 R_RISCV_PCREL_HI20, sv->c.i);
171 sv->c.i = 0;177 sv->c.i = 0;
172 } else {178 } else {
173 if (((unsigned)fc + (1 << 11)) >> 12)179 if (((unsigned)fc + (1 << 11)) >> 12)
174 tcc_error(S, "unimp: large addend for global address (0x%lx)", (long)sv->c.i);180 tcc_error("unimp: large addend for global address (0x%lx)", (long)sv->c.i);
175 greloca(S, cur_text_section, sv->sym, S->tccgen_ind,181 greloca(cur_text_section, sv->sym, ind,
176 R_RISCV_GOT_HI20, 0);182 R_RISCV_GOT_HI20, 0);
177 doload = 1;183 doload = 1;
178 }184 }
179 label.type.t = VT_VOID | VT_STATIC;185 label.type.t = VT_VOID | VT_STATIC;
180 put_extern_sym(S, &label, cur_text_section, S->tccgen_ind, 0);186 put_extern_sym(&label, cur_text_section, ind, 0);
181 rr = is_ireg(r) ? ireg(r) : 5;187 rr = is_ireg(r) ? ireg(r) : 5;
182 o(S, 0x17 | (rr << 7)); // auipc RR, 0 %pcrel_hi(sym)+addend188 o(0x17 | (rr << 7)); // auipc RR, 0 %pcrel_hi(sym)+addend
183 greloca(S, cur_text_section, &label, S->tccgen_ind,189 greloca(cur_text_section, &label, ind,
184 doload || !forstore190 doload || !forstore
185 ? R_RISCV_PCREL_LO12_I : R_RISCV_PCREL_LO12_S, 0);191 ? R_RISCV_PCREL_LO12_I : R_RISCV_PCREL_LO12_S, 0);
186 if (doload) {192 if (doload) {
187 EI(S, 0x03, 3, rr, rr, 0); // ld RR, 0(RR)193 EI(0x03, 3, rr, rr, 0); // ld RR, 0(RR)
188 }194 }
189 } else if (v == VT_LOCAL || v == VT_LLOCAL) {195 } else if (v == VT_LOCAL || v == VT_LLOCAL) {
190 rr = 8; // s0196 rr = 8; // s0
191 if (fc != sv->c.i)197 if (fc != sv->c.i)
192 tcc_error(S, "unimp: store(giant local off) (0x%lx)", (long)sv->c.i);198 tcc_error("unimp: store(giant local off) (0x%lx)", (long)sv->c.i);
193 if (((unsigned)fc + (1 << 11)) >> 12) {199 if (((unsigned)fc + (1 << 11)) >> 12) {
194 rr = is_ireg(r) ? ireg(r) : 5; // t0200 rr = is_ireg(r) ? ireg(r) : 5; // t0
195 o(S, 0x37 | (rr << 7) | ((0x800 + fc) & 0xfffff000)); //lui RR, upper(fc)201 o(0x37 | (rr << 7) | ((0x800 + fc) & 0xfffff000)); //lui RR, upper(fc)
196 ER(S, 0x33, 0, rr, rr, 8, 0); // add RR, RR, s0202 ER(0x33, 0, rr, rr, 8, 0); // add RR, RR, s0
197 sv->c.i = fc << 20 >> 20;203 sv->c.i = fc << 20 >> 20;
198 }204 }
199 } else205 } else
200 tcc_error(S, "uhh");206 tcc_error("uhh");
201 return rr;207 return rr;
202}208}
203 209
204static void load_large_constant(TCCState* S, int rr, int fc, uint32_t pi)210static void load_large_constant(int rr, int fc, uint32_t pi)
205{211{
206 if (fc < 0)212 if (fc < 0)
207 pi++;213 pi++;
208 o(S, 0x37 | (rr << 7) | (((pi + 0x800) & 0xfffff000))); // lui RR, up(up(fc))214 o(0x37 | (rr << 7) | (((pi + 0x800) & 0xfffff000))); // lui RR, up(up(fc))
209 EI(S, 0x13, 0, rr, rr, (int)pi << 20 >> 20); // addi RR, RR, lo(up(fc))215 EI(0x13, 0, rr, rr, (int)pi << 20 >> 20); // addi RR, RR, lo(up(fc))
210 EI(S, 0x13, 1, rr, rr, 12); // slli RR, RR, 12216 EI(0x13, 1, rr, rr, 12); // slli RR, RR, 12
211 EI(S, 0x13, 0, rr, rr, (fc + (1 << 19)) >> 20); // addi RR, RR, up(lo(fc))217 EI(0x13, 0, rr, rr, (fc + (1 << 19)) >> 20); // addi RR, RR, up(lo(fc))
212 EI(S, 0x13, 1, rr, rr, 12); // slli RR, RR, 12218 EI(0x13, 1, rr, rr, 12); // slli RR, RR, 12
213 fc = fc << 12 >> 12;219 fc = fc << 12 >> 12;
214 EI(S, 0x13, 0, rr, rr, fc >> 8); // addi RR, RR, lo1(lo(fc))220 EI(0x13, 0, rr, rr, fc >> 8); // addi RR, RR, lo1(lo(fc))
215 EI(S, 0x13, 1, rr, rr, 8); // slli RR, RR, 8221 EI(0x13, 1, rr, rr, 8); // slli RR, RR, 8
216}222}
217 223
218ST_FUNC void load(TCCState* S, int r, SValue *sv)224ST_FUNC void load(int r, SValue *sv)
219{225{
220 int fr = sv->r;226 int fr = sv->r;
221 int v = fr & VT_VALMASK;227 int v = fr & VT_VALMASK;
@@ -233,49 +239,49 @@ ST_FUNC void load(TCCState* S, int r, SValue *sv) · 11 unmodified lines
233 if (size < 4 && !is_float(sv->type.t) && (sv->type.t & VT_UNSIGNED))239 if (size < 4 && !is_float(sv->type.t) && (sv->type.t & VT_UNSIGNED))
234 func3 |= 4;240 func3 |= 4;
235 if (v == VT_LOCAL || (fr & VT_SYM)) {241 if (v == VT_LOCAL || (fr & VT_SYM)) {
236 br = load_symofs(S, r, sv, 0);242 br = load_symofs(r, sv, 0);
237 fc = sv->c.i;243 fc = sv->c.i;
238 } else if (v < VT_CONST) {244 } else if (v < VT_CONST) {
239 br = ireg(v);245 br = ireg(v);
240 /*if (((unsigned)fc + (1 << 11)) >> 12)246 /*if (((unsigned)fc + (1 << 11)) >> 12)
241 tcc_error(S, "unimp: load(large addend) (0x%x)", fc);*/247 tcc_error("unimp: load(large addend) (0x%x)", fc);*/
242 fc = 0; // XXX store ofs in LVAL(reg)248 fc = 0; // XXX store ofs in LVAL(reg)
243 } else if (v == VT_LLOCAL) {249 } else if (v == VT_LLOCAL) {
244 br = load_symofs(S, r, sv, 0);250 br = load_symofs(r, sv, 0);
245 fc = sv->c.i;251 fc = sv->c.i;
246 EI(S, 0x03, 3, rr, br, fc); // ld RR, fc(BR)252 EI(0x03, 3, rr, br, fc); // ld RR, fc(BR)
247 br = rr;253 br = rr;
248 fc = 0;254 fc = 0;
249 } else if (v == VT_CONST) {255 } else if (v == VT_CONST) {
250 int64_t si = sv->c.i;256 int64_t si = sv->c.i;
251 si >>= 32;257 si >>= 32;
252 if (si != 0) {258 if (si != 0) {
253 load_large_constant(S, rr, fc, si);259 load_large_constant(rr, fc, si);
254 fc &= 0xff;260 fc &= 0xff;
255 } else {261 } else {
256 o(S, 0x37 | (rr << 7) | ((0x800 + fc) & 0xfffff000)); //lui RR, upper(fc)262 o(0x37 | (rr << 7) | ((0x800 + fc) & 0xfffff000)); //lui RR, upper(fc)
257 fc = fc << 20 >> 20;263 fc = fc << 20 >> 20;
258 }264 }
259 br = rr;265 br = rr;
260 } else {266 } else {
261 tcc_error(S, "unimp: load(non-local lval)");267 tcc_error("unimp: load(non-local lval)");
262 }268 }
263 EI(S, opcode, func3, rr, br, fc); // l[bhwd][u] / fl[wd] RR, fc(BR)269 EI(opcode, func3, rr, br, fc); // l[bhwd][u] / fl[wd] RR, fc(BR)
264 } else if (v == VT_CONST) {270 } else if (v == VT_CONST) {
265 int rb = 0, do32bit = 8, zext = 0;271 int rb = 0, do32bit = 8, zext = 0;
266 assert((!is_float(sv->type.t) && is_ireg(r)) || bt == VT_LDOUBLE);272 assert((!is_float(sv->type.t) && is_ireg(r)) || bt == VT_LDOUBLE);
267 if (fr & VT_SYM) {273 if (fr & VT_SYM) {
268 rb = load_symofs(S, r, sv, 0);274 rb = load_symofs(r, sv, 0);
269 fc = sv->c.i;275 fc = sv->c.i;
270 do32bit = 0;276 do32bit = 0;
271 }277 }
272 if (is_float(sv->type.t) && bt != VT_LDOUBLE)278 if (is_float(sv->type.t) && bt != VT_LDOUBLE)
273 tcc_error(S, "unimp: load(float)");279 tcc_error("unimp: load(float)");
274 if (fc != sv->c.i) {280 if (fc != sv->c.i) {
275 int64_t si = sv->c.i;281 int64_t si = sv->c.i;
276 si >>= 32;282 si >>= 32;
277 if (si != 0) {283 if (si != 0) {
278 load_large_constant(S, rr, fc, si);284 load_large_constant(rr, fc, si);
279 fc &= 0xff;285 fc &= 0xff;
280 rb = rr;286 rb = rr;
281 do32bit = 0;287 do32bit = 0;
@@ -286,37 +292,37 @@ ST_FUNC void load(TCCState* S, int r, SValue *sv) · 4 unmodified lines
286 }292 }
287 }293 }
288 if (((unsigned)fc + (1 << 11)) >> 12)294 if (((unsigned)fc + (1 << 11)) >> 12)
289 o(S, 0x37 | (rr << 7) | ((0x800 + fc) & 0xfffff000)), rb = rr; //lui RR, upper(fc)295 o(0x37 | (rr << 7) | ((0x800 + fc) & 0xfffff000)), rb = rr; //lui RR, upper(fc)
290 if (fc || (rr != rb) || do32bit || (fr & VT_SYM))296 if (fc || (rr != rb) || do32bit || (fr & VT_SYM))
291 EI(S, 0x13 | do32bit, 0, rr, rb, fc << 20 >> 20); // addi[w] R, x0|R, FC297 EI(0x13 | do32bit, 0, rr, rb, fc << 20 >> 20); // addi[w] R, x0|R, FC
292 if (zext) {298 if (zext) {
293 EI(S, 0x13, 1, rr, rr, 32); // slli RR, RR, 32299 EI(0x13, 1, rr, rr, 32); // slli RR, RR, 32
294 EI(S, 0x13, 5, rr, rr, 32); // srli RR, RR, 32300 EI(0x13, 5, rr, rr, 32); // srli RR, RR, 32
295 }301 }
296 } else if (v == VT_LOCAL) {302 } else if (v == VT_LOCAL) {
297 int br = load_symofs(S, r, sv, 0);303 int br = load_symofs(r, sv, 0);
298 assert(is_ireg(r));304 assert(is_ireg(r));
299 fc = sv->c.i;305 fc = sv->c.i;
300 EI(S, 0x13, 0, rr, br, fc); // addi R, s0, FC306 EI(0x13, 0, rr, br, fc); // addi R, s0, FC
301 } else if (v < VT_CONST) { /* reg-reg */307 } else if (v < VT_CONST) { /* reg-reg */
302 //assert(!fc); XXX support offseted regs308 //assert(!fc); XXX support offseted regs
303 if (is_freg(r) && is_freg(v))309 if (is_freg(r) && is_freg(v))
304 ER(S, 0x53, 0, rr, freg(v), freg(v), bt == VT_DOUBLE ? 0x11 : 0x10); //fsgnj.[sd] RR, V, V == fmv.[sd] RR, V310 ER(0x53, 0, rr, freg(v), freg(v), bt == VT_DOUBLE ? 0x11 : 0x10); //fsgnj.[sd] RR, V, V == fmv.[sd] RR, V
305 else if (is_ireg(r) && is_ireg(v))311 else if (is_ireg(r) && is_ireg(v))
306 EI(S, 0x13, 0, rr, ireg(v), 0); // addi RR, V, 0 == mv RR, V312 EI(0x13, 0, rr, ireg(v), 0); // addi RR, V, 0 == mv RR, V
307 else {313 else {
308 int func7 = is_ireg(r) ? 0x70 : 0x78;314 int func7 = is_ireg(r) ? 0x70 : 0x78;
309 size = type_size(&sv->type, &align);315 size = type_size(&sv->type, &align);
310 if (size == 8)316 if (size == 8)
311 func7 |= 1;317 func7 |= 1;
312 assert(size == 4 || size == 8);318 assert(size == 4 || size == 8);
313 o(S, 0x53 | (rr << 7) | ((is_freg(v) ? freg(v) : ireg(v)) << 15)319 o(0x53 | (rr << 7) | ((is_freg(v) ? freg(v) : ireg(v)) << 15)
314 | (func7 << 25)); // fmv.{w.x, x.w, d.x, x.d} RR, VR320 | (func7 << 25)); // fmv.{w.x, x.w, d.x, x.d} RR, VR
315 }321 }
316 } else if (v == VT_CMP) {322 } else if (v == VT_CMP) {
317 int op = S->tccgen_vtop->cmp_op;323 int op = vtop->cmp_op;
318 int a = S->tccgen_vtop->cmp_r & 0xff;324 int a = vtop->cmp_r & 0xff;
319 int b = (S->tccgen_vtop->cmp_r >> 8) & 0xff;325 int b = (vtop->cmp_r >> 8) & 0xff;
320 int inv = 0;326 int inv = 0;
321 switch (op) {327 switch (op) {
322 case TOK_ULT:328 case TOK_ULT:
@@ -335,32 +341,32 @@ ST_FUNC void load(TCCState* S, int r, SValue *sv) · 12 unmodified lines
335 int t = a; a = b; b = t;341 int t = a; a = b; b = t;
336 inv ^= 1;342 inv ^= 1;
337 }343 }
338 ER(S, 0x33, (op > TOK_UGT) ? 2 : 3, rr, a, b, 0); // slt[u] d, a, b344 ER(0x33, (op > TOK_UGT) ? 2 : 3, rr, a, b, 0); // slt[u] d, a, b
339 if (inv)345 if (inv)
340 EI(S, 0x13, 4, rr, rr, 1); // xori d, d, 1346 EI(0x13, 4, rr, rr, 1); // xori d, d, 1
341 break;347 break;
342 case TOK_NE:348 case TOK_NE:
343 case TOK_EQ:349 case TOK_EQ:
344 if (rr != a || b)350 if (rr != a || b)
345 ER(S, 0x33, 0, rr, a, b, 0x20); // sub d, a, b351 ER(0x33, 0, rr, a, b, 0x20); // sub d, a, b
346 if (op == TOK_NE)352 if (op == TOK_NE)
347 ER(S, 0x33, 3, rr, 0, rr, 0); // sltu d, x0, d == snez d,d353 ER(0x33, 3, rr, 0, rr, 0); // sltu d, x0, d == snez d,d
348 else354 else
349 EI(S, 0x13, 3, rr, rr, 1); // sltiu d, d, 1 == seqz d,d355 EI(0x13, 3, rr, rr, 1); // sltiu d, d, 1 == seqz d,d
350 break;356 break;
351 }357 }
352 } else if ((v & ~1) == VT_JMP) {358 } else if ((v & ~1) == VT_JMP) {
353 int t = v & 1;359 int t = v & 1;
354 assert(is_ireg(r));360 assert(is_ireg(r));
355 EI(S, 0x13, 0, rr, 0, t); // addi RR, x0, t361 EI(0x13, 0, rr, 0, t); // addi RR, x0, t
356 gjmp_addr(S, S->tccgen_ind + 8);362 gjmp_addr(ind + 8);
357 gsym(S, fc);363 gsym(fc);
358 EI(S, 0x13, 0, rr, 0, t ^ 1); // addi RR, x0, !t364 EI(0x13, 0, rr, 0, t ^ 1); // addi RR, x0, !t
359 } else365 } else
360 tcc_error(S, "unimp: load(non-const)");366 tcc_error("unimp: load(non-const)");
361}367}
362 368
363ST_FUNC void store(TCCState* S, int r, SValue *sv)369ST_FUNC void store(int r, SValue *sv)
364{370{
365 int fr = sv->r & VT_VALMASK;371 int fr = sv->r & VT_VALMASK;
366 int rr = is_ireg(r) ? ireg(r) : freg(r), ptrreg;372 int rr = is_ireg(r) ? ireg(r) : freg(r), ptrreg;
@@ -373,125 +379,125 @@ ST_FUNC void store(TCCState* S, int r, SValue *sv) · 6 unmodified lines
373 if (bt == VT_LDOUBLE)379 if (bt == VT_LDOUBLE)
374 size = align = 8;380 size = align = 8;
375 if (bt == VT_STRUCT)381 if (bt == VT_STRUCT)
376 tcc_error(S, "unimp: store(struct)");382 tcc_error("unimp: store(struct)");
377 if (size > 8)383 if (size > 8)
378 tcc_error(S, "unimp: large sized store");384 tcc_error("unimp: large sized store");
379 assert(sv->r & VT_LVAL);385 assert(sv->r & VT_LVAL);
380 if (fr == VT_LOCAL || (sv->r & VT_SYM)) {386 if (fr == VT_LOCAL || (sv->r & VT_SYM)) {
381 ptrreg = load_symofs(S, -1, sv, 1);387 ptrreg = load_symofs(-1, sv, 1);
382 fc = sv->c.i;388 fc = sv->c.i;
383 } else if (fr < VT_CONST) {389 } else if (fr < VT_CONST) {
384 ptrreg = ireg(fr);390 ptrreg = ireg(fr);
385 /*if (((unsigned)fc + (1 << 11)) >> 12)391 /*if (((unsigned)fc + (1 << 11)) >> 12)
386 tcc_error(S, "unimp: store(large addend) (0x%x)", fc);*/392 tcc_error("unimp: store(large addend) (0x%x)", fc);*/
387 fc = 0; // XXX support offsets regs393 fc = 0; // XXX support offsets regs
388 } else if (fr == VT_CONST) {394 } else if (fr == VT_CONST) {
389 int64_t si = sv->c.i;395 int64_t si = sv->c.i;
390 ptrreg = 8; // s0396 ptrreg = 8; // s0
391 si >>= 32;397 si >>= 32;
392 if (si != 0) {398 if (si != 0) {
393 load_large_constant(S, ptrreg, fc, si);399 load_large_constant(ptrreg, fc, si);
394 fc &= 0xff;400 fc &= 0xff;
395 } else {401 } else {
396 o(S, 0x37 | (ptrreg << 7) | ((0x800 + fc) & 0xfffff000)); //lui RR, upper(fc)402 o(0x37 | (ptrreg << 7) | ((0x800 + fc) & 0xfffff000)); //lui RR, upper(fc)
397 fc = fc << 20 >> 20;403 fc = fc << 20 >> 20;
398 }404 }
399 } else405 } else
400 tcc_error(S, "implement me: %s(!local)", __FUNCTION__);406 tcc_error("implement me: %s(!local)", __FUNCTION__);
401 ES(S, is_freg(r) ? 0x27 : 0x23, // fs... | s...407 ES(is_freg(r) ? 0x27 : 0x23, // fs... | s...
402 size == 1 ? 0 : size == 2 ? 1 : size == 4 ? 2 : 3, // ... [wd] | [bhwd]408 size == 1 ? 0 : size == 2 ? 1 : size == 4 ? 2 : 3, // ... [wd] | [bhwd]
403 ptrreg, rr, fc); // RR, fc(base)409 ptrreg, rr, fc); // RR, fc(base)
404}410}
405 411
406static void gcall_or_jmp(TCCState* S, int docall)412static void gcall_or_jmp(int docall)
407{413{
408 int tr = docall ? 1 : 5; // ra or t0414 int tr = docall ? 1 : 5; // ra or t0
409 if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&415 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
410 ((S->tccgen_vtop->r & VT_SYM) && S->tccgen_vtop->c.i == (int)S->tccgen_vtop->c.i)) {416 ((vtop->r & VT_SYM) && vtop->c.i == (int)vtop->c.i)) {
411 /* constant symbolic case -> simple relocation */417 /* constant symbolic case -> simple relocation */
412 greloca(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind,418 greloca(cur_text_section, vtop->sym, ind,
413 R_RISCV_CALL_PLT, (int)S->tccgen_vtop->c.i);419 R_RISCV_CALL_PLT, (int)vtop->c.i);
414 o(S, 0x17 | (tr << 7)); // auipc TR, 0 %call(func)420 o(0x17 | (tr << 7)); // auipc TR, 0 %call(func)
415 EI(S, 0x67, 0, tr, tr, 0);// jalr TR, r(TR)421 EI(0x67, 0, tr, tr, 0);// jalr TR, r(TR)
416 } else if (S->tccgen_vtop->r < VT_CONST) {422 } else if (vtop->r < VT_CONST) {
417 int r = ireg(S->tccgen_vtop->r);423 int r = ireg(vtop->r);
418 EI(S, 0x67, 0, tr, r, 0); // jalr TR, 0(R)424 EI(0x67, 0, tr, r, 0); // jalr TR, 0(R)
419 } else {425 } else {
420 int r = TREG_RA;426 int r = TREG_RA;
421 load(S, r, S->tccgen_vtop);427 load(r, vtop);
422 r = ireg(r);428 r = ireg(r);
423 EI(S, 0x67, 0, tr, r, 0); // jalr TR, 0(R)429 EI(0x67, 0, tr, r, 0); // jalr TR, 0(R)
424 }430 }
425}431}
426 432
427#if defined(CONFIG_TCC_BCHECK)433#if defined(CONFIG_TCC_BCHECK)
428 434
429static void gen_bounds_call(TCCState* S, int v)435static void gen_bounds_call(int v)
430{436{
431 Sym *sym = external_helper_sym(S, v);437 Sym *sym = external_helper_sym(v);
432 438
433 greloca(S, cur_text_section, sym, S->tccgen_ind, R_RISCV_CALL_PLT, 0);439 greloca(cur_text_section, sym, ind, R_RISCV_CALL_PLT, 0);
434 o(S, 0x17 | (1 << 7)); // auipc TR, 0 %call(func)440 o(0x17 | (1 << 7)); // auipc TR, 0 %call(func)
435 EI(S, 0x67, 0, 1, 1, 0); // jalr TR, r(TR)441 EI(0x67, 0, 1, 1, 0); // jalr TR, r(TR)
436}442}
437 443
438static void gen_bounds_prolog(TCCState* S)444static void gen_bounds_prolog(void)
439{445{
440 /* leave some room for bound checking code */446 /* leave some room for bound checking code */
441 S->func_bound_offset = lbounds_section->data_offset;447 func_bound_offset = lbounds_section->data_offset;
442 S->func_bound_ind = S->tccgen_ind;448 func_bound_ind = ind;
443 S->func_bound_add_epilog = 0;449 func_bound_add_epilog = 0;
444 o(S, 0x00000013); /* ld a0,#lbound section pointer */450 o(0x00000013); /* ld a0,#lbound section pointer */
445 o(S, 0x00000013);451 o(0x00000013);
446 o(S, 0x00000013); /* nop -> call __bound_local_new */452 o(0x00000013); /* nop -> call __bound_local_new */
447 o(S, 0x00000013);453 o(0x00000013);
448}454}
449 455
450static void gen_bounds_epilog(TCCState* S)456static void gen_bounds_epilog(void)
451{457{
452 addr_t saved_ind;458 addr_t saved_ind;
453 addr_t *bounds_ptr;459 addr_t *bounds_ptr;
454 Sym *sym_data;460 Sym *sym_data;
455 Sym label = {0};461 Sym label = {0};
456 462
457 int offset_modified = S->func_bound_offset != lbounds_section->data_offset;463 int offset_modified = func_bound_offset != lbounds_section->data_offset;
458 464
459 if (!offset_modified && !S->func_bound_add_epilog)465 if (!offset_modified && !func_bound_add_epilog)
460 return;466 return;
461 467
462 /* add end of table info */468 /* add end of table info */
463 bounds_ptr = section_ptr_add(S, lbounds_section, sizeof(addr_t));469 bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));
464 *bounds_ptr = 0;470 *bounds_ptr = 0;
465 471
466 sym_data = get_sym_ref(S, &S->tccgen_char_pointer_type, lbounds_section,472 sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
467 S->func_bound_offset, lbounds_section->data_offset);473 func_bound_offset, lbounds_section->data_offset);
468 474
469 label.type.t = VT_VOID | VT_STATIC;475 label.type.t = VT_VOID | VT_STATIC;
470 /* generate bound local allocation */476 /* generate bound local allocation */
471 if (offset_modified) {477 if (offset_modified) {
472 saved_ind = S->tccgen_ind;478 saved_ind = ind;
473 S->tccgen_ind = S->func_bound_ind;479 ind = func_bound_ind;
474 put_extern_sym(S, &label, cur_text_section, S->tccgen_ind, 0);480 put_extern_sym(&label, cur_text_section, ind, 0);
475 greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_RISCV_GOT_HI20, 0);481 greloca(cur_text_section, sym_data, ind, R_RISCV_GOT_HI20, 0);
476 o(S, 0x17 | (10 << 7)); // auipc a0, 0 %pcrel_hi(sym)+addend482 o(0x17 | (10 << 7)); // auipc a0, 0 %pcrel_hi(sym)+addend
477 greloca(S, cur_text_section, &label, S->tccgen_ind, R_RISCV_PCREL_LO12_I, 0);483 greloca(cur_text_section, &label, ind, R_RISCV_PCREL_LO12_I, 0);
478 EI(S, 0x03, 3, 10, 10, 0); // ld a0, 0(a0)484 EI(0x03, 3, 10, 10, 0); // ld a0, 0(a0)
479 gen_bounds_call(S, TOK___bound_local_new);485 gen_bounds_call(TOK___bound_local_new);
480 S->tccgen_ind = saved_ind;486 ind = saved_ind;
481 label.c = 0; /* force new local ELF symbol */487 label.c = 0; /* force new local ELF symbol */
482 }488 }
483 489
484 /* generate bound check local freeing */490 /* generate bound check local freeing */
485 o(S, 0xe02a1101); /* addi sp,sp,-32 sd a0,0(sp) */491 o(0xe02a1101); /* addi sp,sp,-32 sd a0,0(sp) */
486 o(S, 0xa82ae42e); /* sd a1,8(sp) fsd fa0,16(sp) */492 o(0xa82ae42e); /* sd a1,8(sp) fsd fa0,16(sp) */
487 put_extern_sym(S, &label, cur_text_section, S->tccgen_ind, 0);493 put_extern_sym(&label, cur_text_section, ind, 0);
488 greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_RISCV_GOT_HI20, 0);494 greloca(cur_text_section, sym_data, ind, R_RISCV_GOT_HI20, 0);
489 o(S, 0x17 | (10 << 7)); // auipc a0, 0 %pcrel_hi(sym)+addend495 o(0x17 | (10 << 7)); // auipc a0, 0 %pcrel_hi(sym)+addend
490 greloca(S, cur_text_section, &label, S->tccgen_ind, R_RISCV_PCREL_LO12_I, 0);496 greloca(cur_text_section, &label, ind, R_RISCV_PCREL_LO12_I, 0);
491 EI(S, 0x03, 3, 10, 10, 0); // ld a0, 0(a0)497 EI(0x03, 3, 10, 10, 0); // ld a0, 0(a0)
492 gen_bounds_call(S, TOK___bound_local_delete);498 gen_bounds_call(TOK___bound_local_delete);
493 o(S, 0x65a26502); /* ld a0,0(sp) ld a1,8(sp) */499 o(0x65a26502); /* ld a0,0(sp) ld a1,8(sp) */
494 o(S, 0x61052542); /* fld fa0,16(sp) addi sp,sp,32 */500 o(0x61052542); /* fld fa0,16(sp) addi sp,sp,32 */
495}501}
496#endif502#endif
497 503
@@ -540,27 +546,27 @@ static void reg_pass(CType *type, int *prc, int *fieldofs, int named) · 42 unmodified lines
540 }546 }
541}547}
542 548
543ST_FUNC void gfunc_call(TCCState* S, int nb_args)549ST_FUNC void gfunc_call(int nb_args)
544{550{
545 int i, align, size, areg[2];551 int i, align, size, areg[2];
546 int *info = tcc_malloc(S, (nb_args + 1) * sizeof (int));552 int *info = tcc_malloc((nb_args + 1) * sizeof (int));
547 int stack_adj = 0, tempspace = 0, stack_add, ofs, splitofs = 0;553 int stack_adj = 0, tempspace = 0, stack_add, ofs, splitofs = 0;
548 SValue *sv;554 SValue *sv;
549 Sym *sa;555 Sym *sa;
550 556
551#ifdef CONFIG_TCC_BCHECK557#ifdef CONFIG_TCC_BCHECK
552 int bc_save = S->do_bounds_check;558 int bc_save = tcc_state->do_bounds_check;
553 if (S->do_bounds_check)559 if (tcc_state->do_bounds_check)
554 gbound_args(S, nb_args);560 gbound_args(nb_args);
555#endif561#endif
556 562
557 areg[0] = 0; /* int arg regs */563 areg[0] = 0; /* int arg regs */
558 areg[1] = 8; /* float arg regs */564 areg[1] = 8; /* float arg regs */
559 sa = S->tccgen_vtop[-nb_args].type.ref->next;565 sa = vtop[-nb_args].type.ref->next;
560 for (i = 0; i < nb_args; i++) {566 for (i = 0; i < nb_args; i++) {
561 int nregs, byref = 0, tempofs;567 int nregs, byref = 0, tempofs;
562 int prc[3], fieldofs[3];568 int prc[3], fieldofs[3];
563 sv = &S->tccgen_vtop[1 + i - nb_args];569 sv = &vtop[1 + i - nb_args];
564 sv->type.t &= ~VT_ARRAY; // XXX this should be done in tccgen.c570 sv->type.t &= ~VT_ARRAY; // XXX this should be done in tccgen.c
565 size = type_size(&sv->type, &align);571 size = type_size(&sv->type, &align);
566 if (size > 16) {572 if (size > 16) {
@@ -617,53 +623,53 @@ ST_FUNC void gfunc_call(TCCState* S, int nb_args) · 50 unmodified lines
617 stack_add = stack_adj + tempspace;623 stack_add = stack_adj + tempspace;
618 624
619 /* fetch cpu flag before generating any code */625 /* fetch cpu flag before generating any code */
620 if ((S->tccgen_vtop->r & VT_VALMASK) == VT_CMP)626 if ((vtop->r & VT_VALMASK) == VT_CMP)
621 gv(S, RC_INT);627 gv(RC_INT);
622 628
623 if (stack_add) {629 if (stack_add) {
624 if (stack_add >= 0x1000) {630 if (stack_add >= 0x1000) {
625 o(S, 0x37 | (5 << 7) | (-stack_add & 0xfffff000)); //lui t0, upper(v)631 o(0x37 | (5 << 7) | (-stack_add & 0xfffff000)); //lui t0, upper(v)
626 EI(S, 0x13, 0, 5, 5, -stack_add << 20 >> 20); // addi t0, t0, lo(v)632 EI(0x13, 0, 5, 5, -stack_add << 20 >> 20); // addi t0, t0, lo(v)
627 ER(S, 0x33, 0, 2, 2, 5, 0); // add sp, sp, t0633 ER(0x33, 0, 2, 2, 5, 0); // add sp, sp, t0
628 }634 }
629 else635 else
630 EI(S, 0x13, 0, 2, 2, -stack_add); // addi sp, sp, -adj636 EI(0x13, 0, 2, 2, -stack_add); // addi sp, sp, -adj
631 for (i = ofs = 0; i < nb_args; i++) {637 for (i = ofs = 0; i < nb_args; i++) {
632 if (info[i] & (64 | 32)) {638 if (info[i] & (64 | 32)) {
633 vrotb(S, nb_args - i);639 vrotb(nb_args - i);
634 size = type_size(&S->tccgen_vtop->type, &align);640 size = type_size(&vtop->type, &align);
635 if (info[i] & 64) {641 if (info[i] & 64) {
636 vset(S, &S->tccgen_char_pointer_type, TREG_SP, 0);642 vset(&char_pointer_type, TREG_SP, 0);
637 vpushi(S, stack_adj + (info[i] >> 7));643 vpushi(stack_adj + (info[i] >> 7));
638 gen_op(S, '+');644 gen_op('+');
639 vpushv(S, S->tccgen_vtop); // this replaces the old argument645 vpushv(vtop); // this replaces the old argument
640 vrott(S, 3);646 vrott(3);
641 indir(S);647 indir();
642 S->tccgen_vtop->type = S->tccgen_vtop[-1].type;648 vtop->type = vtop[-1].type;
643 vswap(S);649 vswap();
644 vstore(S);650 vstore();
645 vpop(S);651 vpop();
646 size = align = 8;652 size = align = 8;
647 }653 }
648 if (info[i] & 32) {654 if (info[i] & 32) {
649 if (align < XLEN)655 if (align < XLEN)
650 align = XLEN;656 align = XLEN;
651 /* Once we support offseted regs we can do this:657 /* Once we support offseted regs we can do this:
652 vset(S, &S->tccgen_vtop->type, TREG_SP | VT_LVAL, ofs);658 vset(&vtop->type, TREG_SP | VT_LVAL, ofs);
653 to construct the lvalue for the outgoing stack slot,659 to construct the lvalue for the outgoing stack slot,
654 until then we have to jump through hoops. */660 until then we have to jump through hoops. */
655 vset(S, &S->tccgen_char_pointer_type, TREG_SP, 0);661 vset(&char_pointer_type, TREG_SP, 0);
656 ofs = (ofs + align - 1) & -align;662 ofs = (ofs + align - 1) & -align;
657 vpushi(S, ofs);663 vpushi(ofs);
658 gen_op(S, '+');664 gen_op('+');
659 indir(S);665 indir();
660 S->tccgen_vtop->type = S->tccgen_vtop[-1].type;666 vtop->type = vtop[-1].type;
661 vswap(S);667 vswap();
662 vstore(S);668 vstore();
663 S->tccgen_vtop->r = S->tccgen_vtop->r2 = VT_CONST; // this arg is done669 vtop->r = vtop->r2 = VT_CONST; // this arg is done
664 ofs += size;670 ofs += size;
665 }671 }
666 vrott(S, nb_args - i);672 vrott(nb_args - i);
667 } else if (info[i] & 16) {673 } else if (info[i] & 16) {
668 assert(!splitofs);674 assert(!splitofs);
669 splitofs = ofs;675 splitofs = ofs;
@@ -679,12 +685,12 @@ ST_FUNC void gfunc_call(TCCState* S, int nb_args) · 9 unmodified lines
679 r &= 15;685 r &= 15;
680 r2 = r2 & 64 ? 0 : (r2 >> 7) & 31;686 r2 = r2 & 64 ? 0 : (r2 >> 7) & 31;
681 assert(r2 <= 16);687 assert(r2 <= 16);
682 vrotb(S, i+1);688 vrotb(i+1);
683 origtype = S->tccgen_vtop->type;689 origtype = vtop->type;
684 size = type_size(&S->tccgen_vtop->type, &align);690 size = type_size(&vtop->type, &align);
685 if (size == 0)691 if (size == 0)
686 goto done;692 goto done;
687 loadt = S->tccgen_vtop->type.t & VT_BTYPE;693 loadt = vtop->type.t & VT_BTYPE;
688 if (loadt == VT_STRUCT) {694 if (loadt == VT_STRUCT) {
689 loadt = (ii >> 12) & VT_BTYPE;695 loadt = (ii >> 12) & VT_BTYPE;
690 }696 }
@@ -696,74 +702,74 @@ ST_FUNC void gfunc_call(TCCState* S, int nb_args) · 5 unmodified lines
696 assert(r2);702 assert(r2);
697 r2--;703 r2--;
698 } else if (r2) {704 } else if (r2) {
699 test_lvalue(S);705 test_lvalue();
700 vpushv(S, S->tccgen_vtop);706 vpushv(vtop);
701 }707 }
702 S->tccgen_vtop->type.t = loadt | (S->tccgen_vtop->type.t & VT_UNSIGNED);708 vtop->type.t = loadt | (vtop->type.t & VT_UNSIGNED);
703 gv(S, r < 8 ? RC_R(r) : RC_F(r - 8));709 gv(r < 8 ? RC_R(r) : RC_F(r - 8));
704 S->tccgen_vtop->type = origtype;710 vtop->type = origtype;
705 711
706 if (r2 && loadt != VT_LDOUBLE) {712 if (r2 && loadt != VT_LDOUBLE) {
707 r2--;713 r2--;
708 assert(r2 < 16 || r2 == TREG_RA);714 assert(r2 < 16 || r2 == TREG_RA);
709 vswap(S);715 vswap();
710 gaddrof(S);716 gaddrof();
711 S->tccgen_vtop->type = S->tccgen_char_pointer_type;717 vtop->type = char_pointer_type;
712 vpushi(S, ii >> 20);718 vpushi(ii >> 20);
713#ifdef CONFIG_TCC_BCHECK719#ifdef CONFIG_TCC_BCHECK
714 if ((origtype.t & VT_BTYPE) == VT_STRUCT)720 if ((origtype.t & VT_BTYPE) == VT_STRUCT)
715 S->do_bounds_check = 0;721 tcc_state->do_bounds_check = 0;
716#endif722#endif
717 gen_op(S, '+');723 gen_op('+');
718#ifdef CONFIG_TCC_BCHECK724#ifdef CONFIG_TCC_BCHECK
719 S->do_bounds_check = bc_save;725 tcc_state->do_bounds_check = bc_save;
720#endif726#endif
721 indir(S);727 indir();
722 S->tccgen_vtop->type = origtype;728 vtop->type = origtype;
723 loadt = S->tccgen_vtop->type.t & VT_BTYPE;729 loadt = vtop->type.t & VT_BTYPE;
724 if (loadt == VT_STRUCT) {730 if (loadt == VT_STRUCT) {
725 loadt = (ii >> 16) & VT_BTYPE;731 loadt = (ii >> 16) & VT_BTYPE;
726 }732 }
727 save_reg_upstack(S, r2, 1);733 save_reg_upstack(r2, 1);
728 S->tccgen_vtop->type.t = loadt | (S->tccgen_vtop->type.t & VT_UNSIGNED);734 vtop->type.t = loadt | (vtop->type.t & VT_UNSIGNED);
729 load(S, r2, S->tccgen_vtop);735 load(r2, vtop);
730 assert(r2 < VT_CONST);736 assert(r2 < VT_CONST);
731 S->tccgen_vtop--;737 vtop--;
732 S->tccgen_vtop->r2 = r2;738 vtop->r2 = r2;
733 }739 }
734 if (info[nb_args - 1 - i] & 16) {740 if (info[nb_args - 1 - i] & 16) {
735 ES(S, 0x23, 3, 2, ireg(S->tccgen_vtop->r2), splitofs); // sd t0, ofs(sp)741 ES(0x23, 3, 2, ireg(vtop->r2), splitofs); // sd t0, ofs(sp)
736 S->tccgen_vtop->r2 = VT_CONST;742 vtop->r2 = VT_CONST;
737 } else if (loadt == VT_LDOUBLE && S->tccgen_vtop->r2 != r2) {743 } else if (loadt == VT_LDOUBLE && vtop->r2 != r2) {
738 assert(S->tccgen_vtop->r2 <= 7 && r2 <= 7);744 assert(vtop->r2 <= 7 && r2 <= 7);
739 /* XXX we'd like to have 'gv' move directly into745 /* XXX we'd like to have 'gv' move directly into
740 the right class instead of us fixing it up. */746 the right class instead of us fixing it up. */
741 EI(S, 0x13, 0, ireg(r2), ireg(S->tccgen_vtop->r2), 0); // mv Ra+1, RR2747 EI(0x13, 0, ireg(r2), ireg(vtop->r2), 0); // mv Ra+1, RR2
742 S->tccgen_vtop->r2 = r2;748 vtop->r2 = r2;
743 }749 }
744done:750done:
745 vrott(S, i+1);751 vrott(i+1);
746 }752 }
747 }753 }
748 vrotb(S, nb_args + 1);754 vrotb(nb_args + 1);
749 save_regs(S, nb_args + 1);755 save_regs(nb_args + 1);
750 gcall_or_jmp(S, 1);756 gcall_or_jmp(1);
751 S->tccgen_vtop -= nb_args + 1;757 vtop -= nb_args + 1;
752 if (stack_add) {758 if (stack_add) {
753 if (stack_add >= 0x1000) {759 if (stack_add >= 0x1000) {
754 o(S, 0x37 | (5 << 7) | (stack_add & 0xfffff000)); //lui t0, upper(v)760 o(0x37 | (5 << 7) | (stack_add & 0xfffff000)); //lui t0, upper(v)
755 EI(S, 0x13, 0, 5, 5, stack_add << 20 >> 20); // addi t0, t0, lo(v)761 EI(0x13, 0, 5, 5, stack_add << 20 >> 20); // addi t0, t0, lo(v)
756 ER(S, 0x33, 0, 2, 2, 5, 0); // add sp, sp, t0762 ER(0x33, 0, 2, 2, 5, 0); // add sp, sp, t0
757 }763 }
758 else764 else
759 EI(S, 0x13, 0, 2, 2, stack_add); // addi sp, sp, adj765 EI(0x13, 0, 2, 2, stack_add); // addi sp, sp, adj
760 }766 }
761 tcc_free(S, info);767 tcc_free(info);
762}768}
763 769
764static int func_sub_sp_offset, num_va_regs, func_va_list_ofs;770static int func_sub_sp_offset, num_va_regs, func_va_list_ofs;
765 771
766ST_FUNC void gfunc_prolog(TCCState* S, Sym *func_sym)772ST_FUNC void gfunc_prolog(Sym *func_sym)
767{773{
768 CType *func_type = &func_sym->type;774 CType *func_type = &func_sym->type;
769 int i, addr, align, size;775 int i, addr, align, size;
@@ -773,19 +779,19 @@ ST_FUNC void gfunc_prolog(TCCState* S, Sym *func_sym) · 3 unmodified lines
773 CType *type;779 CType *type;
774 780
775 sym = func_type->ref;781 sym = func_type->ref;
776 S->tccgen_loc = -16; // for ra and s0782 loc = -16; // for ra and s0
777 func_sub_sp_offset = S->tccgen_ind;783 func_sub_sp_offset = ind;
778 S->tccgen_ind += 5 * 4;784 ind += 5 * 4;
779 785
780 areg[0] = 0, areg[1] = 0;786 areg[0] = 0, areg[1] = 0;
781 addr = 0;787 addr = 0;
782 /* if the function returns by reference, then add an788 /* if the function returns by reference, then add an
783 implicit pointer parameter */789 implicit pointer parameter */
784 size = type_size(&S->tccgen_func_vt, &align);790 size = type_size(&func_vt, &align);
785 if (size > 2 * XLEN) {791 if (size > 2 * XLEN) {
786 S->tccgen_loc -= 8;792 loc -= 8;
787 S->tccgen_func_vc = S->tccgen_loc;793 func_vc = loc;
788 ES(S, 0x23, 3, 8, 10 + areg[0]++, S->tccgen_loc); // sd a0, loc(s0)794 ES(0x23, 3, 8, 10 + areg[0]++, loc); // sd a0, loc(s0)
789 }795 }
790 /* define parameters */796 /* define parameters */
791 while ((sym = sym->next) != NULL) {797 while ((sym = sym->next) != NULL) {
@@ -795,7 +801,7 @@ ST_FUNC void gfunc_prolog(TCCState* S, Sym *func_sym) · 3 unmodified lines
795 type = &sym->type;801 type = &sym->type;
796 size = type_size(type, &align);802 size = type_size(type, &align);
797 if (size > 2 * XLEN) {803 if (size > 2 * XLEN) {
798 type = &S->tccgen_char_pointer_type;804 type = &char_pointer_type;
799 size = align = byref = 8;805 size = align = byref = 8;
800 }806 }
801 reg_pass(type, prc, fieldofs, 1);807 reg_pass(type, prc, fieldofs, 1);
@@ -810,36 +816,36 @@ ST_FUNC void gfunc_prolog(TCCState* S, Sym *func_sym) · 8 unmodified lines
810 param_addr = addr;816 param_addr = addr;
811 addr += size;817 addr += size;
812 } else {818 } else {
813 S->tccgen_loc -= regcount * 8; // XXX could reserve only 'size' bytes819 loc -= regcount * 8; // XXX could reserve only 'size' bytes
814 param_addr = S->tccgen_loc;820 param_addr = loc;
815 for (i = 0; i < regcount; i++) {821 for (i = 0; i < regcount; i++) {
816 if (areg[prc[1+i] - 1] >= 8) {822 if (areg[prc[1+i] - 1] >= 8) {
817 assert(i == 1 && regcount == 2 && !(addr & 7));823 assert(i == 1 && regcount == 2 && !(addr & 7));
818 EI(S, 0x03, 3, 5, 8, addr); // ld t0, addr(s0)824 EI(0x03, 3, 5, 8, addr); // ld t0, addr(s0)
819 addr += 8;825 addr += 8;
820 ES(S, 0x23, 3, 8, 5, S->tccgen_loc + i*8); // sd t0, loc(s0)826 ES(0x23, 3, 8, 5, loc + i*8); // sd t0, loc(s0)
821 } else if (prc[1+i] == RC_FLOAT) {827 } else if (prc[1+i] == RC_FLOAT) {
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)828 ES(0x27, (size / regcount) == 4 ? 2 : 3, 8, 10 + areg[1]++, loc + (fieldofs[i+1] >> 4)); // fs[wd] FAi, loc(s0)
823 } else {829 } else {
824 ES(S, 0x23, 3, 8, 10 + areg[0]++, S->tccgen_loc + i*8); // sd aX, loc(s0) // XXX830 ES(0x23, 3, 8, 10 + areg[0]++, loc + i*8); // sd aX, loc(s0) // XXX
825 }831 }
826 }832 }
827 }833 }
828 sym_push(S, sym->v & ~SYM_FIELD, &sym->type,834 sym_push(sym->v & ~SYM_FIELD, &sym->type,
829 (byref ? VT_LLOCAL : VT_LOCAL) | VT_LVAL,835 (byref ? VT_LLOCAL : VT_LOCAL) | VT_LVAL,
830 param_addr);836 param_addr);
831 }837 }
832 func_va_list_ofs = addr;838 func_va_list_ofs = addr;
833 num_va_regs = 0;839 num_va_regs = 0;
834 if (S->tccgen_func_var) {840 if (func_var) {
835 for (; areg[0] < 8; areg[0]++) {841 for (; areg[0] < 8; areg[0]++) {
836 num_va_regs++;842 num_va_regs++;
837 ES(S, 0x23, 3, 8, 10 + areg[0], -8 + num_va_regs * 8); // sd aX, loc(s0)843 ES(0x23, 3, 8, 10 + areg[0], -8 + num_va_regs * 8); // sd aX, loc(s0)
838 }844 }
839 }845 }
840#ifdef CONFIG_TCC_BCHECK846#ifdef CONFIG_TCC_BCHECK
841 if (S->do_bounds_check)847 if (tcc_state->do_bounds_check)
842 gen_bounds_prolog(S);848 gen_bounds_prolog();
843#endif849#endif
844}850}
845 851
@@ -864,113 +870,113 @@ ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, · 18 unmodified lines
864 return nregs;870 return nregs;
865}871}
866 872
867ST_FUNC void arch_transfer_ret_regs(TCCState* S, int aftercall)873ST_FUNC void arch_transfer_ret_regs(int aftercall)
868{874{
869 int prc[3], fieldofs[3];875 int prc[3], fieldofs[3];
870 reg_pass(&S->tccgen_vtop->type, prc, fieldofs, 1);876 reg_pass(&vtop->type, prc, fieldofs, 1);
871 assert(prc[0] == 2 && prc[1] != prc[2] && !(fieldofs[1] >> 4));877 assert(prc[0] == 2 && prc[1] != prc[2] && !(fieldofs[1] >> 4));
872 assert(S->tccgen_vtop->r == (VT_LOCAL | VT_LVAL));878 assert(vtop->r == (VT_LOCAL | VT_LVAL));
873 vpushv(S, S->tccgen_vtop);879 vpushv(vtop);
874 S->tccgen_vtop->type.t = fieldofs[1] & VT_BTYPE;880 vtop->type.t = fieldofs[1] & VT_BTYPE;
875 (aftercall ? store : load)(S, prc[1] == RC_INT ? REG_IRET : REG_FRET, S->tccgen_vtop);881 (aftercall ? store : load)(prc[1] == RC_INT ? REG_IRET : REG_FRET, vtop);
876 S->tccgen_vtop->c.i += fieldofs[2] >> 4;882 vtop->c.i += fieldofs[2] >> 4;
877 S->tccgen_vtop->type.t = fieldofs[2] & VT_BTYPE;883 vtop->type.t = fieldofs[2] & VT_BTYPE;
878 (aftercall ? store : load)(S, prc[2] == RC_INT ? REG_IRET : REG_FRET, S->tccgen_vtop);884 (aftercall ? store : load)(prc[2] == RC_INT ? REG_IRET : REG_FRET, vtop);
879 S->tccgen_vtop--;885 vtop--;
880}886}
881 887
882ST_FUNC void gfunc_epilog(TCCState* S)888ST_FUNC void gfunc_epilog(void)
883{889{
884 int v, saved_ind, d, large_ofs_ind;890 int v, saved_ind, d, large_ofs_ind;
885 891
886#ifdef CONFIG_TCC_BCHECK892#ifdef CONFIG_TCC_BCHECK
887 if (S->do_bounds_check)893 if (tcc_state->do_bounds_check)
888 gen_bounds_epilog(S);894 gen_bounds_epilog();
889#endif895#endif
890 896
891 S->tccgen_loc = (S->tccgen_loc - num_va_regs * 8);897 loc = (loc - num_va_regs * 8);
892 d = v = (-S->tccgen_loc + 15) & -16;898 d = v = (-loc + 15) & -16;
893 899
894 if (v >= (1 << 11)) {900 if (v >= (1 << 11)) {
895 d = 16;901 d = 16;
896 o(S, 0x37 | (5 << 7) | ((0x800 + (v-16)) & 0xfffff000)); //lui t0, upper(v)902 o(0x37 | (5 << 7) | ((0x800 + (v-16)) & 0xfffff000)); //lui t0, upper(v)
897 EI(S, 0x13, 0, 5, 5, (v-16) << 20 >> 20); // addi t0, t0, lo(v)903 EI(0x13, 0, 5, 5, (v-16) << 20 >> 20); // addi t0, t0, lo(v)
898 ER(S, 0x33, 0, 2, 2, 5, 0); // add sp, sp, t0904 ER(0x33, 0, 2, 2, 5, 0); // add sp, sp, t0
899 }905 }
900 EI(S, 0x03, 3, 1, 2, d - 8 - num_va_regs * 8); // ld ra, v-8(sp)906 EI(0x03, 3, 1, 2, d - 8 - num_va_regs * 8); // ld ra, v-8(sp)
901 EI(S, 0x03, 3, 8, 2, d - 16 - num_va_regs * 8); // ld s0, v-16(sp)907 EI(0x03, 3, 8, 2, d - 16 - num_va_regs * 8); // ld s0, v-16(sp)
902 EI(S, 0x13, 0, 2, 2, d); // addi sp, sp, v908 EI(0x13, 0, 2, 2, d); // addi sp, sp, v
903 EI(S, 0x67, 0, 0, 1, 0); // jalr x0, 0(x1), aka ret909 EI(0x67, 0, 0, 1, 0); // jalr x0, 0(x1), aka ret
904 large_ofs_ind = S->tccgen_ind;910 large_ofs_ind = ind;
905 if (v >= (1 << 11)) {911 if (v >= (1 << 11)) {
906 EI(S, 0x13, 0, 8, 2, d - num_va_regs * 8); // addi s0, sp, d912 EI(0x13, 0, 8, 2, d - num_va_regs * 8); // addi s0, sp, d
907 o(S, 0x37 | (5 << 7) | ((0x800 + (v-16)) & 0xfffff000)); //lui t0, upper(v)913 o(0x37 | (5 << 7) | ((0x800 + (v-16)) & 0xfffff000)); //lui t0, upper(v)
908 EI(S, 0x13, 0, 5, 5, (v-16) << 20 >> 20); // addi t0, t0, lo(v)914 EI(0x13, 0, 5, 5, (v-16) << 20 >> 20); // addi t0, t0, lo(v)
909 ER(S, 0x33, 0, 2, 2, 5, 0x20); // sub sp, sp, t0915 ER(0x33, 0, 2, 2, 5, 0x20); // sub sp, sp, t0
910 gjmp_addr(S, func_sub_sp_offset + 5*4);916 gjmp_addr(func_sub_sp_offset + 5*4);
911 }917 }
912 saved_ind = S->tccgen_ind;918 saved_ind = ind;
913 919
914 S->tccgen_ind = func_sub_sp_offset;920 ind = func_sub_sp_offset;
915 EI(S, 0x13, 0, 2, 2, -d); // addi sp, sp, -d921 EI(0x13, 0, 2, 2, -d); // addi sp, sp, -d
916 ES(S, 0x23, 3, 2, 1, d - 8 - num_va_regs * 8); // sd ra, d-8(sp)922 ES(0x23, 3, 2, 1, d - 8 - num_va_regs * 8); // sd ra, d-8(sp)
917 ES(S, 0x23, 3, 2, 8, d - 16 - num_va_regs * 8); // sd s0, d-16(sp)923 ES(0x23, 3, 2, 8, d - 16 - num_va_regs * 8); // sd s0, d-16(sp)
918 if (v < (1 << 11))924 if (v < (1 << 11))
919 EI(S, 0x13, 0, 8, 2, d - num_va_regs * 8); // addi s0, sp, d925 EI(0x13, 0, 8, 2, d - num_va_regs * 8); // addi s0, sp, d
920 else926 else
921 gjmp_addr(S, large_ofs_ind);927 gjmp_addr(large_ofs_ind);
922 if ((S->tccgen_ind - func_sub_sp_offset) != 5*4)928 if ((ind - func_sub_sp_offset) != 5*4)
923 EI(S, 0x13, 0, 0, 0, 0); // addi x0, x0, 0 == nop929 EI(0x13, 0, 0, 0, 0); // addi x0, x0, 0 == nop
924 S->tccgen_ind = saved_ind;930 ind = saved_ind;
925}931}
926 932
927ST_FUNC void gen_va_start(TCCState *S)933ST_FUNC void gen_va_start(void)
928{934{
929 S->tccgen_vtop--;935 vtop--;
930 vset(S, &S->tccgen_char_pointer_type, VT_LOCAL, func_va_list_ofs);936 vset(&char_pointer_type, VT_LOCAL, func_va_list_ofs);
931}937}
932 938
933ST_FUNC void gen_fill_nops(TCCState* S, int bytes)939ST_FUNC void gen_fill_nops(int bytes)
934{940{
935 if ((bytes & 3))941 if ((bytes & 3))
936 tcc_error(S, "alignment of code section not multiple of 4");942 tcc_error("alignment of code section not multiple of 4");
937 while (bytes > 0) {943 while (bytes > 0) {
938 EI(S, 0x13, 0, 0, 0, 0); // addi x0, x0, 0 == nop944 EI(0x13, 0, 0, 0, 0); // addi x0, x0, 0 == nop
939 bytes -= 4;945 bytes -= 4;
940 }946 }
941}947}
942 948
943// Generate forward branch to label:949// Generate forward branch to label:
944ST_FUNC int gjmp(TCCState* S, int t)950ST_FUNC int gjmp(int t)
945{951{
946 if (S->tccgen_nocode_wanted)952 if (nocode_wanted)
947 return t;953 return t;
948 o(S, t);954 o(t);
949 return S->tccgen_ind - 4;955 return ind - 4;
950}956}
951 957
952// Generate branch to known address:958// Generate branch to known address:
953ST_FUNC void gjmp_addr(TCCState* S, int a)959ST_FUNC void gjmp_addr(int a)
954{960{
955 uint32_t r = a - S->tccgen_ind, imm;961 uint32_t r = a - ind, imm;
956 if ((r + (1 << 21)) & ~((1U << 22) - 2)) {962 if ((r + (1 << 21)) & ~((1U << 22) - 2)) {
957 o(S, 0x17 | (5 << 7) | (((r + 0x800) & 0xfffff000))); // lui RR, up(r)963 o(0x17 | (5 << 7) | (((r + 0x800) & 0xfffff000))); // lui RR, up(r)
958 r = (int)r << 20 >> 20;964 r = (int)r << 20 >> 20;
959 EI(S, 0x67, 0, 0, 5, r); // jalr x0, r(t0)965 EI(0x67, 0, 0, 5, r); // jalr x0, r(t0)
960 } else {966 } else {
961 imm = (((r >> 12) & 0xff) << 12)967 imm = (((r >> 12) & 0xff) << 12)
962 | (((r >> 11) & 1) << 20)968 | (((r >> 11) & 1) << 20)
963 | (((r >> 1) & 0x3ff) << 21)969 | (((r >> 1) & 0x3ff) << 21)
964 | (((r >> 20) & 1) << 31);970 | (((r >> 20) & 1) << 31);
965 o(S, 0x6f | imm); // jal x0, imm == j imm971 o(0x6f | imm); // jal x0, imm == j imm
966 }972 }
967}973}
968 974
969ST_FUNC int gjmp_cond(TCCState* S, int op, int t)975ST_FUNC int gjmp_cond(int op, int t)
970{976{
971 int tmp;977 int tmp;
972 int a = S->tccgen_vtop->cmp_r & 0xff;978 int a = vtop->cmp_r & 0xff;
973 int b = (S->tccgen_vtop->cmp_r >> 8) & 0xff;979 int b = (vtop->cmp_r >> 8) & 0xff;
974 switch (op) {980 switch (op) {
975 case TOK_ULT: op = 6; break;981 case TOK_ULT: op = 6; break;
976 case TOK_UGE: op = 7; break;982 case TOK_UGE: op = 7; break;
@@ -983,11 +989,11 @@ ST_FUNC int gjmp_cond(TCCState* S, int op, int t) · 6 unmodified lines
983 case TOK_NE: op = 1; break;989 case TOK_NE: op = 1; break;
984 case TOK_EQ: op = 0; break;990 case TOK_EQ: op = 0; break;
985 }991 }
986 o(S, 0x63 | (op ^ 1) << 12 | a << 15 | b << 20 | 8 << 7); // bOP a,b,+4992 o(0x63 | (op ^ 1) << 12 | a << 15 | b << 20 | 8 << 7); // bOP a,b,+4
987 return gjmp(S, t);993 return gjmp(t);
988}994}
989 995
990ST_FUNC int gjmp_append(TCCState* S, int n, int t)996ST_FUNC int gjmp_append(int n, int t)
991{997{
992 void *p;998 void *p;
993 /* insert jump list n into t */999 /* insert jump list n into t */
@@ -1001,23 +1007,23 @@ ST_FUNC int gjmp_append(TCCState* S, int n, int t) · 7 unmodified lines
1001 return t;1007 return t;
1002}1008}
1003 1009
1004static void gen_opil(TCCState* S, int op, int ll)1010static void gen_opil(int op, int ll)
1005{1011{
1006 int a, b, d;1012 int a, b, d;
1007 int func3 = 0;1013 int func3 = 0;
1008 ll = ll ? 0 : 8;1014 ll = ll ? 0 : 8;
1009 if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {1015 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
1010 int fc = S->tccgen_vtop->c.i;1016 int fc = vtop->c.i;
1011 if (fc == S->tccgen_vtop->c.i && !(((unsigned)fc + (1 << 11)) >> 12)) {1017 if (fc == vtop->c.i && !(((unsigned)fc + (1 << 11)) >> 12)) {
1012 int cll = 0;1018 int cll = 0;
1013 int m = ll ? 31 : 63;1019 int m = ll ? 31 : 63;
1014 vswap(S);1020 vswap();
1015 gv(S, RC_INT);1021 gv(RC_INT);
1016 a = ireg(S->tccgen_vtop[0].r);1022 a = ireg(vtop[0].r);
1017 --S->tccgen_vtop;1023 --vtop;
1018 d = get_reg(S, RC_INT);1024 d = get_reg(RC_INT);
1019 ++S->tccgen_vtop;1025 ++vtop;
1020 vswap(S);1026 vswap();
1021 switch (op) {1027 switch (op) {
1022 case '-':1028 case '-':
1023 if (fc <= -(1 << 11))1029 if (fc <= -(1 << 11))
@@ -1027,13 +1033,13 @@ static void gen_opil(TCCState* S, int op, int ll) · 3 unmodified lines
1027 func3 = 0; // addi d, a, fc1033 func3 = 0; // addi d, a, fc
1028 cll = ll;1034 cll = ll;
1029 do_cop:1035 do_cop:
1030 EI(S, 0x13 | cll, func3, ireg(d), a, fc);1036 EI(0x13 | cll, func3, ireg(d), a, fc);
1031 --S->tccgen_vtop;1037 --vtop;
1032 if (op >= TOK_ULT && op <= TOK_GT) {1038 if (op >= TOK_ULT && op <= TOK_GT) {
1033 vset_VT_CMP(S, TOK_NE);1039 vset_VT_CMP(TOK_NE);
1034 S->tccgen_vtop->cmp_r = ireg(d) | 0 << 8;1040 vtop->cmp_r = ireg(d) | 0 << 8;
1035 } else1041 } else
1036 S->tccgen_vtop[0].r = d;1042 vtop[0].r = d;
1037 return;1043 return;
1038 case TOK_LE:1044 case TOK_LE:
1039 if (fc >= (1 << 11) - 1)1045 if (fc >= (1 << 11) - 1)
@@ -1056,97 +1062,97 @@ static void gen_opil(TCCState* S, int op, int ll) · 16 unmodified lines
1056 case TOK_UGT: /* -> TOK_ULE */1062 case TOK_UGT: /* -> TOK_ULE */
1057 case TOK_GE: /* -> TOK_LT */1063 case TOK_GE: /* -> TOK_LT */
1058 case TOK_GT: /* -> TOK_LE */1064 case TOK_GT: /* -> TOK_LE */
1059 gen_opil(S, op - 1, !ll);1065 gen_opil(op - 1, !ll);
1060 S->tccgen_vtop->cmp_op ^= 1;1066 vtop->cmp_op ^= 1;
1061 return;1067 return;
1062 1068
1063 case TOK_NE:1069 case TOK_NE:
1064 case TOK_EQ:1070 case TOK_EQ:
1065 if (fc)1071 if (fc)
1066 gen_opil(S, '-', !ll), a = ireg(S->tccgen_vtop++->r);1072 gen_opil('-', !ll), a = ireg(vtop++->r);
1067 --S->tccgen_vtop;1073 --vtop;
1068 vset_VT_CMP(S, op);1074 vset_VT_CMP(op);
1069 S->tccgen_vtop->cmp_r = a | 0 << 8;1075 vtop->cmp_r = a | 0 << 8;
1070 return;1076 return;
1071 }1077 }
1072 }1078 }
1073 }1079 }
1074 gv2(S, RC_INT, RC_INT);1080 gv2(RC_INT, RC_INT);
1075 a = ireg(S->tccgen_vtop[-1].r);1081 a = ireg(vtop[-1].r);
1076 b = ireg(S->tccgen_vtop[0].r);1082 b = ireg(vtop[0].r);
1077 S->tccgen_vtop -= 2;1083 vtop -= 2;
1078 d = get_reg(S, RC_INT);1084 d = get_reg(RC_INT);
1079 S->tccgen_vtop++;1085 vtop++;
1080 S->tccgen_vtop[0].r = d;1086 vtop[0].r = d;
1081 d = ireg(d);1087 d = ireg(d);
1082 switch (op) {1088 switch (op) {
1083 default:1089 default:
1084 if (op >= TOK_ULT && op <= TOK_GT) {1090 if (op >= TOK_ULT && op <= TOK_GT) {
1085 vset_VT_CMP(S, op);1091 vset_VT_CMP(op);
1086 S->tccgen_vtop->cmp_r = a | b << 8;1092 vtop->cmp_r = a | b << 8;
1087 break;1093 break;
1088 }1094 }
1089 tcc_error(S, "implement me: %s(%s)", __FUNCTION__, get_tok_str(S, op, NULL));1095 tcc_error("implement me: %s(%s)", __FUNCTION__, get_tok_str(op, NULL));
1090 break;1096 break;
1091 1097
1092 case '+':1098 case '+':
1093 ER(S, 0x33 | ll, 0, d, a, b, 0); // add d, a, b1099 ER(0x33 | ll, 0, d, a, b, 0); // add d, a, b
1094 break;1100 break;
1095 case '-':1101 case '-':
1096 ER(S, 0x33 | ll, 0, d, a, b, 0x20); // sub d, a, b1102 ER(0x33 | ll, 0, d, a, b, 0x20); // sub d, a, b
1097 break;1103 break;
1098 case TOK_SAR:1104 case TOK_SAR:
1099 ER(S, 0x33 | ll | ll, 5, d, a, b, 0x20); // sra d, a, b1105 ER(0x33 | ll | ll, 5, d, a, b, 0x20); // sra d, a, b
1100 break;1106 break;
1101 case TOK_SHR:1107 case TOK_SHR:
1102 ER(S, 0x33 | ll | ll, 5, d, a, b, 0); // srl d, a, b1108 ER(0x33 | ll | ll, 5, d, a, b, 0); // srl d, a, b
1103 break;1109 break;
1104 case TOK_SHL:1110 case TOK_SHL:
1105 ER(S, 0x33 | ll, 1, d, a, b, 0); // sll d, a, b1111 ER(0x33 | ll, 1, d, a, b, 0); // sll d, a, b
1106 break;1112 break;
1107 case '*':1113 case '*':
1108 ER(S, 0x33 | ll, 0, d, a, b, 1); // mul d, a, b1114 ER(0x33 | ll, 0, d, a, b, 1); // mul d, a, b
1109 break;1115 break;
1110 case '/':1116 case '/':
1111 ER(S, 0x33 | ll, 4, d, a, b, 1); // div d, a, b1117 ER(0x33 | ll, 4, d, a, b, 1); // div d, a, b
1112 break;1118 break;
1113 case '&':1119 case '&':
1114 ER(S, 0x33, 7, d, a, b, 0); // and d, a, b1120 ER(0x33, 7, d, a, b, 0); // and d, a, b
1115 break;1121 break;
1116 case '^':1122 case '^':
1117 ER(S, 0x33, 4, d, a, b, 0); // xor d, a, b1123 ER(0x33, 4, d, a, b, 0); // xor d, a, b
1118 break;1124 break;
1119 case '|':1125 case '|':
1120 ER(S, 0x33, 6, d, a, b, 0); // or d, a, b1126 ER(0x33, 6, d, a, b, 0); // or d, a, b
1121 break;1127 break;
1122 case '%':1128 case '%':
1123 ER(S, ll ? 0x3b: 0x33, 6, d, a, b, 1); // rem d, a, b1129 ER(ll ? 0x3b: 0x33, 6, d, a, b, 1); // rem d, a, b
1124 break;1130 break;
1125 case TOK_UMOD:1131 case TOK_UMOD:
1126 ER(S, 0x33 | ll, 7, d, a, b, 1); // remu d, a, b1132 ER(0x33 | ll, 7, d, a, b, 1); // remu d, a, b
1127 break;1133 break;
1128 case TOK_PDIV:1134 case TOK_PDIV:
1129 case TOK_UDIV:1135 case TOK_UDIV:
1130 ER(S, 0x33 | ll, 5, d, a, b, 1); // divu d, a, b1136 ER(0x33 | ll, 5, d, a, b, 1); // divu d, a, b
1131 break;1137 break;
1132 }1138 }
1133}1139}
1134 1140
1135ST_FUNC void gen_opi(TCCState* S, int op)1141ST_FUNC void gen_opi(int op)
1136{1142{
1137 gen_opil(S, op, 0);1143 gen_opil(op, 0);
1138}1144}
1139 1145
1140ST_FUNC void gen_opl(TCCState* S, int op)1146ST_FUNC void gen_opl(int op)
1141{1147{
1142 gen_opil(S, op, 1);1148 gen_opil(op, 1);
1143}1149}
1144 1150
1145ST_FUNC void gen_opf(TCCState* S, int op)1151ST_FUNC void gen_opf(int op)
1146{1152{
1147 int rs1, rs2, rd, dbl, invert;1153 int rs1, rs2, rd, dbl, invert;
1148 if (S->tccgen_vtop[0].type.t == VT_LDOUBLE) {1154 if (vtop[0].type.t == VT_LDOUBLE) {
1149 CType type = S->tccgen_vtop[0].type;1155 CType type = vtop[0].type;
1150 int func = 0;1156 int func = 0;
1151 int cond = -1;1157 int cond = -1;
1152 switch (op) {1158 switch (op) {
@@ -1162,27 +1168,27 @@ ST_FUNC void gen_opf(TCCState* S, int op) · 9 unmodified lines
1162 case TOK_GT: func = TOK___gttf2; cond = 13; break;1168 case TOK_GT: func = TOK___gttf2; cond = 13; break;
1163 default: assert(0); break;1169 default: assert(0); break;
1164 }1170 }
1165 vpush_helper_func(S, func);1171 vpush_helper_func(func);
1166 vrott(S, 3);1172 vrott(3);
1167 gfunc_call(S, 2);1173 gfunc_call(2);
1168 vpushi(S, 0);1174 vpushi(0);
1169 S->tccgen_vtop->r = REG_IRET;1175 vtop->r = REG_IRET;
1170 S->tccgen_vtop->r2 = cond < 0 ? TREG_R(1) : VT_CONST;1176 vtop->r2 = cond < 0 ? TREG_R(1) : VT_CONST;
1171 if (cond < 0)1177 if (cond < 0)
1172 S->tccgen_vtop->type = type;1178 vtop->type = type;
1173 else {1179 else {
1174 vpushi(S, 0);1180 vpushi(0);
1175 gen_opil(S, op, 1);1181 gen_opil(op, 1);
1176 }1182 }
1177 return;1183 return;
1178 }1184 }
1179 1185
1180 gv2(S, RC_FLOAT, RC_FLOAT);1186 gv2(RC_FLOAT, RC_FLOAT);
1181 assert(S->tccgen_vtop->type.t == VT_DOUBLE || S->tccgen_vtop->type.t == VT_FLOAT);1187 assert(vtop->type.t == VT_DOUBLE || vtop->type.t == VT_FLOAT);
1182 dbl = S->tccgen_vtop->type.t == VT_DOUBLE;1188 dbl = vtop->type.t == VT_DOUBLE;
1183 rs1 = freg(S->tccgen_vtop[-1].r);1189 rs1 = freg(vtop[-1].r);
1184 rs2 = freg(S->tccgen_vtop->r);1190 rs2 = freg(vtop->r);
1185 S->tccgen_vtop--;1191 vtop--;
1186 invert = 0;1192 invert = 0;
1187 switch(op) {1193 switch(op) {
1188 default:1194 default:
@@ -1190,10 +1196,10 @@ ST_FUNC void gen_opf(TCCState* S, int op) · 1 unmodified line
1190 case '+':1196 case '+':
1191 op = 0; // fadd1197 op = 0; // fadd
1192 arithop:1198 arithop:
1193 rd = get_reg(S, RC_FLOAT);1199 rd = get_reg(RC_FLOAT);
1194 S->tccgen_vtop->r = rd;1200 vtop->r = rd;
1195 rd = freg(rd);1201 rd = freg(rd);
1196 ER(S, 0x53, 7, rd, rs1, rs2, dbl | (op << 2)); // fop.[sd] RD, RS1, RS2 (dyn rm)1202 ER(0x53, 7, rd, rs1, rs2, dbl | (op << 2)); // fop.[sd] RD, RS1, RS2 (dyn rm)
1197 break;1203 break;
1198 case '-':1204 case '-':
1199 op = 1; // fsub1205 op = 1; // fsub
@@ -1207,12 +1213,12 @@ ST_FUNC void gen_opf(TCCState* S, int op) · 7 unmodified lines
1207 case TOK_EQ:1213 case TOK_EQ:
1208 op = 2; // EQ1214 op = 2; // EQ
1209 cmpop:1215 cmpop:
1210 rd = get_reg(S, RC_INT);1216 rd = get_reg(RC_INT);
1211 S->tccgen_vtop->r = rd;1217 vtop->r = rd;
1212 rd = ireg(rd);1218 rd = ireg(rd);
1213 ER(S, 0x53, op, rd, rs1, rs2, dbl | 0x50); // fcmp.[sd] RD, RS1, RS2 (op == eq/lt/le)1219 ER(0x53, op, rd, rs1, rs2, dbl | 0x50); // fcmp.[sd] RD, RS1, RS2 (op == eq/lt/le)
1214 if (invert)1220 if (invert)
1215 EI(S, 0x13, 4, rd, rd, 1); // xori RD, 11221 EI(0x13, 4, rd, rd, 1); // xori RD, 1
1216 break;1222 break;
1217 case TOK_NE:1223 case TOK_NE:
1218 invert = 1;1224 invert = 1;
@@ -1235,67 +1241,67 @@ ST_FUNC void gen_opf(TCCState* S, int op) · 16 unmodified lines
1235 }1241 }
1236}1242}
1237 1243
1238ST_FUNC void gen_cvt_sxtw(TCCState *S)1244ST_FUNC void gen_cvt_sxtw(void)
1239{1245{
1240 /* XXX on risc-v the registers are usually sign-extended already.1246 /* XXX on risc-v the registers are usually sign-extended already.
1241 Let's try to not do anything here. */1247 Let's try to not do anything here. */
1242}1248}
1243 1249
1244ST_FUNC void gen_cvt_itof(TCCState* S, int t)1250ST_FUNC void gen_cvt_itof(int t)
1245{1251{
1246 int rr = ireg(gv(S, RC_INT)), dr;1252 int rr = ireg(gv(RC_INT)), dr;
1247 int u = S->tccgen_vtop->type.t & VT_UNSIGNED;1253 int u = vtop->type.t & VT_UNSIGNED;
1248 int l = (S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG;1254 int l = (vtop->type.t & VT_BTYPE) == VT_LLONG;
1249 if (t == VT_LDOUBLE) {1255 if (t == VT_LDOUBLE) {
1250 int func = l ?1256 int func = l ?
1251 (u ? TOK___floatunditf : TOK___floatditf) :1257 (u ? TOK___floatunditf : TOK___floatditf) :
1252 (u ? TOK___floatunsitf : TOK___floatsitf);1258 (u ? TOK___floatunsitf : TOK___floatsitf);
1253 vpush_helper_func(S, func);1259 vpush_helper_func(func);
1254 vrott(S, 2);1260 vrott(2);
1255 gfunc_call(S, 1);1261 gfunc_call(1);
1256 vpushi(S, 0);1262 vpushi(0);
1257 S->tccgen_vtop->type.t = t;1263 vtop->type.t = t;
1258 S->tccgen_vtop->r = REG_IRET;1264 vtop->r = REG_IRET;
1259 S->tccgen_vtop->r2 = TREG_R(1);1265 vtop->r2 = TREG_R(1);
1260 } else {1266 } else {
1261 S->tccgen_vtop--;1267 vtop--;
1262 dr = get_reg(S, RC_FLOAT);1268 dr = get_reg(RC_FLOAT);
1263 S->tccgen_vtop++;1269 vtop++;
1264 S->tccgen_vtop->r = dr;1270 vtop->r = dr;
1265 dr = freg(dr);1271 dr = freg(dr);
1266 EIu(S, 0x53, 7, dr, rr, ((0x68 | (t == VT_DOUBLE ? 1 : 0)) << 5) | (u ? 1 : 0) | (l ? 2 : 0)); // fcvt.[sd].[wl][u]1272 EIu(0x53, 7, dr, rr, ((0x68 | (t == VT_DOUBLE ? 1 : 0)) << 5) | (u ? 1 : 0) | (l ? 2 : 0)); // fcvt.[sd].[wl][u]
1267 }1273 }
1268}1274}
1269 1275
1270ST_FUNC void gen_cvt_ftoi(TCCState* S, int t)1276ST_FUNC void gen_cvt_ftoi(int t)
1271{1277{
1272 int ft = S->tccgen_vtop->type.t & VT_BTYPE;1278 int ft = vtop->type.t & VT_BTYPE;
1273 int l = (t & VT_BTYPE) == VT_LLONG;1279 int l = (t & VT_BTYPE) == VT_LLONG;
1274 int u = t & VT_UNSIGNED;1280 int u = t & VT_UNSIGNED;
1275 if (ft == VT_LDOUBLE) {1281 if (ft == VT_LDOUBLE) {
1276 int func = l ?1282 int func = l ?
1277 (u ? TOK___fixunstfdi : TOK___fixtfdi) :1283 (u ? TOK___fixunstfdi : TOK___fixtfdi) :
1278 (u ? TOK___fixunstfsi : TOK___fixtfsi);1284 (u ? TOK___fixunstfsi : TOK___fixtfsi);
1279 vpush_helper_func(S, func);1285 vpush_helper_func(func);
1280 vrott(S, 2);1286 vrott(2);
1281 gfunc_call(S, 1);1287 gfunc_call(1);
1282 vpushi(S, 0);1288 vpushi(0);
1283 S->tccgen_vtop->type.t = t;1289 vtop->type.t = t;
1284 S->tccgen_vtop->r = REG_IRET;1290 vtop->r = REG_IRET;
1285 } else {1291 } else {
1286 int rr = freg(gv(S, RC_FLOAT)), dr;1292 int rr = freg(gv(RC_FLOAT)), dr;
1287 S->tccgen_vtop--;1293 vtop--;
1288 dr = get_reg(S, RC_INT);1294 dr = get_reg(RC_INT);
1289 S->tccgen_vtop++;1295 vtop++;
1290 S->tccgen_vtop->r = dr;1296 vtop->r = dr;
1291 dr = ireg(dr);1297 dr = ireg(dr);
1292 EIu(S, 0x53, 1, dr, rr, ((0x60 | (ft == VT_DOUBLE ? 1 : 0)) << 5) | (u ? 1 : 0) | (l ? 2 : 0)); // fcvt.[wl][u].[sd] rtz1298 EIu(0x53, 1, dr, rr, ((0x60 | (ft == VT_DOUBLE ? 1 : 0)) << 5) | (u ? 1 : 0) | (l ? 2 : 0)); // fcvt.[wl][u].[sd] rtz
1293 }1299 }
1294}1300}
1295 1301
1296ST_FUNC void gen_cvt_ftof(TCCState* S, int dt)1302ST_FUNC void gen_cvt_ftof(int dt)
1297{1303{
1298 int st = S->tccgen_vtop->type.t & VT_BTYPE, rs, rd;1304 int st = vtop->type.t & VT_BTYPE, rs, rd;
1299 dt &= VT_BTYPE;1305 dt &= VT_BTYPE;
1300 if (st == dt)1306 if (st == dt)
1301 return;1307 return;
@@ -1307,109 +1313,109 @@ ST_FUNC void gen_cvt_ftof(TCCState* S, int dt) · 5 unmodified lines
1307 functions, and on riscv unnamed float args are passed like1313 functions, and on riscv unnamed float args are passed like
1308 integers. But we really need them in the float argument registers1314 integers. But we really need them in the float argument registers
1309 for extendsftf2/extenddftf2. So, do it explicitely. */1315 for extendsftf2/extenddftf2. So, do it explicitely. */
1310 save_regs(S, 1);1316 save_regs(1);
1311 if (dt == VT_LDOUBLE)1317 if (dt == VT_LDOUBLE)
1312 gv(S, RC_F(0));1318 gv(RC_F(0));
1313 else {1319 else {
1314 gv(S, RC_R(0));1320 gv(RC_R(0));
1315 assert(S->tccgen_vtop->r2 < 7);1321 assert(vtop->r2 < 7);
1316 if (S->tccgen_vtop->r2 != 1 + S->tccgen_vtop->r) {1322 if (vtop->r2 != 1 + vtop->r) {
1317 EI(S, 0x13, 0, ireg(S->tccgen_vtop->r) + 1, ireg(S->tccgen_vtop->r2), 0); // mv Ra+1, RR21323 EI(0x13, 0, ireg(vtop->r) + 1, ireg(vtop->r2), 0); // mv Ra+1, RR2
1318 S->tccgen_vtop->r2 = 1 + S->tccgen_vtop->r;1324 vtop->r2 = 1 + vtop->r;
1319 }1325 }
1320 }1326 }
1321 vpush_helper_func(S, func);1327 vpush_helper_func(func);
1322 gcall_or_jmp(S, 1);1328 gcall_or_jmp(1);
1323 S->tccgen_vtop -= 2;1329 vtop -= 2;
1324 vpushi(S, 0);1330 vpushi(0);
1325 S->tccgen_vtop->type.t = dt;1331 vtop->type.t = dt;
1326 if (dt == VT_LDOUBLE)1332 if (dt == VT_LDOUBLE)
1327 S->tccgen_vtop->r = REG_IRET, S->tccgen_vtop->r2 = REG_IRET+1;1333 vtop->r = REG_IRET, vtop->r2 = REG_IRET+1;
1328 else1334 else
1329 S->tccgen_vtop->r = REG_FRET;1335 vtop->r = REG_FRET;
1330 } else {1336 } else {
1331 assert (dt == VT_FLOAT || dt == VT_DOUBLE);1337 assert (dt == VT_FLOAT || dt == VT_DOUBLE);
1332 assert (st == VT_FLOAT || st == VT_DOUBLE);1338 assert (st == VT_FLOAT || st == VT_DOUBLE);
1333 rs = gv(S, RC_FLOAT);1339 rs = gv(RC_FLOAT);
1334 rd = get_reg(S, RC_FLOAT);1340 rd = get_reg(RC_FLOAT);
1335 if (dt == VT_DOUBLE)1341 if (dt == VT_DOUBLE)
1336 EI(S, 0x53, 0, freg(rd), freg(rs), 0x21 << 5); // fcvt.d.s RD, RS (no rm)1342 EI(0x53, 0, freg(rd), freg(rs), 0x21 << 5); // fcvt.d.s RD, RS (no rm)
1337 else1343 else
1338 EI(S, 0x53, 7, freg(rd), freg(rs), (0x20 << 5) | 1); // fcvt.s.d RD, RS (dyn rm)1344 EI(0x53, 7, freg(rd), freg(rs), (0x20 << 5) | 1); // fcvt.s.d RD, RS (dyn rm)
1339 S->tccgen_vtop->r = rd;1345 vtop->r = rd;
1340 }1346 }
1341}1347}
1342 1348
1343/* increment tcov counter */1349/* increment tcov counter */
1344ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv)1350ST_FUNC void gen_increment_tcov (SValue *sv)
1345{1351{
1346 int r1, r2;1352 int r1, r2;
1347 Sym label = {0};1353 Sym label = {0};
1348 label.type.t = VT_VOID | VT_STATIC;1354 label.type.t = VT_VOID | VT_STATIC;
1349 1355
1350 vpushv(S, sv);1356 vpushv(sv);
1351 S->tccgen_vtop->r = r1 = get_reg(S, RC_INT);1357 vtop->r = r1 = get_reg(RC_INT);
1352 r2 = get_reg(S, RC_INT);1358 r2 = get_reg(RC_INT);
1353 r1 = ireg(r1);1359 r1 = ireg(r1);
1354 r2 = ireg(r2);1360 r2 = ireg(r2);
1355 greloca(S, cur_text_section, sv->sym, S->tccgen_ind, R_RISCV_PCREL_HI20, 0);1361 greloca(cur_text_section, sv->sym, ind, R_RISCV_PCREL_HI20, 0);
1356 put_extern_sym(S, &label, cur_text_section, S->tccgen_ind, 0);1362 put_extern_sym(&label, cur_text_section, ind, 0);
1357 o(S, 0x17 | (r1 << 7)); // auipc RR, 0 %pcrel_hi(sym)1363 o(0x17 | (r1 << 7)); // auipc RR, 0 %pcrel_hi(sym)
1358 greloca(S, cur_text_section, &label, S->tccgen_ind, R_RISCV_PCREL_LO12_I, 0);1364 greloca(cur_text_section, &label, ind, R_RISCV_PCREL_LO12_I, 0);
1359 EI(S, 0x03, 3, r2, r1, 0); // ld r2, x[r1]1365 EI(0x03, 3, r2, r1, 0); // ld r2, x[r1]
1360 EI(S, 0x13, 0, r2, r2, 1); // addi r2, r2, #11366 EI(0x13, 0, r2, r2, 1); // addi r2, r2, #1
1361 greloca(S, cur_text_section, sv->sym, S->tccgen_ind, R_RISCV_PCREL_HI20, 0);1367 greloca(cur_text_section, sv->sym, ind, R_RISCV_PCREL_HI20, 0);
1362 label.c = 0; /* force new local ELF symbol */1368 label.c = 0; /* force new local ELF symbol */
1363 put_extern_sym(S, &label, cur_text_section, S->tccgen_ind, 0);1369 put_extern_sym(&label, cur_text_section, ind, 0);
1364 o(S, 0x17 | (r1 << 7)); // auipc RR, 0 %pcrel_hi(sym)1370 o(0x17 | (r1 << 7)); // auipc RR, 0 %pcrel_hi(sym)
1365 greloca(S, cur_text_section, &label, S->tccgen_ind, R_RISCV_PCREL_LO12_S, 0);1371 greloca(cur_text_section, &label, ind, R_RISCV_PCREL_LO12_S, 0);
1366 ES(S, 0x23, 3, r1, r2, 0); // sd r2, [r1]1372 ES(0x23, 3, r1, r2, 0); // sd r2, [r1]
1367 vpop(S);1373 vpop();
1368}1374}
1369 1375
1370ST_FUNC void ggoto(TCCState* S)1376ST_FUNC void ggoto(void)
1371{1377{
1372 gcall_or_jmp(S, 0);1378 gcall_or_jmp(0);
1373 S->tccgen_vtop--;1379 vtop--;
1374}1380}
1375 1381
1376ST_FUNC void gen_vla_sp_save(TCCState* S, int addr)1382ST_FUNC void gen_vla_sp_save(int addr)
1377{1383{
1378 ES(S, 0x23, 3, 8, 2, addr); // sd sp, fc(s0)1384 ES(0x23, 3, 8, 2, addr); // sd sp, fc(s0)
1379}1385}
1380 1386
1381ST_FUNC void gen_vla_sp_restore(TCCState* S, int addr)1387ST_FUNC void gen_vla_sp_restore(int addr)
1382{1388{
1383 EI(S, 0x03, 3, 2, 8, addr); // ld sp, fc(s0)1389 EI(0x03, 3, 2, 8, addr); // ld sp, fc(s0)
1384}1390}
1385 1391
1386ST_FUNC void gen_vla_alloc(TCCState* S, CType *type, int align)1392ST_FUNC void gen_vla_alloc(CType *type, int align)
1387{1393{
1388 int rr;1394 int rr;
1389#if defined(CONFIG_TCC_BCHECK)1395#if defined(CONFIG_TCC_BCHECK)
1390 if (S->do_bounds_check)1396 if (tcc_state->do_bounds_check)
1391 vpushv(S, S->tccgen_vtop);1397 vpushv(vtop);
1392#endif1398#endif
1393 rr = ireg(gv(S, RC_INT));1399 rr = ireg(gv(RC_INT));
1394#if defined(CONFIG_TCC_BCHECK)1400#if defined(CONFIG_TCC_BCHECK)
1395 if (S->do_bounds_check)1401 if (tcc_state->do_bounds_check)
1396 EI(S, 0x13, 0, rr, rr, 15+1); // addi RR, RR, 15+11402 EI(0x13, 0, rr, rr, 15+1); // addi RR, RR, 15+1
1397 else1403 else
1398#endif1404#endif
1399 EI(S, 0x13, 0, rr, rr, 15); // addi RR, RR, 151405 EI(0x13, 0, rr, rr, 15); // addi RR, RR, 15
1400 EI(S, 0x13, 7, rr, rr, -16); // andi, RR, RR, -161406 EI(0x13, 7, rr, rr, -16); // andi, RR, RR, -16
1401 ER(S, 0x33, 0, 2, 2, rr, 0x20); // sub sp, sp, rr1407 ER(0x33, 0, 2, 2, rr, 0x20); // sub sp, sp, rr
1402 vpop(S);1408 vpop();
1403#if defined(CONFIG_TCC_BCHECK)1409#if defined(CONFIG_TCC_BCHECK)
1404 if (S->do_bounds_check) {1410 if (tcc_state->do_bounds_check) {
1405 vpushi(S, 0);1411 vpushi(0);
1406 S->tccgen_vtop->r = TREG_R(0);1412 vtop->r = TREG_R(0);
1407 o(S, 0x00010513); /* mv a0,sp */1413 o(0x00010513); /* mv a0,sp */
1408 vswap(S);1414 vswap();
1409 vpush_helper_func(S, TOK___bound_new_region);1415 vpush_helper_func(TOK___bound_new_region);
1410 vrott(S, 3);1416 vrott(3);
1411 gfunc_call(S, 2);1417 gfunc_call(2);
1412 S->func_bound_add_epilog = 1;1418 func_bound_add_epilog = 1;
1413 }1419 }
1414#endif1420#endif
1415}1421}
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 *S, unsigned got_offset, struct sym_attr *attr)98ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
99{99{
100 Section *plt = S->plt;100 Section *plt = s1->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(S, plt, 32);105 section_ptr_add(plt, 32);
106 plt_offset = plt->data_offset;106 plt_offset = plt->data_offset;
107 107
108 p = section_ptr_add(S, plt, 16);108 p = section_ptr_add(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 *S)115ST_FUNC void relocate_plt(TCCState *s1)
116{116{
117 uint8_t *p, *p_end;117 uint8_t *p, *p_end;
118 118
119 if (!S->plt)119 if (!s1->plt)
120 return;120 return;
121 121
122 p = S->plt->data;122 p = s1->plt->data;
123 p_end = p + S->plt->data_offset;123 p_end = p + s1->plt->data_offset;
124 124
125 if (p < p_end) {125 if (p < p_end) {
126 uint64_t plt = S->plt->sh_addr;126 uint64_t plt = s1->plt->sh_addr;
127 uint64_t got = S->got->sh_addr;127 uint64_t got = s1->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(S, "Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt);130 tcc_error("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 *S) · 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 - S->plt->data);143 uint64_t pc = plt + (p - s1->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(S, "Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc);147 tcc_error("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 *S) · 3 unmodified lines
154 }154 }
155 }155 }
156 156
157 if (S->plt->reloc) {157 if (s1->plt->reloc) {
158 ElfW_Rel *rel;158 ElfW_Rel *rel;
159 p = S->got->data;159 p = s1->got->data;
160 for_each_elem(S->plt->reloc, 0, rel, ElfW_Rel) {160 for_each_elem(s1->plt->reloc, 0, rel, ElfW_Rel) {
161 write64le(p + rel->r_offset, S->plt->sh_addr);161 write64le(p + rel->r_offset, s1->plt->sh_addr);
162 }162 }
163 }163 }
164}164}
165 165
166void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr,166void relocate(TCCState *s1, 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 *S, 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(S, "R_RISCV_BRANCH relocation failed"182 tcc_error("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 *S, 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(S, "R_RISCV_JAL relocation failed"194 tcc_error("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 *S, 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(S, "R_RISCV_PCREL_HI20 relocation failed: off=%lx cond=%lx sym=%s",216 tcc_error("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 *S, 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 = S->got->sh_addr + get_sym_attr(S, sym_index, 0)->got_offset;225 val = s1->got->sh_addr + get_sym_attr(s1, 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(S, "R_RISCV_GOT_HI20 relocation failed");228 tcc_error("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 *S, 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(S, "unsupported hi/lo pcrel reloc scheme");239 tcc_error("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 *S, 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(S, "unsupported hi/lo pcrel reloc scheme");247 tcc_error("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 *S, 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(S, "R_RISCV_RVC_BRANCH relocation failed"259 tcc_error("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 *S, 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(S, "R_RISCV_RVC_BRANCH relocation failed"272 tcc_error("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 *S, 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 (S->output_type == TCC_OUTPUT_DLL) {287 if (s1->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 *S, 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 (S->output_type == TCC_OUTPUT_DLL) {299 if (s1->output_type == TCC_OUTPUT_DLL) {
300 esym_index = get_sym_attr(S, sym_index, 0)->dyn_index;300 esym_index = get_sym_attr(s1, 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+70−168
@@ -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(S, buf);257 return tcc_strdup(buf);
258}258}
259 259
260static unsigned getclock_ms(void)260static unsigned getclock_ms(void)
@@ -268,101 +268,9 @@ 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
363int main(int argc0, char **argv0)271int main(int argc0, char **argv0)
364{272{
365 TCCState *S, *s1;273 TCCState *s, *s1;
366 int ret, opt, n = 0, t = 0, done;274 int ret, opt, n = 0, t = 0, done;
367 unsigned start_time = 0, end_time = 0;275 unsigned start_time = 0, end_time = 0;
368 const char *first_file;276 const char *first_file;
@@ -371,19 +279,13 @@ int main(int argc0, char **argv0) · 2 unmodified lines
371 279
372redo:280redo:
373 argc = argc0, argv = argv0;281 argc = argc0, argv = argv0;
374 S = s1 = tcc_new();282 s = s1 = tcc_new();
375 opt = tcc_parse_args(S, &argc, &argv, 1);283 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
382 284
383 if (n == 0) {285 if (n == 0) {
384 if (opt == OPT_HELP) {286 if (opt == OPT_HELP) {
385 fputs(help, stdout);287 fputs(help, stdout);
386 if (!S->verbose)288 if (!s->verbose)
387 return 0;289 return 0;
388 ++opt;290 ++opt;
389 }291 }
@@ -392,57 +294,57 @@ redo: · 2 unmodified lines
392 return 0;294 return 0;
393 }295 }
394 if (opt == OPT_M32 || opt == OPT_M64)296 if (opt == OPT_M32 || opt == OPT_M64)
395 tcc_tool_cross(S, argv, opt); /* never returns */297 tcc_tool_cross(s, argv, opt); /* never returns */
396 if (S->verbose)298 if (s->verbose)
397 printf(version);299 printf(version);
398 if (opt == OPT_AR)300 if (opt == OPT_AR)
399 return tcc_tool_ar(S, argc, argv);301 return tcc_tool_ar(s, argc, argv);
400#ifdef TCC_TARGET_PE302#ifdef TCC_TARGET_PE
401 if (opt == OPT_IMPDEF)303 if (opt == OPT_IMPDEF)
402 return tcc_tool_impdef(S, argc, argv);304 return tcc_tool_impdef(s, argc, argv);
403#endif305#endif
404 if (opt == OPT_V)306 if (opt == OPT_V)
405 return 0;307 return 0;
406 if (opt == OPT_PRINT_DIRS) {308 if (opt == OPT_PRINT_DIRS) {
407 /* initialize search dirs */309 /* initialize search dirs */
408 set_environment(S);310 set_environment(s);
409 tcc_set_output_type(S, TCC_OUTPUT_MEMORY);311 tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
410 print_search_dirs(S);312 print_search_dirs(s);
411 return 0;313 return 0;
412 }314 }
413 315
414 if (S->nb_files == 0)316 if (s->nb_files == 0)
415 tcc_error(S, "no input files");317 tcc_error("no input files");
416 318
417 if (S->output_type == TCC_OUTPUT_PREPROCESS) {319 if (s->output_type == TCC_OUTPUT_PREPROCESS) {
418 if (S->outfile && 0!=strcmp("-",S->outfile)) {320 if (s->outfile && 0!=strcmp("-",s->outfile)) {
419 ppfp = fopen(S->outfile, "w");321 ppfp = fopen(s->outfile, "w");
420 if (!ppfp)322 if (!ppfp)
421 tcc_error(S, "could not write '%s'", S->outfile);323 tcc_error("could not write '%s'", s->outfile);
422 }324 }
423 } else if (S->output_type == TCC_OUTPUT_OBJ && !S->option_r) {325 } else if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) {
424 if (S->nb_libraries)326 if (s->nb_libraries)
425 tcc_error(S, "cannot specify libraries with -c");327 tcc_error("cannot specify libraries with -c");
426 if (S->nb_files > 1 && S->outfile)328 if (s->nb_files > 1 && s->outfile)
427 tcc_error(S, "cannot specify output file with -c many files");329 tcc_error("cannot specify output file with -c many files");
428 }330 }
429 331
430 if (S->do_bench)332 if (s->do_bench)
431 start_time = getclock_ms();333 start_time = getclock_ms();
432 }334 }
433 335
434 set_environment(S);336 set_environment(s);
435 if (S->output_type == 0)337 if (s->output_type == 0)
436 S->output_type = TCC_OUTPUT_EXE;338 s->output_type = TCC_OUTPUT_EXE;
437 tcc_set_output_type(S, S->output_type);339 tcc_set_output_type(s, s->output_type);
438 S->ppfp = ppfp;340 s->ppfp = ppfp;
439 341
440 if ((S->output_type == TCC_OUTPUT_MEMORY342 if ((s->output_type == TCC_OUTPUT_MEMORY
441 || S->output_type == TCC_OUTPUT_PREPROCESS)343 || s->output_type == TCC_OUTPUT_PREPROCESS)
442 && (S->dflag & TCC_OPTION_d_t)) { /* -dt option */344 && (s->dflag & 16)) { /* -dt option */
443 if (t)345 if (t)
444 S->dflag |= TCC_OPTION_d_32;346 s->dflag |= 32;
445 S->run_test = ++t;347 s->run_test = ++t;
446 if (n)348 if (n)
447 --n;349 --n;
448 }350 }
@@ -450,48 +352,48 @@ redo: · 1 unmodified line
450 /* compile or add each files or library */352 /* compile or add each files or library */
451 first_file = NULL, ret = 0;353 first_file = NULL, ret = 0;
452 do {354 do {
453 struct filespec *f = S->files[n];355 struct filespec *f = s->files[n];
454 S->filetype = f->type;356 s->filetype = f->type;
455 if (f->type & AFF_TYPE_LIB) {357 if (f->type & AFF_TYPE_LIB) {
456 if (tcc_add_library_err(S, f->name) < 0)358 if (tcc_add_library_err(s, f->name) < 0)
457 ret = 1;359 ret = 1;
458 } else {360 } else {
459 if (1 == S->verbose)361 if (1 == s->verbose)
460 printf("-> %s\n", f->name);362 printf("-> %s\n", f->name);
461 if (!first_file)363 if (!first_file)
462 first_file = f->name;364 first_file = f->name;
463 if (tcc_add_file(S, f->name) < 0)365 if (tcc_add_file(s, f->name) < 0)
464 ret = 1;366 ret = 1;
465 }367 }
466 done = ret || ++n >= S->nb_files;368 done = ret || ++n >= s->nb_files;
467 } while (!done && (S->output_type != TCC_OUTPUT_OBJ || S->option_r));369 } while (!done && (s->output_type != TCC_OUTPUT_OBJ || s->option_r));
468 370
469 if (S->do_bench)371 if (s->do_bench)
470 end_time = getclock_ms();372 end_time = getclock_ms();
471 373
472 if (S->run_test) {374 if (s->run_test) {
473 t = 0;375 t = 0;
474 } else if (S->output_type == TCC_OUTPUT_PREPROCESS) {376 } else if (s->output_type == TCC_OUTPUT_PREPROCESS) {
475 ;377 ;
476 } else if (0 == ret) {378 } else if (0 == ret) {
477 if (S->output_type == TCC_OUTPUT_MEMORY) {379 if (s->output_type == TCC_OUTPUT_MEMORY) {
478#ifdef TCC_IS_NATIVE380#ifdef TCC_IS_NATIVE
479 ret = tcc_run(S, argc, argv);381 ret = tcc_run(s, argc, argv);
480#endif382#endif
481 } else {383 } else {
482 if (!S->outfile)384 if (!s->outfile)
483 S->outfile = default_outputfile(S, first_file);385 s->outfile = default_outputfile(s, first_file);
484 if (!S->just_deps && tcc_output_file(S, S->outfile))386 if (!s->just_deps && tcc_output_file(s, s->outfile))
485 ret = 1;387 ret = 1;
486 else if (S->gen_deps)388 else if (s->gen_deps)
487 gen_makedeps(S, S->outfile, S->deps_outfile);389 gen_makedeps(s, s->outfile, s->deps_outfile);
488 }390 }
489 }391 }
490 392
491 if (done && 0 == t && 0 == ret && S->do_bench)393 if (done && 0 == t && 0 == ret && s->do_bench)
492 tcc_print_stats(S, end_time - start_time);394 tcc_print_stats(s, end_time - start_time);
493 395
494 tcc_delete(S);396 tcc_delete(s);
495 if (!done)397 if (!done)
496 goto redo; /* compile more files with -c */398 goto redo; /* compile more files with -c */
497 if (t)399 if (t)
tcc.h+299−458
@@ -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 *S;588 TCCState *s1;
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,78 +743,6 @@ 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
818struct TCCState {746struct TCCState {
819 unsigned char verbose; /* if true, display some information during compilation */747 unsigned char verbose; /* if true, display some information during compilation */
820 unsigned char nostdinc; /* if true, no standard headers are added */748 unsigned char nostdinc; /* if true, no standard headers are added */
@@ -999,11 +927,11 @@ struct TCCState { · 178 unmodified lines
999 int nb_sym_attrs;927 int nb_sym_attrs;
1000 /* ptr to next reloc entry reused */928 /* ptr to next reloc entry reused */
1001 ElfW_Rel *qrel;929 ElfW_Rel *qrel;
1002 #define qrel S->qrel930 #define qrel s1->qrel
1003 931
1004#ifdef TCC_TARGET_RISCV64932#ifdef TCC_TARGET_RISCV64
1005 struct pcrel_hi { addr_t addr, val; } last_hi;933 struct pcrel_hi { addr_t addr, val; } last_hi;
1006 #define last_hi S->last_hi934 #define last_hi s1->last_hi
1007#endif935#endif
1008 936
1009#ifdef TCC_TARGET_PE937#ifdef TCC_TARGET_PE
@@ -1034,10 +962,6 @@ struct TCCState { · 24 unmodified lines
1034 const char *runtime_main;962 const char *runtime_main;
1035 void **runtime_mem;963 void **runtime_mem;
1036 int nb_runtime_mem;964 int nb_runtime_mem;
1037# ifdef HAVE_SELINUX
1038 void *write_mem;
1039 unsigned long mem_size;
1040# endif
1041#endif965#endif
1042 966
1043#ifdef CONFIG_TCC_BACKTRACE967#ifdef CONFIG_TCC_BACKTRACE
@@ -1067,117 +991,6 @@ struct TCCState { · 23 unmodified lines
1067 char *deps_outfile; /* option -MF */991 char *deps_outfile; /* option -MF */
1068 int argc;992 int argc;
1069 char **argv;993 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
1181};994};
1182 995
1183struct filespec {996struct filespec {
@@ -1361,7 +1174,7 @@ enum tcc_token { · 177 unmodified lines
1361 1174
1362/* ------------ libtcc.c ------------ */1175/* ------------ libtcc.c ------------ */
1363 1176
1364//ST_DATA struct TCCState *S;1177ST_DATA struct TCCState *tcc_state;
1365 1178
1366/* public functions currently used by the tcc main function */1179/* public functions currently used by the tcc main function */
1367ST_FUNC char *pstrcpy(char *buf, size_t buf_size, const char *s);1180ST_FUNC char *pstrcpy(char *buf, size_t buf_size, const char *s);
@@ -1370,56 +1183,53 @@ ST_FUNC char *pstrncpy(char *out, const char *in, size_t num); · 2 unmodified lines
1370PUB_FUNC char *tcc_basename(const char *name);1183PUB_FUNC char *tcc_basename(const char *name);
1371PUB_FUNC char *tcc_fileextension (const char *name);1184PUB_FUNC char *tcc_fileextension (const char *name);
1372 1185
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);
1376#ifndef MEM_DEBUG1186#ifndef MEM_DEBUG
1377PUB_FUNC void tcc_free(TCCState* S, void *ptr);1187PUB_FUNC void tcc_free(void *ptr);
1378PUB_FUNC void *tcc_malloc(TCCState* S, unsigned long size);1188PUB_FUNC void *tcc_malloc(unsigned long size);
1379PUB_FUNC void *tcc_mallocz(TCCState* S, unsigned long size);1189PUB_FUNC void *tcc_mallocz(unsigned long size);
1380PUB_FUNC void *tcc_realloc(TCCState* S, void *ptr, unsigned long size);1190PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size);
1381PUB_FUNC char *tcc_strdup(TCCState* S, const char *str);1191PUB_FUNC char *tcc_strdup(const char *str);
1382#else1192#else
1383#define tcc_free(s, ptr) tcc_free_debug(s, ptr)1193#define tcc_free(ptr) tcc_free_debug(ptr)
1384#define tcc_malloc(s, size) tcc_malloc_debug(s, size, __FILE__, __LINE__)1194#define tcc_malloc(size) tcc_malloc_debug(size, __FILE__, __LINE__)
1385#define tcc_mallocz(s, size) tcc_mallocz_debug(s, size, __FILE__, __LINE__)1195#define tcc_mallocz(size) tcc_mallocz_debug(size, __FILE__, __LINE__)
1386#define tcc_realloc(s, ptr, size) tcc_realloc_debug(s, ptr, size, __FILE__, __LINE__)1196#define tcc_realloc(ptr,size) tcc_realloc_debug(ptr, size, __FILE__, __LINE__)
1387#define tcc_strdup(s, str) tcc_strdup_debug(s, str, __FILE__, __LINE__)1197#define tcc_strdup(str) tcc_strdup_debug(str, __FILE__, __LINE__)
1388PUB_FUNC void tcc_free_debug(TCCState* S, void *ptr);1198PUB_FUNC void tcc_free_debug(void *ptr);
1389PUB_FUNC void *tcc_malloc_debug(TCCState* S, unsigned long size, const char *file, int line);1199PUB_FUNC void *tcc_malloc_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);1200PUB_FUNC void *tcc_mallocz_debug(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);1201PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file, int line);
1392PUB_FUNC char *tcc_strdup_debug(TCCState* S, const char *str, const char *file, int line);1202PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line);
1393#endif1203#endif
1394 1204
1395#define free(p) use_tcc_free(S, p)1205#define free(p) use_tcc_free(p)
1396#define malloc(s) use_tcc_malloc(S, s)1206#define malloc(s) use_tcc_malloc(s)
1397#define realloc(p, s) use_tcc_realloc(S, p, s)1207#define realloc(p, s) use_tcc_realloc(p, s)
1398#undef strdup1208#undef strdup
1399#define strdup(s) use_tcc_strdup(S, s)1209#define strdup(s) use_tcc_strdup(s)
1400PUB_FUNC void _tcc_error_noabort(TCCState* S, const char *fmt, ...) PRINTF_LIKE(2,3);1210PUB_FUNC void _tcc_error_noabort(const char *fmt, ...) PRINTF_LIKE(1,2);
1401PUB_FUNC NORETURN void _tcc_error(TCCState* S, const char *fmt, ...) PRINTF_LIKE(2,3);1211PUB_FUNC NORETURN void _tcc_error(const char *fmt, ...) PRINTF_LIKE(1,2);
1402PUB_FUNC void _tcc_warning(TCCState* S, const char *fmt, ...) PRINTF_LIKE(2,3);1212PUB_FUNC void _tcc_warning(const char *fmt, ...) PRINTF_LIKE(1,2);
1403#define tcc_internal_error(S, msg) tcc_error(S, "internal compiler error\n"\1213#define tcc_internal_error(msg) tcc_error("internal compiler error\n"\
1404 "%s:%d: in %s(): " msg, __FILE__,__LINE__,__FUNCTION__)1214 "%s:%d: in %s(): " msg, __FILE__,__LINE__,__FUNCTION__)
1405 1215
1406/* other utilities */1216/* other utilities */
1407ST_FUNC void dynarray_add(TCCState* S, void *ptab, int *nb_ptr, void *data);1217ST_FUNC void dynarray_add(void *ptab, int *nb_ptr, void *data);
1408ST_FUNC void dynarray_reset(TCCState* S, void *pp, int *n);1218ST_FUNC void dynarray_reset(void *pp, int *n);
1409ST_INLN void cstr_ccat(TCCState* S, CString *cstr, int ch);1219ST_INLN void cstr_ccat(CString *cstr, int ch);
1410ST_FUNC void cstr_cat(TCCState* S, CString *cstr, const char *str, int len);1220ST_FUNC void cstr_cat(CString *cstr, const char *str, int len);
1411ST_FUNC void cstr_wccat(TCCState* S, CString *cstr, int ch);1221ST_FUNC void cstr_wccat(CString *cstr, int ch);
1412ST_FUNC void cstr_new(TCCState* S, CString *cstr);1222ST_FUNC void cstr_new(CString *cstr);
1413ST_FUNC void cstr_free(TCCState* S, CString *cstr);1223ST_FUNC void cstr_free(CString *cstr);
1414ST_FUNC int cstr_printf(TCCState* S, CString *cs, const char *fmt, ...) PRINTF_LIKE(3,4);1224ST_FUNC int cstr_printf(CString *cs, const char *fmt, ...) PRINTF_LIKE(2,3);
1415ST_FUNC int cstr_vprintf(TCCState* S, CString *cstr, const char *fmt, va_list ap);1225ST_FUNC int cstr_vprintf(CString *cstr, const char *fmt, va_list ap);
1416ST_FUNC void cstr_reset(CString *cstr);1226ST_FUNC void cstr_reset(CString *cstr);
1417 1227
1418ST_FUNC void tcc_open_bf(TCCState *S, const char *filename, int initlen);1228ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen);
1419ST_FUNC int tcc_open(TCCState *S, const char *filename);1229ST_FUNC int tcc_open(TCCState *s1, const char *filename);
1420ST_FUNC void tcc_close(TCCState *S);1230ST_FUNC void tcc_close(void);
1421 1231
1422ST_FUNC int tcc_add_file_internal(TCCState *S, const char *filename, int flags);1232ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags);
1423/* flags: */1233/* flags: */
1424#define AFF_PRINT_ERROR 0x10 /* print error if file not found */1234#define AFF_PRINT_ERROR 0x10 /* print error if file not found */
1425#define AFF_REFERENCED_DLL 0x20 /* load a referenced dll from another dll */1235#define AFF_REFERENCED_DLL 0x20 /* load a referenced dll from another dll */
@@ -1439,26 +1249,26 @@ ST_FUNC int tcc_add_file_internal(TCCState *S, const char *filename, int flags); · 13 unmodified lines
1439#define AFF_BINTYPE_C67 41249#define AFF_BINTYPE_C67 4
1440 1250
1441#ifndef ELF_OBJ_ONLY1251#ifndef ELF_OBJ_ONLY
1442ST_FUNC int tcc_add_crt(TCCState *S, const char *filename);1252ST_FUNC int tcc_add_crt(TCCState *s, const char *filename);
1443#endif1253#endif
1444#ifndef TCC_TARGET_MACHO1254#ifndef TCC_TARGET_MACHO
1445ST_FUNC int tcc_add_dll(TCCState *S, const char *filename, int flags);1255ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags);
1446#endif1256#endif
1447#ifdef CONFIG_TCC_BCHECK1257#ifdef CONFIG_TCC_BCHECK
1448ST_FUNC void tcc_add_bcheck(TCCState *S);1258ST_FUNC void tcc_add_bcheck(TCCState *s1);
1449#endif1259#endif
1450#ifdef CONFIG_TCC_BACKTRACE1260#ifdef CONFIG_TCC_BACKTRACE
1451ST_FUNC void tcc_add_btstub(TCCState *S);1261ST_FUNC void tcc_add_btstub(TCCState *s1);
1452#endif1262#endif
1453ST_FUNC void tcc_add_pragma_libs(TCCState *S);1263ST_FUNC void tcc_add_pragma_libs(TCCState *s1);
1454PUB_FUNC int tcc_add_library_err(TCCState *S, const char *f);1264PUB_FUNC int tcc_add_library_err(TCCState *s, const char *f);
1455PUB_FUNC void tcc_print_stats(TCCState *S, unsigned total_time);1265PUB_FUNC void tcc_print_stats(TCCState *s, unsigned total_time);
1456PUB_FUNC int tcc_parse_args(TCCState *S, int *argc, char ***argv, int optind);1266PUB_FUNC int tcc_parse_args(TCCState *s, int *argc, char ***argv, int optind);
1457#ifdef _WIN321267#ifdef _WIN32
1458ST_FUNC char *normalize_slashes(char *path);1268ST_FUNC char *normalize_slashes(char *path);
1459#endif1269#endif
1460ST_FUNC DLLReference *tcc_add_dllref(TCCState *S, const char *dllname);1270ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllname);
1461ST_FUNC char *tcc_load_text(TCCState *S, int fd);1271ST_FUNC char *tcc_load_text(int fd);
1462 1272
1463/* tcc_parse_args return codes: */1273/* tcc_parse_args return codes: */
1464#define OPT_HELP 11274#define OPT_HELP 1
@@ -1472,6 +1282,18 @@ ST_FUNC char *tcc_load_text(TCCState *S, int fd); · 7 unmodified lines
1472 1282
1473/* ------------ tccpp.c ------------ */1283/* ------------ tccpp.c ------------ */
1474 1284
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
1475#define TOK_FLAG_BOL 0x0001 /* beginning of line before */1297#define TOK_FLAG_BOL 0x0001 /* beginning of line before */
1476#define TOK_FLAG_BOF 0x0002 /* beginning of file before */1298#define TOK_FLAG_BOF 0x0002 /* beginning of file before */
1477#define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */1299#define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
@@ -1499,36 +1321,36 @@ enum line_macro_output_format { · 21 unmodified lines
1499 LINE_MACRO_OUTPUT_FORMAT_P10 = 111321 LINE_MACRO_OUTPUT_FORMAT_P10 = 11
1500};1322};
1501 1323
1502ST_FUNC TokenSym *tok_alloc(TCCState* S, const char *str, int len);1324ST_FUNC TokenSym *tok_alloc(const char *str, int len);
1503ST_FUNC int tok_alloc_const(TCCState* S, const char *str);1325ST_FUNC int tok_alloc_const(const char *str);
1504ST_FUNC const char *get_tok_str(TCCState* S, int v, CValue *cv);1326ST_FUNC const char *get_tok_str(int v, CValue *cv);
1505ST_FUNC void begin_macro(TCCState* S, TokenString *str, int alloc);1327ST_FUNC void begin_macro(TokenString *str, int alloc);
1506ST_FUNC void end_macro(TCCState* S);1328ST_FUNC void end_macro(void);
1507ST_FUNC int set_idnum(TCCState* S, int c, int val);1329ST_FUNC int set_idnum(int c, int val);
1508ST_INLN void tok_str_new(TokenString *s);1330ST_INLN void tok_str_new(TokenString *s);
1509ST_FUNC TokenString *tok_str_alloc(TCCState* S);1331ST_FUNC TokenString *tok_str_alloc(void);
1510ST_FUNC void tok_str_free(TCCState* S, TokenString *s);1332ST_FUNC void tok_str_free(TokenString *s);
1511ST_FUNC void tok_str_free_str(TCCState* S, int *str);1333ST_FUNC void tok_str_free_str(int *str);
1512ST_FUNC void tok_str_add(TCCState* S, TokenString *s, int t);1334ST_FUNC void tok_str_add(TokenString *s, int t);
1513ST_FUNC void tok_str_add_tok(TCCState* S, TokenString *s);1335ST_FUNC void tok_str_add_tok(TokenString *s);
1514ST_INLN void define_push(TCCState* S, int v, int macro_type, int *str, Sym *first_arg);1336ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg);
1515ST_FUNC void define_undef(TCCState* S, Sym *s);1337ST_FUNC void define_undef(Sym *s);
1516ST_INLN Sym *define_find(TCCState* S, int v);1338ST_INLN Sym *define_find(int v);
1517ST_FUNC void free_defines(TCCState* S, Sym *b);1339ST_FUNC void free_defines(Sym *b);
1518ST_FUNC Sym *label_find(TCCState* S, int v);1340ST_FUNC Sym *label_find(int v);
1519ST_FUNC Sym *label_push(TCCState* S, Sym **ptop, int v, int flags);1341ST_FUNC Sym *label_push(Sym **ptop, int v, int flags);
1520ST_FUNC void label_pop(TCCState* S, Sym **ptop, Sym *slast, int keep);1342ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep);
1521ST_FUNC void parse_define(TCCState* S);1343ST_FUNC void parse_define(void);
1522ST_FUNC void preprocess(TCCState* S, int is_bof);1344ST_FUNC void preprocess(int is_bof);
1523ST_FUNC void next(TCCState* S);1345ST_FUNC void next(void);
1524ST_INLN void unget_tok(TCCState* S, int last_tok);1346ST_INLN void unget_tok(int last_tok);
1525ST_FUNC void preprocess_start(TCCState *S, int filetype);1347ST_FUNC void preprocess_start(TCCState *s1, int filetype);
1526ST_FUNC void preprocess_end(TCCState *S);1348ST_FUNC void preprocess_end(TCCState *s1);
1527ST_FUNC void tccpp_new(TCCState *S);1349ST_FUNC void tccpp_new(TCCState *s);
1528ST_FUNC void tccpp_delete(TCCState *S);1350ST_FUNC void tccpp_delete(TCCState *s);
1529ST_FUNC int tcc_preprocess(TCCState *S);1351ST_FUNC int tcc_preprocess(TCCState *s1);
1530ST_FUNC void skip(TCCState* S, int c);1352ST_FUNC void skip(int c);
1531ST_FUNC NORETURN void expect(TCCState* S, const char *msg);1353ST_FUNC NORETURN void expect(const char *msg);
1532 1354
1533/* space excluding newline */1355/* space excluding newline */
1534static inline int is_space(int ch) {1356static inline int is_space(int ch) {
@@ -1550,85 +1372,104 @@ static inline int toup(int c) { · 15 unmodified lines
1550/* ------------ tccgen.c ------------ */1372/* ------------ tccgen.c ------------ */
1551 1373
1552#define SYM_POOL_NB (8192 / sizeof(Sym))1374#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);
1558 1375
1559ST_FUNC void tccgen_init(TCCState *S);1376ST_DATA Sym *global_stack;
1560ST_FUNC int tccgen_compile(TCCState *S);1377ST_DATA Sym *local_stack;
1561ST_FUNC void tccgen_finish(TCCState *S);1378ST_DATA Sym *local_label_stack;
1562ST_FUNC void check_vstack(TCCState* S);1379ST_DATA Sym *global_label_stack;
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);
1563 1404
1564ST_INLN int is_float(int t);1405ST_INLN int is_float(int t);
1565ST_FUNC int ieee_finite(double d);1406ST_FUNC int ieee_finite(double d);
1566ST_FUNC int exact_log2p1(int i);1407ST_FUNC int exact_log2p1(int i);
1567ST_FUNC void test_lvalue(TCCState* S);1408ST_FUNC void test_lvalue(void);
1568 1409
1569ST_FUNC ElfSym *elfsym(TCCState* S, Sym *);1410ST_FUNC ElfSym *elfsym(Sym *);
1570ST_FUNC void update_storage(TCCState* S, Sym *sym);1411ST_FUNC void update_storage(Sym *sym);
1571ST_FUNC void put_extern_sym2(TCCState* S, Sym *sym, int sh_num, addr_t value, unsigned long size, int can_add_underscore);1412ST_FUNC void put_extern_sym2(Sym *sym, int sh_num, addr_t value, unsigned long size, int can_add_underscore);
1572ST_FUNC void put_extern_sym(TCCState* S, Sym *sym, Section *section, addr_t value, unsigned long size);1413ST_FUNC void put_extern_sym(Sym *sym, Section *section, addr_t value, unsigned long size);
1573#if PTR_SIZE == 41414#if PTR_SIZE == 4
1574ST_FUNC void greloc(TCCState* S, Section *s, Sym *sym, unsigned long offset, int type);1415ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type);
1575#endif1416#endif
1576ST_FUNC void greloca(TCCState* S, Section *s, Sym *sym, unsigned long offset, int type, addr_t addend);1417ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type, addr_t addend);
1577 1418
1578ST_INLN void sym_free(TCCState* S, Sym *sym);1419ST_INLN void sym_free(Sym *sym);
1579ST_FUNC Sym *sym_push(TCCState* S, int v, CType *type, int r, int c);1420ST_FUNC Sym *sym_push(int v, CType *type, int r, int c);
1580ST_FUNC void sym_pop(TCCState* S, Sym **ptop, Sym *b, int keep);1421ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep);
1581ST_FUNC Sym *sym_push2(TCCState* S, Sym **ps, int v, int t, int c);1422ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, int c);
1582ST_FUNC Sym *sym_find2(Sym *s, int v);1423ST_FUNC Sym *sym_find2(Sym *s, int v);
1583ST_INLN Sym *sym_find(TCCState* S, int v);1424ST_INLN Sym *sym_find(int v);
1584ST_INLN Sym *struct_find(TCCState* S, int v);1425ST_INLN Sym *struct_find(int v);
1585 1426
1586ST_FUNC Sym *global_identifier_push(TCCState* S, int v, int t, int c);1427ST_FUNC Sym *global_identifier_push(int v, int t, int c);
1587ST_FUNC Sym *external_global_sym(TCCState* S, int v, CType *type);1428ST_FUNC Sym *external_global_sym(int v, CType *type);
1588ST_FUNC Sym *external_helper_sym(TCCState* S, int v);1429ST_FUNC Sym *external_helper_sym(int v);
1589ST_FUNC void vpush_helper_func(TCCState* S, int v);1430ST_FUNC void vpush_helper_func(int v);
1590ST_FUNC void vset(TCCState* S, CType *type, int r, int v);1431ST_FUNC void vset(CType *type, int r, int v);
1591ST_FUNC void vset_VT_CMP(TCCState* S, int op);1432ST_FUNC void vset_VT_CMP(int op);
1592ST_FUNC void vpushi(TCCState* S, int v);1433ST_FUNC void vpushi(int v);
1593ST_FUNC void vpushv(TCCState* S, SValue *v);1434ST_FUNC void vpushv(SValue *v);
1594ST_FUNC void vpushsym(TCCState* S, CType *type, Sym *sym);1435ST_FUNC void vpushsym(CType *type, Sym *sym);
1595ST_FUNC void vswap(TCCState* S);1436ST_FUNC void vswap(void);
1596ST_FUNC void vrote(TCCState* S, SValue *e, int n);1437ST_FUNC void vrote(SValue *e, int n);
1597ST_FUNC void vrott(TCCState* S, int n);1438ST_FUNC void vrott(int n);
1598ST_FUNC void vrotb(TCCState* S, int n);1439ST_FUNC void vrotb(int n);
1599ST_FUNC void vpop(TCCState* S);1440ST_FUNC void vpop(void);
1600#if PTR_SIZE == 41441#if PTR_SIZE == 4
1601ST_FUNC void lexpand(TCCState* S);1442ST_FUNC void lexpand(void);
1602#endif1443#endif
1603#ifdef TCC_TARGET_ARM1444#ifdef TCC_TARGET_ARM
1604ST_FUNC int get_reg_ex(TCCState* S, int rc, int rc2);1445ST_FUNC int get_reg_ex(int rc, int rc2);
1605#endif1446#endif
1606ST_FUNC void save_reg(TCCState* S, int r);1447ST_FUNC void save_reg(int r);
1607ST_FUNC void save_reg_upstack(TCCState* S, int r, int n);1448ST_FUNC void save_reg_upstack(int r, int n);
1608ST_FUNC int get_reg(TCCState* S, int rc);1449ST_FUNC int get_reg(int rc);
1609ST_FUNC void save_regs(TCCState* S, int n);1450ST_FUNC void save_regs(int n);
1610ST_FUNC void gaddrof(TCCState* S);1451ST_FUNC void gaddrof(void);
1611ST_FUNC int gv(TCCState* S, int rc);1452ST_FUNC int gv(int rc);
1612ST_FUNC void gv2(TCCState* S, int rc1, int rc2);1453ST_FUNC void gv2(int rc1, int rc2);
1613ST_FUNC void gen_op(TCCState* S, int op);1454ST_FUNC void gen_op(int op);
1614ST_FUNC int type_size(CType *type, int *a);1455ST_FUNC int type_size(CType *type, int *a);
1615ST_FUNC void mk_pointer(TCCState* S, CType *type);1456ST_FUNC void mk_pointer(CType *type);
1616ST_FUNC void vstore(TCCState* S);1457ST_FUNC void vstore(void);
1617ST_FUNC void inc(TCCState* S, int post, int c);1458ST_FUNC void inc(int post, int c);
1618ST_FUNC void parse_mult_str (TCCState* S, CString *astr, const char *msg);1459ST_FUNC void parse_mult_str (CString *astr, const char *msg);
1619ST_FUNC void parse_asm_str(TCCState* S, CString *astr);1460ST_FUNC void parse_asm_str(CString *astr);
1620ST_FUNC void indir(TCCState* S);1461ST_FUNC void indir(void);
1621ST_FUNC void unary(TCCState* S);1462ST_FUNC void unary(void);
1622ST_FUNC void gexpr(TCCState* S);1463ST_FUNC void gexpr(void);
1623ST_FUNC int expr_const(TCCState* S);1464ST_FUNC int expr_const(void);
1624#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C671465#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C67
1625ST_FUNC Sym *get_sym_ref(TCCState* S, CType *type, Section *sec, unsigned long offset, unsigned long size);1466ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size);
1626#endif1467#endif
1627#if defined TCC_TARGET_X86_64 && !defined TCC_TARGET_PE1468#if defined TCC_TARGET_X86_64 && !defined TCC_TARGET_PE
1628ST_FUNC int classify_x86_64_va_arg(CType *ty);1469ST_FUNC int classify_x86_64_va_arg(CType *ty);
1629#endif1470#endif
1630#ifdef CONFIG_TCC_BCHECK1471#ifdef CONFIG_TCC_BCHECK
1631ST_FUNC void gbound_args(TCCState* S, int nb_args);1472ST_FUNC void gbound_args(int nb_args);
1632ST_DATA int func_bound_add_epilog;1473ST_DATA int func_bound_add_epilog;
1633#endif1474#endif
1634 1475
@@ -1648,51 +1489,51 @@ typedef struct { · 13 unmodified lines
1648 unsigned int n_value; /* value of symbol */1489 unsigned int n_value; /* value of symbol */
1649} Stab_Sym;1490} Stab_Sym;
1650 1491
1651ST_FUNC void tccelf_new(TCCState *S);1492ST_FUNC void tccelf_new(TCCState *s);
1652ST_FUNC void tccelf_delete(TCCState *S);1493ST_FUNC void tccelf_delete(TCCState *s);
1653ST_FUNC void tccelf_stab_new(TCCState *S);1494ST_FUNC void tccelf_stab_new(TCCState *s);
1654ST_FUNC void tccelf_begin_file(TCCState *S);1495ST_FUNC void tccelf_begin_file(TCCState *s1);
1655ST_FUNC void tccelf_end_file(TCCState *S);1496ST_FUNC void tccelf_end_file(TCCState *s1);
1656#ifdef CONFIG_TCC_BCHECK1497#ifdef CONFIG_TCC_BCHECK
1657ST_FUNC void tccelf_bounds_new(TCCState *S);1498ST_FUNC void tccelf_bounds_new(TCCState *s);
1658#endif1499#endif
1659ST_FUNC Section *new_section(TCCState *S, const char *name, int sh_type, int sh_flags);1500ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags);
1660ST_FUNC void section_realloc(TCCState* S, Section *sec, unsigned long new_size);1501ST_FUNC void section_realloc(Section *sec, unsigned long new_size);
1661ST_FUNC size_t section_add(TCCState* S, Section *sec, addr_t size, int align);1502ST_FUNC size_t section_add(Section *sec, addr_t size, int align);
1662ST_FUNC void *section_ptr_add(TCCState* S, Section *sec, addr_t size);1503ST_FUNC void *section_ptr_add(Section *sec, addr_t size);
1663ST_FUNC Section *find_section(TCCState *S, const char *name);1504ST_FUNC Section *find_section(TCCState *s1, const char *name);
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);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);
1665 1506
1666ST_FUNC int put_elf_str(TCCState* S, Section *s, const char *sym);1507ST_FUNC int put_elf_str(Section *s, const char *sym);
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);1508ST_FUNC int put_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);1509ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int shndx, const char *name);
1669ST_FUNC int find_elf_sym(Section *S, const char *name);1510ST_FUNC int find_elf_sym(Section *s, const char *name);
1670ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, int type, int symbol);1511ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, int type, int symbol);
1671ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset, int type, int symbol, addr_t addend);1512ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset, int type, int symbol, addr_t addend);
1672 1513
1673ST_FUNC void put_stabs(TCCState *S, const char *str, int type, int other, int desc, unsigned long value);1514ST_FUNC void put_stabs(TCCState *s1, const char *str, int type, int other, int desc, unsigned long value);
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);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);
1675ST_FUNC void put_stabn(TCCState *S, int type, int other, int desc, int value);1516ST_FUNC void put_stabn(TCCState *s1, int type, int other, int desc, int value);
1676 1517
1677ST_FUNC void resolve_common_syms(TCCState *S);1518ST_FUNC void resolve_common_syms(TCCState *s1);
1678ST_FUNC void relocate_syms(TCCState *S, Section *symtab, int do_resolve);1519ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve);
1679ST_FUNC void relocate_sections(TCCState *S);1520ST_FUNC void relocate_sections(TCCState *s1);
1680 1521
1681ST_FUNC ssize_t full_read(int fd, void *buf, size_t count);1522ST_FUNC ssize_t full_read(int fd, void *buf, size_t count);
1682ST_FUNC void *load_data(TCCState* S, int fd, unsigned long file_offset, unsigned long size);1523ST_FUNC void *load_data(int fd, unsigned long file_offset, unsigned long size);
1683ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h);1524ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h);
1684ST_FUNC int tcc_load_object_file(TCCState *S, int fd, unsigned long file_offset);1525ST_FUNC int tcc_load_object_file(TCCState *s1, int fd, unsigned long file_offset);
1685ST_FUNC int tcc_load_archive(TCCState *S, int fd, int alacarte);1526ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte);
1686ST_FUNC void add_array(TCCState *S, const char *sec, int c);1527ST_FUNC void add_array(TCCState *s1, const char *sec, int c);
1687 1528
1688#if !defined(ELF_OBJ_ONLY) || (defined(TCC_TARGET_MACHO) && defined TCC_IS_NATIVE)1529#if !defined(ELF_OBJ_ONLY) || (defined(TCC_TARGET_MACHO) && defined TCC_IS_NATIVE)
1689ST_FUNC void build_got_entries(TCCState *S);1530ST_FUNC void build_got_entries(TCCState *s1);
1690#endif1531#endif
1691ST_FUNC struct sym_attr *get_sym_attr(TCCState *S, int index, int alloc);1532ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc);
1692ST_FUNC addr_t get_sym_addr(TCCState *S, const char *name, int err, int forc);1533ST_FUNC addr_t get_sym_addr(TCCState *s, const char *name, int err, int forc);
1693ST_FUNC void list_elf_symbols(TCCState *S, void *ctx,1534ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
1694 void (*symbol_cb)(void *ctx, const char *name, const void *val));1535 void (*symbol_cb)(void *ctx, const char *name, const void *val));
1695ST_FUNC int set_global_sym(TCCState *S, const char *name, Section *sec, addr_t offs);1536ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs);
1696 1537
1697/* Browse each elem of type <type> in section <sec> starting at elem <startoff>1538/* Browse each elem of type <type> in section <sec> starting at elem <startoff>
1698 using variable <elem> */1539 using variable <elem> */
@@ -1701,11 +1542,11 @@ ST_FUNC int set_global_sym(TCCState *S, const char *name, Section *sec, addr_t o · 2 unmodified lines
1701 elem < (type *) (sec->data + sec->data_offset); elem++)1542 elem < (type *) (sec->data + sec->data_offset); elem++)
1702 1543
1703#ifndef ELF_OBJ_ONLY1544#ifndef ELF_OBJ_ONLY
1704ST_FUNC int tcc_load_dll(TCCState *S, int fd, const char *filename, int level);1545ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level);
1705ST_FUNC int tcc_load_ldscript(TCCState *S, int fd);1546ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd);
1706#endif1547#endif
1707#ifndef TCC_TARGET_PE1548#ifndef TCC_TARGET_PE
1708ST_FUNC void tcc_add_runtime(TCCState *S);1549ST_FUNC void tcc_add_runtime(TCCState *s1);
1709#endif1550#endif
1710 1551
1711/* ------------ xxx-link.c ------------ */1552/* ------------ xxx-link.c ------------ */
@@ -1723,41 +1564,41 @@ enum gotplt_entry { · 11 unmodified lines
1723ST_FUNC int code_reloc (int reloc_type);1564ST_FUNC int code_reloc (int reloc_type);
1724ST_FUNC int gotplt_entry_type (int reloc_type);1565ST_FUNC int gotplt_entry_type (int reloc_type);
1725#if !defined(TCC_TARGET_MACHO) || defined TCC_IS_NATIVE1566#if !defined(TCC_TARGET_MACHO) || defined TCC_IS_NATIVE
1726ST_FUNC unsigned create_plt_entry(TCCState *S, unsigned got_offset, struct sym_attr *attr);1567ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr);
1727ST_FUNC void relocate_plt(TCCState *S);1568ST_FUNC void relocate_plt(TCCState *s1);
1728#endif1569#endif
1729#endif1570#endif
1730ST_FUNC void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val);1571ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val);
1731 1572
1732/* ------------ xxx-gen.c ------------ */1573/* ------------ xxx-gen.c ------------ */
1733ST_DATA const char * const target_machine_defs;1574ST_DATA const char * const target_machine_defs;
1734ST_DATA const int reg_classes[NB_REGS];1575ST_DATA const int reg_classes[NB_REGS];
1735 1576
1736ST_FUNC void gsym_addr(TCCState* S, int t, int a);1577ST_FUNC void gsym_addr(int t, int a);
1737ST_FUNC void gsym(TCCState* S, int t);1578ST_FUNC void gsym(int t);
1738ST_FUNC void load(TCCState *S, int r, SValue *sv);1579ST_FUNC void load(int r, SValue *sv);
1739ST_FUNC void store(TCCState *S, int r, SValue *v);1580ST_FUNC void store(int r, SValue *v);
1740ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *align, int *regsize);1581ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *align, int *regsize);
1741ST_FUNC void gfunc_call(TCCState *S, int nb_args);1582ST_FUNC void gfunc_call(int nb_args);
1742ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym);1583ST_FUNC void gfunc_prolog(Sym *func_sym);
1743ST_FUNC void gfunc_epilog(TCCState *S);1584ST_FUNC void gfunc_epilog(void);
1744ST_FUNC void gen_fill_nops(TCCState* S, int);1585ST_FUNC void gen_fill_nops(int);
1745ST_FUNC int gjmp(TCCState* S, int t);1586ST_FUNC int gjmp(int t);
1746ST_FUNC void gjmp_addr(TCCState* S, int a);1587ST_FUNC void gjmp_addr(int a);
1747ST_FUNC int gjmp_cond(TCCState* S, int op, int t);1588ST_FUNC int gjmp_cond(int op, int t);
1748ST_FUNC int gjmp_append(TCCState *S, int n, int t);1589ST_FUNC int gjmp_append(int n, int t);
1749ST_FUNC void gen_opi(TCCState* S, int op);1590ST_FUNC void gen_opi(int op);
1750ST_FUNC void gen_opf(TCCState* S, int op);1591ST_FUNC void gen_opf(int op);
1751ST_FUNC void gen_cvt_ftoi(TCCState *S, int t);1592ST_FUNC void gen_cvt_ftoi(int t);
1752ST_FUNC void gen_cvt_itof(TCCState *S, int t);1593ST_FUNC void gen_cvt_itof(int t);
1753ST_FUNC void gen_cvt_ftof(TCCState *S, int t);1594ST_FUNC void gen_cvt_ftof(int t);
1754ST_FUNC void ggoto(TCCState *S);1595ST_FUNC void ggoto(void);
1755#ifndef TCC_TARGET_C671596#ifndef TCC_TARGET_C67
1756ST_FUNC void o(TCCState* S, unsigned int c);1597ST_FUNC void o(unsigned int c);
1757#endif1598#endif
1758ST_FUNC void gen_vla_sp_save(TCCState* S, int addr);1599ST_FUNC void gen_vla_sp_save(int addr);
1759ST_FUNC void gen_vla_sp_restore(TCCState* S, int addr);1600ST_FUNC void gen_vla_sp_restore(int addr);
1760ST_FUNC void gen_vla_alloc(TCCState* S, CType *type, int align);1601ST_FUNC void gen_vla_alloc(CType *type, int align);
1761 1602
1762static inline uint16_t read16le(unsigned char *p) {1603static inline uint16_t read16le(unsigned char *p) {
1763 return p[0] | (uint16_t)p[1] << 8;1604 return p[0] | (uint16_t)p[1] << 8;
@@ -1786,57 +1627,57 @@ static inline void add64le(unsigned char *p, int64_t x) { · 22 unmodified lines
1786 1627
1787/* ------------ i386-gen.c ------------ */1628/* ------------ i386-gen.c ------------ */
1788#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM1629#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM
1789ST_FUNC void g(TCCState* S, int c);1630ST_FUNC void g(int c);
1790ST_FUNC void gen_le16(TCCState* S, int c);1631ST_FUNC void gen_le16(int c);
1791ST_FUNC void gen_le32(TCCState* S, int c);1632ST_FUNC void gen_le32(int c);
1792#endif1633#endif
1793#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_641634#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
1794ST_FUNC void gen_addr32(TCCState* S, int r, Sym *sym, int c);1635ST_FUNC void gen_addr32(int r, Sym *sym, int c);
1795ST_FUNC void gen_addrpc32(TCCState* S, int r, Sym *sym, int c);1636ST_FUNC void gen_addrpc32(int r, Sym *sym, int c);
1796ST_FUNC void gen_cvt_csti(TCCState* S, int t);1637ST_FUNC void gen_cvt_csti(int t);
1797ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv);1638ST_FUNC void gen_increment_tcov (SValue *sv);
1798#endif1639#endif
1799 1640
1800/* ------------ x86_64-gen.c ------------ */1641/* ------------ x86_64-gen.c ------------ */
1801#ifdef TCC_TARGET_X86_641642#ifdef TCC_TARGET_X86_64
1802ST_FUNC void gen_addr64(TCCState* S, int r, Sym *sym, int64_t c);1643ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c);
1803ST_FUNC void gen_opl(TCCState* S, int op);1644ST_FUNC void gen_opl(int op);
1804#ifdef TCC_TARGET_PE1645#ifdef TCC_TARGET_PE
1805ST_FUNC void gen_vla_result(TCCState* S, int addr);1646ST_FUNC void gen_vla_result(int addr);
1806#endif1647#endif
1807ST_FUNC void gen_cvt_sxtw(TCCState *S);1648ST_FUNC void gen_cvt_sxtw(void);
1808ST_FUNC void gen_cvt_csti(TCCState* S, int t);1649ST_FUNC void gen_cvt_csti(int t);
1809#endif1650#endif
1810 1651
1811/* ------------ arm-gen.c ------------ */1652/* ------------ arm-gen.c ------------ */
1812#ifdef TCC_TARGET_ARM1653#ifdef TCC_TARGET_ARM
1813#if defined(TCC_ARM_EABI) && !defined(CONFIG_TCC_ELFINTERP)1654#if defined(TCC_ARM_EABI) && !defined(CONFIG_TCC_ELFINTERP)
1814PUB_FUNC const char *default_elfinterp(TCCState *S);1655PUB_FUNC const char *default_elfinterp(struct TCCState *s);
1815#endif1656#endif
1816ST_FUNC void arm_init(TCCState *S);1657ST_FUNC void arm_init(struct TCCState *s);
1817ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv);1658ST_FUNC void gen_increment_tcov (SValue *sv);
1818#endif1659#endif
1819 1660
1820/* ------------ arm64-gen.c ------------ */1661/* ------------ arm64-gen.c ------------ */
1821#ifdef TCC_TARGET_ARM641662#ifdef TCC_TARGET_ARM64
1822ST_FUNC void gen_opl(TCCState* S, int op);1663ST_FUNC void gen_opl(int op);
1823ST_FUNC void gfunc_return(TCCState *S, CType *func_type);1664ST_FUNC void gfunc_return(CType *func_type);
1824ST_FUNC void gen_va_start(TCCState *S);1665ST_FUNC void gen_va_start(void);
1825ST_FUNC void gen_va_arg(TCCState *S, CType *t);1666ST_FUNC void gen_va_arg(CType *t);
1826ST_FUNC void gen_clear_cache(TCCState *S);1667ST_FUNC void gen_clear_cache(void);
1827ST_FUNC void gen_cvt_sxtw(TCCState *S);1668ST_FUNC void gen_cvt_sxtw(void);
1828ST_FUNC void gen_cvt_csti(TCCState *S, int t);1669ST_FUNC void gen_cvt_csti(int t);
1829ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv);1670ST_FUNC void gen_increment_tcov (SValue *sv);
1830#endif1671#endif
1831 1672
1832/* ------------ riscv64-gen.c ------------ */1673/* ------------ riscv64-gen.c ------------ */
1833#ifdef TCC_TARGET_RISCV641674#ifdef TCC_TARGET_RISCV64
1834ST_FUNC void gen_opl(TCCState* S, int op);1675ST_FUNC void gen_opl(int op);
1835//ST_FUNC void gfunc_return(TCCState *S, CType *func_type);1676//ST_FUNC void gfunc_return(CType *func_type);
1836ST_FUNC void gen_va_start(TCCState *S);1677ST_FUNC void gen_va_start(void);
1837ST_FUNC void arch_transfer_ret_regs(TCCState* S, int);1678ST_FUNC void arch_transfer_ret_regs(int);
1838ST_FUNC void gen_cvt_sxtw(TCCState *S);1679ST_FUNC void gen_cvt_sxtw(void);
1839ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv);1680ST_FUNC void gen_increment_tcov (SValue *sv);
1840#endif1681#endif
1841 1682
1842/* ------------ c67-gen.c ------------ */1683/* ------------ c67-gen.c ------------ */
@@ -1846,44 +1687,44 @@ ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv); · 3 unmodified lines
1846/* ------------ tcccoff.c ------------ */1687/* ------------ tcccoff.c ------------ */
1847 1688
1848#ifdef TCC_TARGET_COFF1689#ifdef TCC_TARGET_COFF
1849ST_FUNC int tcc_output_coff(TCCState *S, FILE *f);1690ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f);
1850ST_FUNC int tcc_load_coff(TCCState *S, int fd);1691ST_FUNC int tcc_load_coff(TCCState * s1, int fd);
1851#endif1692#endif
1852 1693
1853/* ------------ tccasm.c ------------ */1694/* ------------ tccasm.c ------------ */
1854ST_FUNC void asm_instr(TCCState* S);1695ST_FUNC void asm_instr(void);
1855ST_FUNC void asm_global_instr(TCCState* S);1696ST_FUNC void asm_global_instr(void);
1856ST_FUNC int tcc_assemble(TCCState *S, int do_preprocess);1697ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess);
1857#ifdef CONFIG_TCC_ASM1698#ifdef CONFIG_TCC_ASM
1858ST_FUNC int find_constraint(TCCState* S, ASMOperand *operands, int nb_operands, const char *name, const char **pp);1699ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands, const char *name, const char **pp);
1859ST_FUNC Sym* get_asm_sym(TCCState* S, int name, Sym *csym);1700ST_FUNC Sym* get_asm_sym(int name, Sym *csym);
1860ST_FUNC void asm_expr(TCCState *S, ExprValue *pe);1701ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe);
1861ST_FUNC int asm_int_expr(TCCState *S);1702ST_FUNC int asm_int_expr(TCCState *s1);
1862/* ------------ i386-asm.c ------------ */1703/* ------------ i386-asm.c ------------ */
1863ST_FUNC void gen_expr32(TCCState* S, ExprValue *pe);1704ST_FUNC void gen_expr32(ExprValue *pe);
1864#ifdef TCC_TARGET_X86_641705#ifdef TCC_TARGET_X86_64
1865ST_FUNC void gen_expr64(TCCState* S, ExprValue *pe);1706ST_FUNC void gen_expr64(ExprValue *pe);
1866#endif1707#endif
1867ST_FUNC void asm_opcode(TCCState *S, int opcode);1708ST_FUNC void asm_opcode(TCCState *s1, int opcode);
1868ST_FUNC int asm_parse_regvar(TCCState* S, int t);1709ST_FUNC int asm_parse_regvar(int t);
1869ST_FUNC void asm_compute_constraints(TCCState* S, ASMOperand *operands, int nb_operands, int nb_outputs, const uint8_t *clobber_regs, int *pout_reg);1710ST_FUNC void asm_compute_constraints(ASMOperand *operands, int nb_operands, int nb_outputs, const uint8_t *clobber_regs, int *pout_reg);
1870ST_FUNC void subst_asm_operand(TCCState* S, CString *add_str, SValue *sv, int modifier);1711ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier);
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);1712ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, int nb_outputs, int is_output, uint8_t *clobber_regs, int out_reg);
1872ST_FUNC void asm_clobber(TCCState* S, uint8_t *clobber_regs, const char *str);1713ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str);
1873#endif1714#endif
1874 1715
1875/* ------------ tccpe.c -------------- */1716/* ------------ tccpe.c -------------- */
1876#ifdef TCC_TARGET_PE1717#ifdef TCC_TARGET_PE
1877ST_FUNC int pe_load_file(struct TCCState *S, int fd, const char *filename);1718ST_FUNC int pe_load_file(struct TCCState *s1, int fd, const char *filename);
1878ST_FUNC int pe_output_file(TCCState * S, const char *filename);1719ST_FUNC int pe_output_file(TCCState * s1, const char *filename);
1879ST_FUNC int pe_putimport(TCCState *S, int dllindex, const char *name, addr_t value);1720ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t value);
1880#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_641721#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
1881ST_FUNC SValue *pe_getimport(TCCState * S, SValue *sv, SValue *v2);1722ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2);
1882#endif1723#endif
1883#ifdef TCC_TARGET_X86_641724#ifdef TCC_TARGET_X86_64
1884ST_FUNC void pe_add_unwind_data(TCCState* S, unsigned start, unsigned end, unsigned stack);1725ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack);
1885#endif1726#endif
1886PUB_FUNC int tcc_get_dllexports(TCCState* S, const char *filename, char **pp);1727PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp);
1887/* symbol properties stored in Elf32_Sym->st_other */1728/* symbol properties stored in Elf32_Sym->st_other */
1888# define ST_PE_EXPORT 0x101729# define ST_PE_EXPORT 0x10
1889# define ST_PE_IMPORT 0x201730# define ST_PE_IMPORT 0x20
@@ -1893,11 +1734,11 @@ PUB_FUNC int tcc_get_dllexports(TCCState* S, const char *filename, char **pp); · 3 unmodified lines
1893 1734
1894/* ------------ tccmacho.c ----------------- */1735/* ------------ tccmacho.c ----------------- */
1895#ifdef TCC_TARGET_MACHO1736#ifdef TCC_TARGET_MACHO
1896ST_FUNC int macho_output_file(TCCState * S, const char *filename);1737ST_FUNC int macho_output_file(TCCState * s1, const char *filename);
1897ST_FUNC int macho_load_dll(TCCState *S, int fd, const char *filename, int lev);1738ST_FUNC int macho_load_dll(TCCState *s1, int fd, const char *filename, int lev);
1898ST_FUNC int macho_load_tbd(TCCState *S, int fd, const char *filename, int lev);1739ST_FUNC int macho_load_tbd(TCCState *s1, int fd, const char *filename, int lev);
1899#ifdef TCC_IS_NATIVE1740#ifdef TCC_IS_NATIVE
1900ST_FUNC void tcc_add_macos_sdkpath(TCCState* S);1741ST_FUNC void tcc_add_macos_sdkpath(TCCState* s);
1901ST_FUNC const char* macho_tbd_soname(const char* filename);1742ST_FUNC const char* macho_tbd_soname(const char* filename);
1902#endif1743#endif
1903#endif1744#endif
@@ -1914,17 +1755,17 @@ ST_FUNC void dlclose(void *p); · 10 unmodified lines
1914ST_FUNC const char *dlerror(void);1755ST_FUNC const char *dlerror(void);
1915ST_FUNC void *dlsym(void *handle, const char *symbol);1756ST_FUNC void *dlsym(void *handle, const char *symbol);
1916#endif1757#endif
1917ST_FUNC void tcc_run_free(TCCState *S);1758ST_FUNC void tcc_run_free(TCCState *s1);
1918#endif1759#endif
1919 1760
1920/* ------------ tcctools.c ----------------- */1761/* ------------ tcctools.c ----------------- */
1921#if 0 /* included in tcc.c */1762#if 0 /* included in tcc.c */
1922ST_FUNC int tcc_tool_ar(TCCState *S, int argc, char **argv);1763ST_FUNC int tcc_tool_ar(TCCState *s, int argc, char **argv);
1923#ifdef TCC_TARGET_PE1764#ifdef TCC_TARGET_PE
1924ST_FUNC int tcc_tool_impdef(TCCState *S, int argc, char **argv);1765ST_FUNC int tcc_tool_impdef(TCCState *s, int argc, char **argv);
1925#endif1766#endif
1926ST_FUNC void tcc_tool_cross(TCCState *S, char **argv, int option);1767ST_FUNC void tcc_tool_cross(TCCState *s, char **argv, int option);
1927ST_FUNC void gen_makedeps(TCCState *S, const char *target, const char *filename);1768ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename);
1928#endif1769#endif
1929 1770
1930/********************************************************/1771/********************************************************/
@@ -1979,12 +1820,12 @@ ST_FUNC void post_sem(TCCSem *p); · 48 unmodified lines
1979#define total_lines TCC_STATE_VAR(total_lines)1820#define total_lines TCC_STATE_VAR(total_lines)
1980#define total_bytes TCC_STATE_VAR(total_bytes)1821#define total_bytes TCC_STATE_VAR(total_bytes)
1981 1822
1982PUB_FUNC void tcc_enter_state(TCCState *S);1823PUB_FUNC void tcc_enter_state(TCCState *s1);
1983PUB_FUNC void tcc_exit_state(TCCState *S);1824PUB_FUNC void tcc_exit_state(TCCState *s1);
1984 1825
1985/* conditional warning depending on switch */1826/* conditional warning depending on switch */
1986#define tcc_warning_c(sw) TCC_SET_STATE((\1827#define tcc_warning_c(sw) TCC_SET_STATE((\
1987 S->warn_num = offsetof(TCCState, sw) \1828 tcc_state->warn_num = offsetof(TCCState, sw) \
1988 - offsetof(TCCState, warn_none), _tcc_warning))1829 - offsetof(TCCState, warn_none), _tcc_warning))
1989 1830
1990/********************************************************/1831/********************************************************/
@@ -1994,10 +1835,10 @@ PUB_FUNC void tcc_exit_state(TCCState *S); · 3 unmodified lines
1994#undef TCC_SET_STATE1835#undef TCC_SET_STATE
1995 1836
1996#ifdef USING_GLOBALS1837#ifdef USING_GLOBALS
1997# define TCC_STATE_VAR(sym) S->sym1838# define TCC_STATE_VAR(sym) tcc_state->sym
1998# define TCC_SET_STATE(fn) fn1839# define TCC_SET_STATE(fn) fn
1999# undef USING_GLOBALS1840# undef USING_GLOBALS
2000#else1841#else
2001# define TCC_STATE_VAR(sym) S->sym1842# define TCC_STATE_VAR(sym) s1->sym
2002# define TCC_SET_STATE(fn) (tcc_enter_state(S),fn)1843# define TCC_SET_STATE(fn) (tcc_enter_state(s1),fn)
2003#endif1844#endif
tccasm.c+420−418
@@ -22,16 +22,18 @@ · 21 unmodified lines
22#include "tcc.h"22#include "tcc.h"
23#ifdef CONFIG_TCC_ASM23#ifdef CONFIG_TCC_ASM
24 24
25ST_FUNC int asm_get_local_label_name(TCCState *S, unsigned int n)25static Section *last_text_section; /* to handle .previous asm directive */
26
27ST_FUNC int asm_get_local_label_name(TCCState *s1, unsigned int n)
26{28{
27 char buf[64];29 char buf[64];
28 snprintf(buf, sizeof(buf), "L..%u", n);30 snprintf(buf, sizeof(buf), "L..%u", n);
29 return tok_alloc_const(S, buf);31 return tok_alloc_const(buf);
30}32}
31 33
32static int tcc_assemble_internal(TCCState *S, int do_preprocess, int global);34static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global);
33static Sym* asm_new_label(TCCState *S, int label, int is_local);35static Sym* asm_new_label(TCCState *s1, int label, int is_local);
34static Sym* asm_new_label1(TCCState *S, int label, int is_local, int sh_num, int value);36static Sym* asm_new_label1(TCCState *s1, int label, int is_local, int sh_num, int value);
35 37
36/* If a C name has an _ prepended then only asm labels that start38/* If a C name has an _ prepended then only asm labels that start
37 with _ are representable in C, by removing the first _. ASM names39 with _ are representable in C, by removing the first _. ASM names
@@ -39,44 +41,44 @@ static Sym* asm_new_label1(TCCState *S, int label, int is_local, int sh_num, int · 1 unmodified line
39 the global C symbol table to track ASM names as well, so we need to41 the global C symbol table to track ASM names as well, so we need to
40 transform those into ones that don't conflict with a C name,42 transform those into ones that don't conflict with a C name,
41 so prepend a '.' for them, but force the ELF asm name to be set. */43 so prepend a '.' for them, but force the ELF asm name to be set. */
42static int asm2cname(TCCState* S, int v, int *addeddot)44static int asm2cname(int v, int *addeddot)
43{45{
44 const char *name;46 const char *name;
45 *addeddot = 0;47 *addeddot = 0;
46 if (!S->leading_underscore)48 if (!tcc_state->leading_underscore)
47 return v;49 return v;
48 name = get_tok_str(S, v, NULL);50 name = get_tok_str(v, NULL);
49 if (!name)51 if (!name)
50 return v;52 return v;
51 if (name[0] == '_') {53 if (name[0] == '_') {
52 v = tok_alloc_const(S, name + 1);54 v = tok_alloc_const(name + 1);
53 } else if (!strchr(name, '.')) {55 } else if (!strchr(name, '.')) {
54 char newname[256];56 char newname[256];
55 snprintf(newname, sizeof newname, ".%s", name);57 snprintf(newname, sizeof newname, ".%s", name);
56 v = tok_alloc_const(S, newname);58 v = tok_alloc_const(newname);
57 *addeddot = 1;59 *addeddot = 1;
58 }60 }
59 return v;61 return v;
60}62}
61 63
62static Sym *asm_label_find(TCCState* S, int v)64static Sym *asm_label_find(int v)
63{65{
64 Sym *sym;66 Sym *sym;
65 int addeddot;67 int addeddot;
66 v = asm2cname(S, v, &addeddot);68 v = asm2cname(v, &addeddot);
67 sym = sym_find(S, v);69 sym = sym_find(v);
68 while (sym && sym->sym_scope && !(sym->type.t & VT_STATIC))70 while (sym && sym->sym_scope && !(sym->type.t & VT_STATIC))
69 sym = sym->prev_tok;71 sym = sym->prev_tok;
70 return sym;72 return sym;
71}73}
72 74
73static Sym *asm_label_push(TCCState* S, int v)75static Sym *asm_label_push(int v)
74{76{
75 int addeddot, v2 = asm2cname(S, v, &addeddot);77 int addeddot, v2 = asm2cname(v, &addeddot);
76 /* We always add VT_EXTERN, for sym definition that's tentative78 /* We always add VT_EXTERN, for sym definition that's tentative
77 (for .set, removed for real defs), for mere references it's correct79 (for .set, removed for real defs), for mere references it's correct
78 as is. */80 as is. */
79 Sym *sym = global_identifier_push(S, v2, VT_ASM | VT_EXTERN | VT_STATIC, 0);81 Sym *sym = global_identifier_push(v2, VT_ASM | VT_EXTERN | VT_STATIC, 0);
80 if (addeddot)82 if (addeddot)
81 sym->asm_label = v;83 sym->asm_label = v;
82 return sym;84 return sym;
@@ -92,55 +94,55 @@ static Sym *asm_label_push(TCCState* S, int v) · 9 unmodified lines
92 are anonymous in C, in this case CSYM can be used to transfer94 are anonymous in C, in this case CSYM can be used to transfer
93 all information from that symbol to the (possibly newly created)95 all information from that symbol to the (possibly newly created)
94 asm symbol. */96 asm symbol. */
95ST_FUNC Sym* get_asm_sym(TCCState* S, int name, Sym *csym)97ST_FUNC Sym* get_asm_sym(int name, Sym *csym)
96{98{
97 Sym *sym = asm_label_find(S, name);99 Sym *sym = asm_label_find(name);
98 if (!sym) {100 if (!sym) {
99 sym = asm_label_push(S, name);101 sym = asm_label_push(name);
100 if (csym)102 if (csym)
101 sym->c = csym->c;103 sym->c = csym->c;
102 }104 }
103 return sym;105 return sym;
104}106}
105 107
106static Sym* asm_section_sym(TCCState *S, Section *sec)108static Sym* asm_section_sym(TCCState *s1, Section *sec)
107{109{
108 char buf[100]; int label; Sym *sym;110 char buf[100]; int label; Sym *sym;
109 snprintf(buf, sizeof buf, "L.%s", sec->name);111 snprintf(buf, sizeof buf, "L.%s", sec->name);
110 label = tok_alloc_const(S, buf);112 label = tok_alloc_const(buf);
111 sym = asm_label_find(S, label);113 sym = asm_label_find(label);
112 return sym ? sym : asm_new_label1(S, label, 1, sec->sh_num, 0);114 return sym ? sym : asm_new_label1(s1, label, 1, sec->sh_num, 0);
113}115}
114 116
115/* We do not use the C expression parser to handle symbols. Maybe the117/* We do not use the C expression parser to handle symbols. Maybe the
116 C expression parser could be tweaked to do so. */118 C expression parser could be tweaked to do so. */
117 119
118static void asm_expr_unary(TCCState *S, ExprValue *pe)120static void asm_expr_unary(TCCState *s1, ExprValue *pe)
119{121{
120 Sym *sym;122 Sym *sym;
121 int op, label;123 int op, label;
122 uint64_t n;124 uint64_t n;
123 const char *p;125 const char *p;
124 126
125 switch(S->tccpp_tok) {127 switch(tok) {
126 case TOK_PPNUM:128 case TOK_PPNUM:
127 p = S->tccpp_tokc.str.data;129 p = tokc.str.data;
128 n = strtoull(p, (char **)&p, 0);130 n = strtoull(p, (char **)&p, 0);
129 if (*p == 'b' || *p == 'f') {131 if (*p == 'b' || *p == 'f') {
130 /* backward or forward label */132 /* backward or forward label */
131 label = asm_get_local_label_name(S, n);133 label = asm_get_local_label_name(s1, n);
132 sym = asm_label_find(S, label);134 sym = asm_label_find(label);
133 if (*p == 'b') {135 if (*p == 'b') {
134 /* backward : find the last corresponding defined label */136 /* backward : find the last corresponding defined label */
135 if (sym && (!sym->c || elfsym(S, sym)->st_shndx == SHN_UNDEF))137 if (sym && (!sym->c || elfsym(sym)->st_shndx == SHN_UNDEF))
136 sym = sym->prev_tok;138 sym = sym->prev_tok;
137 if (!sym)139 if (!sym)
138 tcc_error(S, "local label '%d' not found backward", (int)n);140 tcc_error("local label '%d' not found backward", (int)n);
139 } else {141 } else {
140 /* forward */142 /* forward */
141 if (!sym || (sym->c && elfsym(S, sym)->st_shndx != SHN_UNDEF)) {143 if (!sym || (sym->c && elfsym(sym)->st_shndx != SHN_UNDEF)) {
142 /* if the last label is defined, then define a new one */144 /* if the last label is defined, then define a new one */
143 sym = asm_label_push(S, label);145 sym = asm_label_push(label);
144 }146 }
145 }147 }
146 pe->v = 0;148 pe->v = 0;
@@ -151,21 +153,21 @@ static void asm_expr_unary(TCCState *S, ExprValue *pe) · 4 unmodified lines
151 pe->sym = NULL;153 pe->sym = NULL;
152 pe->pcrel = 0;154 pe->pcrel = 0;
153 } else {155 } else {
154 tcc_error(S, "invalid number syntax");156 tcc_error("invalid number syntax");
155 }157 }
156 next(S);158 next();
157 break;159 break;
158 case '+':160 case '+':
159 next(S);161 next();
160 asm_expr_unary(S, pe);162 asm_expr_unary(s1, pe);
161 break;163 break;
162 case '-':164 case '-':
163 case '~':165 case '~':
164 op = S->tccpp_tok;166 op = tok;
165 next(S);167 next();
166 asm_expr_unary(S, pe);168 asm_expr_unary(s1, pe);
167 if (pe->sym)169 if (pe->sym)
168 tcc_error(S, "invalid operation with label");170 tcc_error("invalid operation with label");
169 if (op == '-')171 if (op == '-')
170 pe->v = -pe->v;172 pe->v = -pe->v;
171 else173 else
@@ -173,28 +175,28 @@ static void asm_expr_unary(TCCState *S, ExprValue *pe) · 1 unmodified line
173 break;175 break;
174 case TOK_CCHAR:176 case TOK_CCHAR:
175 case TOK_LCHAR:177 case TOK_LCHAR:
176 pe->v = S->tccpp_tokc.i;178 pe->v = tokc.i;
177 pe->sym = NULL;179 pe->sym = NULL;
178 pe->pcrel = 0;180 pe->pcrel = 0;
179 next(S);181 next();
180 break;182 break;
181 case '(':183 case '(':
182 next(S);184 next();
183 asm_expr(S, pe);185 asm_expr(s1, pe);
184 skip(S, ')');186 skip(')');
185 break;187 break;
186 case '.':188 case '.':
187 pe->v = S->tccgen_ind;189 pe->v = ind;
188 pe->sym = asm_section_sym(S, cur_text_section);190 pe->sym = asm_section_sym(s1, cur_text_section);
189 pe->pcrel = 0;191 pe->pcrel = 0;
190 next(S);192 next();
191 break;193 break;
192 default:194 default:
193 if (S->tccpp_tok >= TOK_IDENT) {195 if (tok >= TOK_IDENT) {
194 ElfSym *esym;196 ElfSym *esym;
195 /* label case : if the label was not found, add one */197 /* label case : if the label was not found, add one */
196 sym = get_asm_sym(S, S->tccpp_tok, NULL);198 sym = get_asm_sym(tok, NULL);
197 esym = elfsym(S, sym);199 esym = elfsym(sym);
198 if (esym && esym->st_shndx == SHN_ABS) {200 if (esym && esym->st_shndx == SHN_ABS) {
199 /* if absolute symbol, no need to put a symbol value */201 /* if absolute symbol, no need to put a symbol value */
200 pe->v = esym->st_value;202 pe->v = esym->st_value;
@@ -205,29 +207,29 @@ static void asm_expr_unary(TCCState *S, ExprValue *pe) · 4 unmodified lines
205 pe->sym = sym;207 pe->sym = sym;
206 pe->pcrel = 0;208 pe->pcrel = 0;
207 }209 }
208 next(S);210 next();
209 } else {211 } else {
210 tcc_error(S, "bad expression syntax [%s]", get_tok_str(S, S->tccpp_tok, &S->tccpp_tokc));212 tcc_error("bad expression syntax [%s]", get_tok_str(tok, &tokc));
211 }213 }
212 break;214 break;
213 }215 }
214}216}
215 217
216static void asm_expr_prod(TCCState *S, ExprValue *pe)218static void asm_expr_prod(TCCState *s1, ExprValue *pe)
217{219{
218 int op;220 int op;
219 ExprValue e2;221 ExprValue e2;
220 222
221 asm_expr_unary(S, pe);223 asm_expr_unary(s1, pe);
222 for(;;) {224 for(;;) {
223 op = S->tccpp_tok;225 op = tok;
224 if (op != '*' && op != '/' && op != '%' && 226 if (op != '*' && op != '/' && op != '%' &&
225 op != TOK_SHL && op != TOK_SAR)227 op != TOK_SHL && op != TOK_SAR)
226 break;228 break;
227 next(S);229 next();
228 asm_expr_unary(S, &e2);230 asm_expr_unary(s1, &e2);
229 if (pe->sym || e2.sym)231 if (pe->sym || e2.sym)
230 tcc_error(S, "invalid operation with label");232 tcc_error("invalid operation with label");
231 switch(op) {233 switch(op) {
232 case '*':234 case '*':
233 pe->v *= e2.v;235 pe->v *= e2.v;
@@ -235,7 +237,7 @@ static void asm_expr_prod(TCCState *S, ExprValue *pe) · 1 unmodified line
235 case '/': 237 case '/':
236 if (e2.v == 0) {238 if (e2.v == 0) {
237 div_error:239 div_error:
238 tcc_error(S, "division by zero");240 tcc_error("division by zero");
239 }241 }
240 pe->v /= e2.v;242 pe->v /= e2.v;
241 break;243 break;
@@ -255,20 +257,20 @@ static void asm_expr_prod(TCCState *S, ExprValue *pe) · 13 unmodified lines
255 }257 }
256}258}
257 259
258static void asm_expr_logic(TCCState *S, ExprValue *pe)260static void asm_expr_logic(TCCState *s1, ExprValue *pe)
259{261{
260 int op;262 int op;
261 ExprValue e2;263 ExprValue e2;
262 264
263 asm_expr_prod(S, pe);265 asm_expr_prod(s1, pe);
264 for(;;) {266 for(;;) {
265 op = S->tccpp_tok;267 op = tok;
266 if (op != '&' && op != '|' && op != '^')268 if (op != '&' && op != '|' && op != '^')
267 break;269 break;
268 next(S);270 next();
269 asm_expr_prod(S, &e2);271 asm_expr_prod(s1, &e2);
270 if (pe->sym || e2.sym)272 if (pe->sym || e2.sym)
271 tcc_error(S, "invalid operation with label");273 tcc_error("invalid operation with label");
272 switch(op) {274 switch(op) {
273 case '&':275 case '&':
274 pe->v &= e2.v;276 pe->v &= e2.v;
@@ -284,18 +286,18 @@ static void asm_expr_logic(TCCState *S, ExprValue *pe) · 9 unmodified lines
284 }286 }
285}287}
286 288
287static inline void asm_expr_sum(TCCState *S, ExprValue *pe)289static inline void asm_expr_sum(TCCState *s1, ExprValue *pe)
288{290{
289 int op;291 int op;
290 ExprValue e2;292 ExprValue e2;
291 293
292 asm_expr_logic(S, pe);294 asm_expr_logic(s1, pe);
293 for(;;) {295 for(;;) {
294 op = S->tccpp_tok;296 op = tok;
295 if (op != '+' && op != '-')297 if (op != '+' && op != '-')
296 break;298 break;
297 next(S);299 next();
298 asm_expr_logic(S, &e2);300 asm_expr_logic(s1, &e2);
299 if (op == '+') {301 if (op == '+') {
300 if (pe->sym != NULL && e2.sym != NULL)302 if (pe->sym != NULL && e2.sym != NULL)
301 goto cannot_relocate;303 goto cannot_relocate;
@@ -313,8 +315,8 @@ static inline void asm_expr_sum(TCCState *S, ExprValue *pe) · 11 unmodified lines
313 pe->sym = NULL; /* same symbols can be subtracted to NULL */315 pe->sym = NULL; /* same symbols can be subtracted to NULL */
314 } else {316 } else {
315 ElfSym *esym1, *esym2;317 ElfSym *esym1, *esym2;
316 esym1 = elfsym(S, pe->sym);318 esym1 = elfsym(pe->sym);
317 esym2 = elfsym(S, e2.sym);319 esym2 = elfsym(e2.sym);
318 if (esym1 && esym1->st_shndx == esym2->st_shndx320 if (esym1 && esym1->st_shndx == esym2->st_shndx
319 && esym1->st_shndx != SHN_UNDEF) {321 && esym1->st_shndx != SHN_UNDEF) {
320 /* we also accept defined symbols in the same section */322 /* we also accept defined symbols in the same section */
@@ -323,33 +325,33 @@ static inline void asm_expr_sum(TCCState *S, ExprValue *pe) · 2 unmodified lines
323 } else if (esym2->st_shndx == cur_text_section->sh_num) {325 } else if (esym2->st_shndx == cur_text_section->sh_num) {
324 /* When subtracting a defined symbol in current section326 /* When subtracting a defined symbol in current section
325 this actually makes the value PC-relative. */327 this actually makes the value PC-relative. */
326 pe->v -= esym2->st_value - S->tccgen_ind - 4;328 pe->v -= esym2->st_value - ind - 4;
327 pe->pcrel = 1;329 pe->pcrel = 1;
328 e2.sym = NULL;330 e2.sym = NULL;
329 } else {331 } else {
330cannot_relocate:332cannot_relocate:
331 tcc_error(S, "invalid operation with label");333 tcc_error("invalid operation with label");
332 }334 }
333 }335 }
334 }336 }
335 }337 }
336}338}
337 339
338static inline void asm_expr_cmp(TCCState *S, ExprValue *pe)340static inline void asm_expr_cmp(TCCState *s1, ExprValue *pe)
339{341{
340 int op;342 int op;
341 ExprValue e2;343 ExprValue e2;
342 344
343 asm_expr_sum(S, pe);345 asm_expr_sum(s1, pe);
344 for(;;) {346 for(;;) {
345 op = S->tccpp_tok;347 op = tok;
346 if (op != TOK_EQ && op != TOK_NE348 if (op != TOK_EQ && op != TOK_NE
347 && (op > TOK_GT || op < TOK_ULE))349 && (op > TOK_GT || op < TOK_ULE))
348 break;350 break;
349 next(S);351 next();
350 asm_expr_sum(S, &e2);352 asm_expr_sum(s1, &e2);
351 if (pe->sym || e2.sym)353 if (pe->sym || e2.sym)
352 tcc_error(S, "invalid operation with label");354 tcc_error("invalid operation with label");
353 switch(op) {355 switch(op) {
354 case TOK_EQ:356 case TOK_EQ:
355 pe->v = pe->v == e2.v;357 pe->v = pe->v == e2.v;
@@ -377,29 +379,29 @@ static inline void asm_expr_cmp(TCCState *S, ExprValue *pe) · 21 unmodified lines
377 }379 }
378}380}
379 381
380ST_FUNC void asm_expr(TCCState *S, ExprValue *pe)382ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe)
381{383{
382 asm_expr_cmp(S, pe);384 asm_expr_cmp(s1, pe);
383}385}
384 386
385ST_FUNC int asm_int_expr(TCCState *S)387ST_FUNC int asm_int_expr(TCCState *s1)
386{388{
387 ExprValue e;389 ExprValue e;
388 asm_expr(S, &e);390 asm_expr(s1, &e);
389 if (e.sym)391 if (e.sym)
390 expect(S, "constant");392 expect("constant");
391 return e.v;393 return e.v;
392}394}
393 395
394static Sym* asm_new_label1(TCCState *S, int label, int is_local,396static Sym* asm_new_label1(TCCState *s1, int label, int is_local,
395 int sh_num, int value)397 int sh_num, int value)
396{398{
397 Sym *sym;399 Sym *sym;
398 ElfSym *esym;400 ElfSym *esym;
399 401
400 sym = asm_label_find(S, label);402 sym = asm_label_find(label);
401 if (sym) {403 if (sym) {
402 esym = elfsym(S, sym);404 esym = elfsym(sym);
403 /* A VT_EXTERN symbol, even if it has a section is considered405 /* A VT_EXTERN symbol, even if it has a section is considered
404 overridable. This is how we "define" .set targets. Real406 overridable. This is how we "define" .set targets. Real
405 definitions won't have VT_EXTERN set. */407 definitions won't have VT_EXTERN set. */
@@ -409,16 +411,16 @@ static Sym* asm_new_label1(TCCState *S, int label, int is_local, · 3 unmodified lines
409 && (is_local == 1 || (sym->type.t & VT_EXTERN)))411 && (is_local == 1 || (sym->type.t & VT_EXTERN)))
410 goto new_label;412 goto new_label;
411 if (!(sym->type.t & VT_EXTERN))413 if (!(sym->type.t & VT_EXTERN))
412 tcc_error(S, "assembler label '%s' already defined",414 tcc_error("assembler label '%s' already defined",
413 get_tok_str(S, label, NULL));415 get_tok_str(label, NULL));
414 }416 }
415 } else {417 } else {
416 new_label:418 new_label:
417 sym = asm_label_push(S, label);419 sym = asm_label_push(label);
418 }420 }
419 if (!sym->c)421 if (!sym->c)
420 put_extern_sym2(S, sym, SHN_UNDEF, 0, 0, 1);422 put_extern_sym2(sym, SHN_UNDEF, 0, 0, 1);
421 esym = elfsym(S, sym);423 esym = elfsym(sym);
422 esym->st_shndx = sh_num;424 esym->st_shndx = sh_num;
423 esym->st_value = value;425 esym->st_value = value;
424 if (is_local != 2)426 if (is_local != 2)
@@ -426,61 +428,61 @@ static Sym* asm_new_label1(TCCState *S, int label, int is_local, · 1 unmodified line
426 return sym;428 return sym;
427}429}
428 430
429static Sym* asm_new_label(TCCState *S, int label, int is_local)431static Sym* asm_new_label(TCCState *s1, int label, int is_local)
430{432{
431 return asm_new_label1(S, label, is_local, cur_text_section->sh_num, S->tccgen_ind);433 return asm_new_label1(s1, label, is_local, cur_text_section->sh_num, ind);
432}434}
433 435
434/* Set the value of LABEL to that of some expression (possibly436/* Set the value of LABEL to that of some expression (possibly
435 involving other symbols). LABEL can be overwritten later still. */437 involving other symbols). LABEL can be overwritten later still. */
436static Sym* set_symbol(TCCState *S, int label)438static Sym* set_symbol(TCCState *s1, int label)
437{439{
438 long n;440 long n;
439 ExprValue e;441 ExprValue e;
440 Sym *sym;442 Sym *sym;
441 ElfSym *esym;443 ElfSym *esym;
442 next(S);444 next();
443 asm_expr(S, &e);445 asm_expr(s1, &e);
444 n = e.v;446 n = e.v;
445 esym = elfsym(S, e.sym);447 esym = elfsym(e.sym);
446 if (esym)448 if (esym)
447 n += esym->st_value;449 n += esym->st_value;
448 sym = asm_new_label1(S, label, 2, esym ? esym->st_shndx : SHN_ABS, n);450 sym = asm_new_label1(s1, label, 2, esym ? esym->st_shndx : SHN_ABS, n);
449 elfsym(S, sym)->st_other |= ST_ASM_SET;451 elfsym(sym)->st_other |= ST_ASM_SET;
450 return sym;452 return sym;
451}453}
452 454
453static void use_section1(TCCState *S, Section *sec)455static void use_section1(TCCState *s1, Section *sec)
454{456{
455 cur_text_section->data_offset = S->tccgen_ind;457 cur_text_section->data_offset = ind;
456 cur_text_section = sec;458 cur_text_section = sec;
457 S->tccgen_ind = cur_text_section->data_offset;459 ind = cur_text_section->data_offset;
458}460}
459 461
460static void use_section(TCCState *S, const char *name)462static void use_section(TCCState *s1, const char *name)
461{463{
462 Section *sec;464 Section *sec;
463 sec = find_section(S, name);465 sec = find_section(s1, name);
464 use_section1(S, sec);466 use_section1(s1, sec);
465}467}
466 468
467static void push_section(TCCState *S, const char *name)469static void push_section(TCCState *s1, const char *name)
468{470{
469 Section *sec = find_section(S, name);471 Section *sec = find_section(s1, name);
470 sec->prev = cur_text_section;472 sec->prev = cur_text_section;
471 use_section1(S, sec);473 use_section1(s1, sec);
472}474}
473 475
474static void pop_section(TCCState *S)476static void pop_section(TCCState *s1)
475{477{
476 Section *prev = cur_text_section->prev;478 Section *prev = cur_text_section->prev;
477 if (!prev)479 if (!prev)
478 tcc_error(S, ".popsection without .pushsection");480 tcc_error(".popsection without .pushsection");
479 cur_text_section->prev = NULL;481 cur_text_section->prev = NULL;
480 use_section1(S, prev);482 use_section1(s1, prev);
481}483}
482 484
483static void asm_parse_directive(TCCState *S, int global)485static void asm_parse_directive(TCCState *s1, int global)
484{486{
485 int n, offset, v, size, tok1;487 int n, offset, v, size, tok1;
486 Section *sec;488 Section *sec;
@@ -488,27 +490,27 @@ static void asm_parse_directive(TCCState *S, int global) · 1 unmodified line
488 490
489 /* assembler directive */491 /* assembler directive */
490 sec = cur_text_section;492 sec = cur_text_section;
491 switch(S->tccpp_tok) {493 switch(tok) {
492 case TOK_ASMDIR_align:494 case TOK_ASMDIR_align:
493 case TOK_ASMDIR_balign:495 case TOK_ASMDIR_balign:
494 case TOK_ASMDIR_p2align:496 case TOK_ASMDIR_p2align:
495 case TOK_ASMDIR_skip:497 case TOK_ASMDIR_skip:
496 case TOK_ASMDIR_space:498 case TOK_ASMDIR_space:
497 tok1 = S->tccpp_tok;499 tok1 = tok;
498 next(S);500 next();
499 n = asm_int_expr(S);501 n = asm_int_expr(s1);
500 if (tok1 == TOK_ASMDIR_p2align)502 if (tok1 == TOK_ASMDIR_p2align)
501 {503 {
502 if (n < 0 || n > 30)504 if (n < 0 || n > 30)
503 tcc_error(S, "invalid p2align, must be between 0 and 30");505 tcc_error("invalid p2align, must be between 0 and 30");
504 n = 1 << n;506 n = 1 << n;
505 tok1 = TOK_ASMDIR_align;507 tok1 = TOK_ASMDIR_align;
506 }508 }
507 if (tok1 == TOK_ASMDIR_align || tok1 == TOK_ASMDIR_balign) {509 if (tok1 == TOK_ASMDIR_align || tok1 == TOK_ASMDIR_balign) {
508 if (n < 0 || (n & (n-1)) != 0)510 if (n < 0 || (n & (n-1)) != 0)
509 tcc_error(S, "alignment must be a positive power of two");511 tcc_error("alignment must be a positive power of two");
510 offset = (S->tccgen_ind + n - 1) & -n;512 offset = (ind + n - 1) & -n;
511 size = offset - S->tccgen_ind;513 size = offset - ind;
512 /* the section must have a compatible alignment */514 /* the section must have a compatible alignment */
513 if (sec->sh_addralign < n)515 if (sec->sh_addralign < n)
514 sec->sh_addralign = n;516 sec->sh_addralign = n;
@@ -518,47 +520,47 @@ static void asm_parse_directive(TCCState *S, int global) · 3 unmodified lines
518 size = n;520 size = n;
519 }521 }
520 v = 0;522 v = 0;
521 if (S->tccpp_tok == ',') {523 if (tok == ',') {
522 next(S);524 next();
523 v = asm_int_expr(S);525 v = asm_int_expr(s1);
524 }526 }
525 zero_pad:527 zero_pad:
526 if (sec->sh_type != SHT_NOBITS) {528 if (sec->sh_type != SHT_NOBITS) {
527 sec->data_offset = S->tccgen_ind;529 sec->data_offset = ind;
528 ptr = section_ptr_add(S, sec, size);530 ptr = section_ptr_add(sec, size);
529 memset(ptr, v, size);531 memset(ptr, v, size);
530 }532 }
531 S->tccgen_ind += size;533 ind += size;
532 break;534 break;
533 case TOK_ASMDIR_quad:535 case TOK_ASMDIR_quad:
534#ifdef TCC_TARGET_X86_64536#ifdef TCC_TARGET_X86_64
535 size = 8;537 size = 8;
536 goto asm_data;538 goto asm_data;
537#else539#else
538 next(S);540 next();
539 for(;;) {541 for(;;) {
540 uint64_t vl;542 uint64_t vl;
541 const char *p;543 const char *p;
542 544
543 p = S->tccpp_tokc.str.data;545 p = tokc.str.data;
544 if (S->tccpp_tok != TOK_PPNUM) {546 if (tok != TOK_PPNUM) {
545 error_constant:547 error_constant:
546 tcc_error(S, "64 bit constant");548 tcc_error("64 bit constant");
547 }549 }
548 vl = strtoll(p, (char **)&p, 0);550 vl = strtoll(p, (char **)&p, 0);
549 if (*p != '\0')551 if (*p != '\0')
550 goto error_constant;552 goto error_constant;
551 next(S);553 next();
552 if (sec->sh_type != SHT_NOBITS) {554 if (sec->sh_type != SHT_NOBITS) {
553 /* XXX: endianness */555 /* XXX: endianness */
554 gen_le32(S, vl);556 gen_le32(vl);
555 gen_le32(S, vl >> 32);557 gen_le32(vl >> 32);
556 } else {558 } else {
557 S->tccgen_ind += 8;559 ind += 8;
558 }560 }
559 if (S->tccpp_tok != ',')561 if (tok != ',')
560 break;562 break;
561 next(S);563 next();
562 }564 }
563 break;565 break;
564#endif566#endif
@@ -573,57 +575,57 @@ static void asm_parse_directive(TCCState *S, int global) · 8 unmodified lines
573 case TOK_ASMDIR_int:575 case TOK_ASMDIR_int:
574 size = 4;576 size = 4;
575 asm_data:577 asm_data:
576 next(S);578 next();
577 for(;;) {579 for(;;) {
578 ExprValue e;580 ExprValue e;
579 asm_expr(S, &e);581 asm_expr(s1, &e);
580 if (sec->sh_type != SHT_NOBITS) {582 if (sec->sh_type != SHT_NOBITS) {
581 if (size == 4) {583 if (size == 4) {
582 gen_expr32(S, &e);584 gen_expr32(&e);
583#ifdef TCC_TARGET_X86_64585#ifdef TCC_TARGET_X86_64
584 } else if (size == 8) {586 } else if (size == 8) {
585 gen_expr64(S, &e);587 gen_expr64(&e);
586#endif588#endif
587 } else {589 } else {
588 if (e.sym)590 if (e.sym)
589 expect(S, "constant");591 expect("constant");
590 if (size == 1)592 if (size == 1)
591 g(S, e.v);593 g(e.v);
592 else594 else
593 gen_le16(S, e.v);595 gen_le16(e.v);
594 }596 }
595 } else {597 } else {
596 S->tccgen_ind += size;598 ind += size;
597 }599 }
598 if (S->tccpp_tok != ',')600 if (tok != ',')
599 break;601 break;
600 next(S);602 next();
601 }603 }
602 break;604 break;
603 case TOK_ASMDIR_fill:605 case TOK_ASMDIR_fill:
604 {606 {
605 int repeat, size, val, i, j;607 int repeat, size, val, i, j;
606 uint8_t repeat_buf[8];608 uint8_t repeat_buf[8];
607 next(S);609 next();
608 repeat = asm_int_expr(S);610 repeat = asm_int_expr(s1);
609 if (repeat < 0) {611 if (repeat < 0) {
610 tcc_error(S, "repeat < 0; .fill ignored");612 tcc_error("repeat < 0; .fill ignored");
611 break;613 break;
612 }614 }
613 size = 1;615 size = 1;
614 val = 0;616 val = 0;
615 if (S->tccpp_tok == ',') {617 if (tok == ',') {
616 next(S);618 next();
617 size = asm_int_expr(S);619 size = asm_int_expr(s1);
618 if (size < 0) {620 if (size < 0) {
619 tcc_error(S, "size < 0; .fill ignored");621 tcc_error("size < 0; .fill ignored");
620 break;622 break;
621 }623 }
622 if (size > 8)624 if (size > 8)
623 size = 8;625 size = 8;
624 if (S->tccpp_tok == ',') {626 if (tok == ',') {
625 next(S);627 next();
626 val = asm_int_expr(S);628 val = asm_int_expr(s1);
627 }629 }
628 }630 }
629 /* XXX: endianness */631 /* XXX: endianness */
@@ -637,7 +639,7 @@ static void asm_parse_directive(TCCState *S, int global) · 7 unmodified lines
637 repeat_buf[7] = 0;639 repeat_buf[7] = 0;
638 for(i = 0; i < repeat; i++) {640 for(i = 0; i < repeat; i++) {
639 for(j = 0; j < size; j++) {641 for(j = 0; j < size; j++) {
640 g(S, repeat_buf[j]);642 g(repeat_buf[j]);
641 }643 }
642 }644 }
643 }645 }
@@ -646,24 +648,24 @@ static void asm_parse_directive(TCCState *S, int global) · 2 unmodified lines
646 {648 {
647 int repeat;649 int repeat;
648 TokenString *init_str;650 TokenString *init_str;
649 next(S);651 next();
650 repeat = asm_int_expr(S);652 repeat = asm_int_expr(s1);
651 init_str = tok_str_alloc(S);653 init_str = tok_str_alloc();
652 while (next(S), S->tccpp_tok != TOK_ASMDIR_endr) {654 while (next(), tok != TOK_ASMDIR_endr) {
653 if (S->tccpp_tok == CH_EOF)655 if (tok == CH_EOF)
654 tcc_error(S, "we at end of file, .endr not found");656 tcc_error("we at end of file, .endr not found");
655 tok_str_add_tok(S, init_str);657 tok_str_add_tok(init_str);
656 }658 }
657 tok_str_add(S, init_str, -1);659 tok_str_add(init_str, -1);
658 tok_str_add(S, init_str, 0);660 tok_str_add(init_str, 0);
659 begin_macro(S, init_str, 1);661 begin_macro(init_str, 1);
660 while (repeat-- > 0) {662 while (repeat-- > 0) {
661 tcc_assemble_internal(S, (S->tccpp_parse_flags & PARSE_FLAG_PREPROCESS),663 tcc_assemble_internal(s1, (parse_flags & PARSE_FLAG_PREPROCESS),
662 global);664 global);
663 S->tccpp_macro_ptr = init_str->str;665 macro_ptr = init_str->str;
664 }666 }
665 end_macro(S);667 end_macro();
666 next(S);668 next();
667 break;669 break;
668 }670 }
669 case TOK_ASMDIR_org:671 case TOK_ASMDIR_org:
@@ -671,49 +673,49 @@ static void asm_parse_directive(TCCState *S, int global) · 1 unmodified line
671 unsigned long n;673 unsigned long n;
672 ExprValue e;674 ExprValue e;
673 ElfSym *esym;675 ElfSym *esym;
674 next(S);676 next();
675 asm_expr(S, &e);677 asm_expr(s1, &e);
676 n = e.v;678 n = e.v;
677 esym = elfsym(S, e.sym);679 esym = elfsym(e.sym);
678 if (esym) {680 if (esym) {
679 if (esym->st_shndx != cur_text_section->sh_num)681 if (esym->st_shndx != cur_text_section->sh_num)
680 expect(S, "constant or same-section symbol");682 expect("constant or same-section symbol");
681 n += esym->st_value;683 n += esym->st_value;
682 }684 }
683 if (n < S->tccgen_ind)685 if (n < ind)
684 tcc_error(S, "attempt to .org backwards");686 tcc_error("attempt to .org backwards");
685 v = 0;687 v = 0;
686 size = n - S->tccgen_ind;688 size = n - ind;
687 goto zero_pad;689 goto zero_pad;
688 }690 }
689 break;691 break;
690 case TOK_ASMDIR_set:692 case TOK_ASMDIR_set:
691 next(S);693 next();
692 tok1 = S->tccpp_tok;694 tok1 = tok;
693 next(S);695 next();
694 /* Also accept '.set stuff', but don't do anything with this.696 /* Also accept '.set stuff', but don't do anything with this.
695 It's used in GAS to set various features like '.set mips16'. */697 It's used in GAS to set various features like '.set mips16'. */
696 if (S->tccpp_tok == ',')698 if (tok == ',')
697 set_symbol(S, tok1);699 set_symbol(s1, tok1);
698 break;700 break;
699 case TOK_ASMDIR_globl:701 case TOK_ASMDIR_globl:
700 case TOK_ASMDIR_global:702 case TOK_ASMDIR_global:
701 case TOK_ASMDIR_weak:703 case TOK_ASMDIR_weak:
702 case TOK_ASMDIR_hidden:704 case TOK_ASMDIR_hidden:
703 tok1 = S->tccpp_tok;705 tok1 = tok;
704 do { 706 do {
705 Sym *sym;707 Sym *sym;
706 next(S);708 next();
707 sym = get_asm_sym(S, S->tccpp_tok, NULL);709 sym = get_asm_sym(tok, NULL);
708 if (tok1 != TOK_ASMDIR_hidden)710 if (tok1 != TOK_ASMDIR_hidden)
709 sym->type.t &= ~VT_STATIC;711 sym->type.t &= ~VT_STATIC;
710 if (tok1 == TOK_ASMDIR_weak)712 if (tok1 == TOK_ASMDIR_weak)
711 sym->a.weak = 1;713 sym->a.weak = 1;
712 else if (tok1 == TOK_ASMDIR_hidden)714 else if (tok1 == TOK_ASMDIR_hidden)
713 sym->a.visibility = STV_HIDDEN;715 sym->a.visibility = STV_HIDDEN;
714 update_storage(S, sym);716 update_storage(sym);
715 next(S);717 next();
716 } while (S->tccpp_tok == ',');718 } while (tok == ',');
717 break;719 break;
718 case TOK_ASMDIR_string:720 case TOK_ASMDIR_string:
719 case TOK_ASMDIR_ascii:721 case TOK_ASMDIR_ascii:
@@ -722,21 +724,21 @@ static void asm_parse_directive(TCCState *S, int global) · 2 unmodified lines
722 const uint8_t *p;724 const uint8_t *p;
723 int i, size, t;725 int i, size, t;
724 726
725 t = S->tccpp_tok;727 t = tok;
726 next(S);728 next();
727 for(;;) {729 for(;;) {
728 if (S->tccpp_tok != TOK_STR)730 if (tok != TOK_STR)
729 expect(S, "string constant");731 expect("string constant");
730 p = S->tccpp_tokc.str.data;732 p = tokc.str.data;
731 size = S->tccpp_tokc.str.size;733 size = tokc.str.size;
732 if (t == TOK_ASMDIR_ascii && size > 0)734 if (t == TOK_ASMDIR_ascii && size > 0)
733 size--;735 size--;
734 for(i = 0; i < size; i++)736 for(i = 0; i < size; i++)
735 g(S, p[i]);737 g(p[i]);
736 next(S);738 next();
737 if (S->tccpp_tok == ',') {739 if (tok == ',') {
738 next(S);740 next();
739 } else if (S->tccpp_tok != TOK_STR) {741 } else if (tok != TOK_STR) {
740 break;742 break;
741 }743 }
742 }744 }
@@ -747,18 +749,18 @@ static void asm_parse_directive(TCCState *S, int global) · 4 unmodified lines
747 case TOK_ASMDIR_bss:749 case TOK_ASMDIR_bss:
748 { 750 {
749 char sname[64];751 char sname[64];
750 tok1 = S->tccpp_tok;752 tok1 = tok;
751 n = 0;753 n = 0;
752 next(S);754 next();
753 if (S->tccpp_tok != ';' && S->tccpp_tok != TOK_LINEFEED) {755 if (tok != ';' && tok != TOK_LINEFEED) {
754 n = asm_int_expr(S);756 n = asm_int_expr(s1);
755 next(S);757 next();
756 }758 }
757 if (n)759 if (n)
758 sprintf(sname, "%s%d", get_tok_str(S, tok1, NULL), n);760 sprintf(sname, "%s%d", get_tok_str(tok1, NULL), n);
759 else761 else
760 sprintf(sname, "%s", get_tok_str(S, tok1, NULL));762 sprintf(sname, "%s", get_tok_str(tok1, NULL));
761 use_section(S, sname);763 use_section(s1, sname);
762 }764 }
763 break;765 break;
764 case TOK_ASMDIR_file:766 case TOK_ASMDIR_file:
@@ -766,13 +768,13 @@ static void asm_parse_directive(TCCState *S, int global) · 1 unmodified line
766 char filename[512];768 char filename[512];
767 769
768 filename[0] = '\0';770 filename[0] = '\0';
769 next(S);771 next();
770 if (S->tccpp_tok == TOK_STR)772 if (tok == TOK_STR)
771 pstrcat(filename, sizeof(filename), S->tccpp_tokc.str.data);773 pstrcat(filename, sizeof(filename), tokc.str.data);
772 else774 else
773 pstrcat(filename, sizeof(filename), get_tok_str(S, S->tccpp_tok, NULL));775 pstrcat(filename, sizeof(filename), get_tok_str(tok, NULL));
774 tcc_warning_c(warn_unsupported)(S, "ignoring .file %s", filename);776 tcc_warning_c(warn_unsupported)("ignoring .file %s", filename);
775 next(S);777 next();
776 }778 }
777 break;779 break;
778 case TOK_ASMDIR_ident:780 case TOK_ASMDIR_ident:
@@ -780,30 +782,30 @@ static void asm_parse_directive(TCCState *S, int global) · 1 unmodified line
780 char ident[256];782 char ident[256];
781 783
782 ident[0] = '\0';784 ident[0] = '\0';
783 next(S);785 next();
784 if (S->tccpp_tok == TOK_STR)786 if (tok == TOK_STR)
785 pstrcat(ident, sizeof(ident), S->tccpp_tokc.str.data);787 pstrcat(ident, sizeof(ident), tokc.str.data);
786 else788 else
787 pstrcat(ident, sizeof(ident), get_tok_str(S, S->tccpp_tok, NULL));789 pstrcat(ident, sizeof(ident), get_tok_str(tok, NULL));
788 tcc_warning_c(warn_unsupported)(S, "ignoring .ident %s", ident);790 tcc_warning_c(warn_unsupported)("ignoring .ident %s", ident);
789 next(S);791 next();
790 }792 }
791 break;793 break;
792 case TOK_ASMDIR_size:794 case TOK_ASMDIR_size:
793 { 795 {
794 Sym *sym;796 Sym *sym;
795 797
796 next(S);798 next();
797 sym = asm_label_find(S, S->tccpp_tok);799 sym = asm_label_find(tok);
798 if (!sym) {800 if (!sym) {
799 tcc_error(S, "label not found: %s", get_tok_str(S, S->tccpp_tok, NULL));801 tcc_error("label not found: %s", get_tok_str(tok, NULL));
800 }802 }
801 /* XXX .size name,label2-label1 */803 /* XXX .size name,label2-label1 */
802 tcc_warning_c(warn_unsupported)(S, "ignoring .size %s,*", get_tok_str(S, S->tccpp_tok, NULL));804 tcc_warning_c(warn_unsupported)("ignoring .size %s,*", get_tok_str(tok, NULL));
803 next(S);805 next();
804 skip(S, ',');806 skip(',');
805 while (S->tccpp_tok != TOK_LINEFEED && S->tccpp_tok != ';' && S->tccpp_tok != CH_EOF) {807 while (tok != TOK_LINEFEED && tok != ';' && tok != CH_EOF) {
806 next(S);808 next();
807 }809 }
808 }810 }
809 break;811 break;
@@ -812,182 +814,182 @@ static void asm_parse_directive(TCCState *S, int global) · 2 unmodified lines
812 Sym *sym;814 Sym *sym;
813 const char *newtype;815 const char *newtype;
814 816
815 next(S);817 next();
816 sym = get_asm_sym(S, S->tccpp_tok, NULL);818 sym = get_asm_sym(tok, NULL);
817 next(S);819 next();
818 skip(S, ',');820 skip(',');
819 if (S->tccpp_tok == TOK_STR) {821 if (tok == TOK_STR) {
820 newtype = S->tccpp_tokc.str.data;822 newtype = tokc.str.data;
821 } else {823 } else {
822 if (S->tccpp_tok == '@' || S->tccpp_tok == '%')824 if (tok == '@' || tok == '%')
823 next(S);825 next();
824 newtype = get_tok_str(S, S->tccpp_tok, NULL);826 newtype = get_tok_str(tok, NULL);
825 }827 }
826 828
827 if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) {829 if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) {
828 sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC;830 sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC;
829 } else831 } else
830 tcc_warning_c(warn_unsupported)(S, "change type of '%s' from 0x%x to '%s' ignored",832 tcc_warning_c(warn_unsupported)("change type of '%s' from 0x%x to '%s' ignored",
831 get_tok_str(S, sym->v, NULL), sym->type.t, newtype);833 get_tok_str(sym->v, NULL), sym->type.t, newtype);
832 834
833 next(S);835 next();
834 }836 }
835 break;837 break;
836 case TOK_ASMDIR_pushsection:838 case TOK_ASMDIR_pushsection:
837 case TOK_ASMDIR_section:839 case TOK_ASMDIR_section:
838 {840 {
839 char sname[256];841 char sname[256];
840 int old_nb_section = S->nb_sections;842 int old_nb_section = s1->nb_sections;
841 843
842 tok1 = S->tccpp_tok;844 tok1 = tok;
843 /* XXX: support more options */845 /* XXX: support more options */
844 next(S);846 next();
845 sname[0] = '\0';847 sname[0] = '\0';
846 while (S->tccpp_tok != ';' && S->tccpp_tok != TOK_LINEFEED && S->tccpp_tok != ',') {848 while (tok != ';' && tok != TOK_LINEFEED && tok != ',') {
847 if (S->tccpp_tok == TOK_STR)849 if (tok == TOK_STR)
848 pstrcat(sname, sizeof(sname), S->tccpp_tokc.str.data);850 pstrcat(sname, sizeof(sname), tokc.str.data);
849 else851 else
850 pstrcat(sname, sizeof(sname), get_tok_str(S, S->tccpp_tok, NULL));852 pstrcat(sname, sizeof(sname), get_tok_str(tok, NULL));
851 next(S);853 next();
852 }854 }
853 if (S->tccpp_tok == ',') {855 if (tok == ',') {
854 /* skip section options */856 /* skip section options */
855 next(S);857 next();
856 if (S->tccpp_tok != TOK_STR)858 if (tok != TOK_STR)
857 expect(S, "string constant");859 expect("string constant");
858 next(S);860 next();
859 if (S->tccpp_tok == ',') {861 if (tok == ',') {
860 next(S);862 next();
861 if (S->tccpp_tok == '@' || S->tccpp_tok == '%')863 if (tok == '@' || tok == '%')
862 next(S);864 next();
863 next(S);865 next();
864 }866 }
865 }867 }
866 S->tccasm_last_text_section = cur_text_section;868 last_text_section = cur_text_section;
867 if (tok1 == TOK_ASMDIR_section)869 if (tok1 == TOK_ASMDIR_section)
868 use_section(S, sname);870 use_section(s1, sname);
869 else871 else
870 push_section(S, sname);872 push_section(s1, sname);
871 /* If we just allocated a new section reset its alignment to873 /* If we just allocated a new section reset its alignment to
872 1. new_section normally acts for GCC compatibility and874 1. new_section normally acts for GCC compatibility and
873 sets alignment to PTR_SIZE. The assembler behaves different. */875 sets alignment to PTR_SIZE. The assembler behaves different. */
874 if (old_nb_section != S->nb_sections)876 if (old_nb_section != s1->nb_sections)
875 cur_text_section->sh_addralign = 1;877 cur_text_section->sh_addralign = 1;
876 }878 }
877 break;879 break;
878 case TOK_ASMDIR_previous:880 case TOK_ASMDIR_previous:
879 { 881 {
880 Section *sec;882 Section *sec;
881 next(S);883 next();
882 if (!S->tccasm_last_text_section)884 if (!last_text_section)
883 tcc_error(S, "no previous section referenced");885 tcc_error("no previous section referenced");
884 sec = cur_text_section;886 sec = cur_text_section;
885 use_section1(S, S->tccasm_last_text_section);887 use_section1(s1, last_text_section);
886 S->tccasm_last_text_section = sec;888 last_text_section = sec;
887 }889 }
888 break;890 break;
889 case TOK_ASMDIR_popsection:891 case TOK_ASMDIR_popsection:
890 next(S);892 next();
891 pop_section(S);893 pop_section(s1);
892 break;894 break;
893#ifdef TCC_TARGET_I386895#ifdef TCC_TARGET_I386
894 case TOK_ASMDIR_code16:896 case TOK_ASMDIR_code16:
895 {897 {
896 next(S);898 next();
897 S->seg_size = 16;899 s1->seg_size = 16;
898 }900 }
899 break;901 break;
900 case TOK_ASMDIR_code32:902 case TOK_ASMDIR_code32:
901 {903 {
902 next(S);904 next();
903 S->seg_size = 32;905 s1->seg_size = 32;
904 }906 }
905 break;907 break;
906#endif908#endif
907#ifdef TCC_TARGET_X86_64909#ifdef TCC_TARGET_X86_64
908 /* added for compatibility with GAS */910 /* added for compatibility with GAS */
909 case TOK_ASMDIR_code64:911 case TOK_ASMDIR_code64:
910 next(S);912 next();
911 break;913 break;
912#endif914#endif
913 default:915 default:
914 tcc_error(S, "unknown assembler directive '.%s'", get_tok_str(S, S->tccpp_tok, NULL));916 tcc_error("unknown assembler directive '.%s'", get_tok_str(tok, NULL));
915 break;917 break;
916 }918 }
917}919}
918 920
919 921
920/* assemble a file */922/* assemble a file */
921static int tcc_assemble_internal(TCCState *S, int do_preprocess, int global)923static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global)
922{924{
923 int opcode;925 int opcode;
924 int saved_parse_flags = S->tccpp_parse_flags;926 int saved_parse_flags = parse_flags;
925 927
926 S->tccpp_parse_flags = PARSE_FLAG_ASM_FILE | PARSE_FLAG_TOK_STR;928 parse_flags = PARSE_FLAG_ASM_FILE | PARSE_FLAG_TOK_STR;
927 if (do_preprocess)929 if (do_preprocess)
928 S->tccpp_parse_flags |= PARSE_FLAG_PREPROCESS;930 parse_flags |= PARSE_FLAG_PREPROCESS;
929 for(;;) {931 for(;;) {
930 next(S);932 next();
931 if (S->tccpp_tok == TOK_EOF)933 if (tok == TOK_EOF)
932 break;934 break;
933 S->tccpp_parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */935 parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
934 redo:936 redo:
935 if (S->tccpp_tok == '#') {937 if (tok == '#') {
936 /* horrible gas comment */938 /* horrible gas comment */
937 while (S->tccpp_tok != TOK_LINEFEED)939 while (tok != TOK_LINEFEED)
938 next(S);940 next();
939 } else if (S->tccpp_tok >= TOK_ASMDIR_FIRST && S->tccpp_tok <= TOK_ASMDIR_LAST) {941 } else if (tok >= TOK_ASMDIR_FIRST && tok <= TOK_ASMDIR_LAST) {
940 asm_parse_directive(S, global);942 asm_parse_directive(s1, global);
941 } else if (S->tccpp_tok == TOK_PPNUM) {943 } else if (tok == TOK_PPNUM) {
942 const char *p;944 const char *p;
943 int n;945 int n;
944 p = S->tccpp_tokc.str.data;946 p = tokc.str.data;
945 n = strtoul(p, (char **)&p, 10);947 n = strtoul(p, (char **)&p, 10);
946 if (*p != '\0')948 if (*p != '\0')
947 expect(S, "':'");949 expect("':'");
948 /* new local label */950 /* new local label */
949 asm_new_label(S, asm_get_local_label_name(S, n), 1);951 asm_new_label(s1, asm_get_local_label_name(s1, n), 1);
950 next(S);952 next();
951 skip(S, ':');953 skip(':');
952 goto redo;954 goto redo;
953 } else if (S->tccpp_tok >= TOK_IDENT) {955 } else if (tok >= TOK_IDENT) {
954 /* instruction or label */956 /* instruction or label */
955 opcode = S->tccpp_tok;957 opcode = tok;
956 next(S);958 next();
957 if (S->tccpp_tok == ':') {959 if (tok == ':') {
958 /* new label */960 /* new label */
959 asm_new_label(S, opcode, 0);961 asm_new_label(s1, opcode, 0);
960 next(S);962 next();
961 goto redo;963 goto redo;
962 } else if (S->tccpp_tok == '=') {964 } else if (tok == '=') {
963 set_symbol(S, opcode);965 set_symbol(s1, opcode);
964 goto redo;966 goto redo;
965 } else {967 } else {
966 asm_opcode(S, opcode);968 asm_opcode(s1, opcode);
967 }969 }
968 }970 }
969 /* end of line */971 /* end of line */
970 if (S->tccpp_tok != ';' && S->tccpp_tok != TOK_LINEFEED)972 if (tok != ';' && tok != TOK_LINEFEED)
971 expect(S, "end of line");973 expect("end of line");
972 S->tccpp_parse_flags &= ~PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */974 parse_flags &= ~PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
973 }975 }
974 976
975 S->tccpp_parse_flags = saved_parse_flags;977 parse_flags = saved_parse_flags;
976 return 0;978 return 0;
977}979}
978 980
979/* Assemble the current file */981/* Assemble the current file */
980ST_FUNC int tcc_assemble(TCCState *S, int do_preprocess)982ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess)
981{983{
982 int ret;984 int ret;
983 tcc_debug_start(S);985 tcc_debug_start(s1);
984 /* default section is text */986 /* default section is text */
985 cur_text_section = text_section;987 cur_text_section = text_section;
986 S->tccgen_ind = cur_text_section->data_offset;988 ind = cur_text_section->data_offset;
987 S->tccgen_nocode_wanted = 0;989 nocode_wanted = 0;
988 ret = tcc_assemble_internal(S, do_preprocess, 1);990 ret = tcc_assemble_internal(s1, do_preprocess, 1);
989 cur_text_section->data_offset = S->tccgen_ind;991 cur_text_section->data_offset = ind;
990 tcc_debug_end(S);992 tcc_debug_end(s1);
991 return ret;993 return ret;
992}994}
993 995
@@ -997,27 +999,27 @@ ST_FUNC int tcc_assemble(TCCState *S, int do_preprocess) · 3 unmodified lines
997/* assemble the string 'str' in the current C compilation unit without999/* assemble the string 'str' in the current C compilation unit without
998 C preprocessing. NOTE: str is modified by modifying the '\0' at the1000 C preprocessing. NOTE: str is modified by modifying the '\0' at the
999 end */1001 end */
1000static void tcc_assemble_inline(TCCState *S, char *str, int len, int global)1002static void tcc_assemble_inline(TCCState *s1, char *str, int len, int global)
1001{1003{
1002 const int *saved_macro_ptr = S->tccpp_macro_ptr;1004 const int *saved_macro_ptr = macro_ptr;
1003 int dotid = set_idnum(S, '.', IS_ID);1005 int dotid = set_idnum('.', IS_ID);
1004 int dolid = set_idnum(S, '$', 0);1006 int dolid = set_idnum('$', 0);
1005 1007
1006 tcc_open_bf(S, ":asm:", len);1008 tcc_open_bf(s1, ":asm:", len);
1007 memcpy(S->tccpp_file->buffer, str, len);1009 memcpy(file->buffer, str, len);
1008 S->tccpp_macro_ptr = NULL;1010 macro_ptr = NULL;
1009 tcc_assemble_internal(S, 0, global);1011 tcc_assemble_internal(s1, 0, global);
1010 tcc_close(S);1012 tcc_close();
1011 1013
1012 set_idnum(S, '$', dolid);1014 set_idnum('$', dolid);
1013 set_idnum(S, '.', dotid);1015 set_idnum('.', dotid);
1014 S->tccpp_macro_ptr = saved_macro_ptr;1016 macro_ptr = saved_macro_ptr;
1015}1017}
1016 1018
1017/* find a constraint by its number or id (gcc 3 extended1019/* find a constraint by its number or id (gcc 3 extended
1018 syntax). return -1 if not found. Return in *pp in char after the1020 syntax). return -1 if not found. Return in *pp in char after the
1019 constraint */1021 constraint */
1020ST_FUNC int find_constraint(TCCState* S, ASMOperand *operands, int nb_operands, 1022ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands,
1021 const char *name, const char **pp)1023 const char *name, const char **pp)
1022{1024{
1023 int index;1025 int index;
@@ -1036,7 +1038,7 @@ ST_FUNC int find_constraint(TCCState* S, ASMOperand *operands, int nb_operands, · 12 unmodified lines
1036 name++;1038 name++;
1037 p = strchr(name, ']');1039 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+675−672

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

tccgen.c+2728−2636

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

tccmacho.c+113−112

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

tccpe.c+178−177

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

tccpp.c+1108−1063

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

tccqsort.c+0−261

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+680−667

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