History

div fixes

- Makefile: don't produce unknown targets - libtcc.c: tcc_set_linker(): improve parser - tcc.h: tcc_internal_error(): don't record __FILE__ (for privacy reasons) - tccgen.c: - reject pointer + float operation - use 'int level' for builtin_frame/return_address - save_regs(): remove VT_ARRAY (confuses riscv64-gen) - tccpe.c: store just basename of loaded dlls (rather than full path) - tccpp.c: remove unused TAL defines - *-link.c: add missing ST_FUNC - i386-gen.c: fix thiscall - riscv64-asm.c/arm-asm.c: stay simple C89 - avoid .designators, decl after statement - avoid multiple instances of same static const objects - use skip() instead of next() & expect() - use cstr_printf() instead of snprintf() & cstr_cat() - tcc_error(), expect(): never return

grischka committed 2 years ago

Commit 6b78e561 parent 3b943be20 files · +227 −508Browse files

Unified · Split

20 files
  1. Makefile +1 −0
  2. arm-asm.c +28 −193
  3. arm-link.c +3 −3
  4. arm64-link.c +3 −3
  5. c67-link.c +3 −3
  6. i386-asm.c +6 −19
  7. i386-gen.c +8 −24
  8. i386-link.c +3 −3
  9. libtcc.c +27 −17
  10. riscv64-asm.c +28 −108
  11. riscv64-link.c +3 −3
  12. tcc.h +4 −5
  13. tccelf.c +9 −20
  14. tccgen.c +51 −54
  15. tccpe.c +5 −2
  16. tccpp.c +32 −31
  17. tests/tests2/60_errors_and_warnings.c +7 −0
  18. tests/tests2/60_errors_and_warnings.expect +3 −0
  19. tests/thiscall/thiscall-test.c +0 −17
  20. x86_64-link.c +3 −3
Makefile+1−0
@@ -198,6 +198,7 @@ DEFINES += $(if $(ELF-$T),-DCONFIG_TCC_ELFINTERP="\"$(ELF-$T)\"") · 197 unmodified lines
198DEFINES += $(DEF-$(or $(findstring win,$T),unx))198DEFINES += $(DEF-$(or $(findstring win,$T),unx))
199 199
200ifneq ($(X),)200ifneq ($(X),)
201$(if $(DEF-$T),,$(error error: unknown target: '$T'))
201DEF-all += -DCONFIG_TCC_CROSSPREFIX="\"$X\""202DEF-all += -DCONFIG_TCC_CROSSPREFIX="\"$X\""
202ifneq ($(CONFIG_WIN32),yes)203ifneq ($(CONFIG_WIN32),yes)
203DEF-win += -DCONFIG_TCCDIR="\"$(tccdir)/win32\""204DEF-win += -DCONFIG_TCCDIR="\"$(tccdir)/win32\""
arm-asm.c+28−193
@@ -92,7 +92,6 @@ static void parse_operand(TCCState *s1, Operand *op) · 91 unmodified lines
92 reg = asm_parse_regvar(tok);92 reg = asm_parse_regvar(tok);
93 if (reg == -1) {93 if (reg == -1) {
94 expect("register");94 expect("register");
95 return;
96 } else95 } else
97 next(); // skip register name96 next(); // skip register name
98 97
@@ -103,9 +102,7 @@ static void parse_operand(TCCState *s1, Operand *op) · 4 unmodified lines
103 break;102 break;
104 next(); // skip ','103 next(); // skip ','
105 }104 }
106 if (tok != '}')105 skip('}');
107 expect("'}'");
108 next(); // skip '}'
109 if (regset == 0) {106 if (regset == 0) {
110 // ARM instructions don't support empty regset.107 // ARM instructions don't support empty regset.
111 tcc_error("empty register list is not supported");108 tcc_error("empty register list is not supported");
@@ -186,7 +183,6 @@ ST_FUNC void gen_expr32(ExprValue *pe) · 74 unmodified lines
186static uint32_t condition_code_of_token(int token) {183static uint32_t condition_code_of_token(int token) {
187 if (token < TOK_ASM_nopeq) {184 if (token < TOK_ASM_nopeq) {
188 expect("condition-enabled instruction");185 expect("condition-enabled instruction");
189 return 0;
190 } else186 } else
191 return (token - TOK_ASM_nopeq) & 15;187 return (token - TOK_ASM_nopeq) & 15;
192}188}
@@ -262,19 +258,14 @@ static void asm_binary_opcode(TCCState *s1, int token) · 69 unmodified lines
262 uint32_t encoded_rotation = 0;258 uint32_t encoded_rotation = 0;
263 uint64_t amount;259 uint64_t amount;
264 parse_operand(s1, &ops[0]);260 parse_operand(s1, &ops[0]);
265 if (tok == ',')261 skip(',');
266 next();
267 else
268 expect("','");
269 parse_operand(s1, &ops[1]);262 parse_operand(s1, &ops[1]);
270 if (ops[0].type != OP_REG32) {263 if (ops[0].type != OP_REG32) {
271 expect("(destination operand) register");264 expect("(destination operand) register");
272 return;
273 }265 }
274 266
275 if (ops[0].reg == 15) {267 if (ops[0].reg == 15) {
276 tcc_error("'%s' does not support 'pc' as operand", get_tok_str(token, NULL));268 tcc_error("'%s' does not support 'pc' as operand", get_tok_str(token, NULL));
277 return;
278 }269 }
279 270
280 if (ops[0].reg == 13)271 if (ops[0].reg == 13)
@@ -308,7 +299,6 @@ static void asm_binary_opcode(TCCState *s1, int token) · 27 unmodified lines
308 299
309 if (ops[1].reg == 15) {300 if (ops[1].reg == 15) {
310 tcc_error("'%s' does not support 'pc' as operand", get_tok_str(token, NULL));301 tcc_error("'%s' does not support 'pc' as operand", get_tok_str(token, NULL));
311 return;
312 }302 }
313 303
314 if (ops[1].reg == 13)304 if (ops[1].reg == 13)
@@ -321,7 +311,6 @@ static void asm_binary_opcode(TCCState *s1, int token) · 6 unmodified lines
321 parse_operand(s1, &rotation);311 parse_operand(s1, &rotation);
322 if (rotation.type != OP_IM8) {312 if (rotation.type != OP_IM8) {
323 expect("immediate value for rotation");313 expect("immediate value for rotation");
324 return;
325 } else {314 } else {
326 amount = rotation.e.v;315 amount = rotation.e.v;
327 switch (amount) {316 switch (amount) {
@@ -336,7 +325,6 @@ static void asm_binary_opcode(TCCState *s1, int token) · 8 unmodified lines
336 break;325 break;
337 default:326 default:
338 expect("'8' or '16' or '24'");327 expect("'8' or '16' or '24'");
339 return;
340 }328 }
341 }329 }
342 }330 }
@@ -378,32 +366,21 @@ static void asm_coprocessor_opcode(TCCState *s1, int token) { · 35 unmodified lines
378 next();366 next();
379 } else {367 } else {
380 expect("'p<number>'");368 expect("'p<number>'");
381 return;
382 }369 }
383 370 skip(',');
384 if (tok == ',')
385 next();
386 else
387 expect("','");
388
389 parse_operand(s1, &opcode1);371 parse_operand(s1, &opcode1);
390 if (opcode1.type != OP_IM8 || opcode1.e.v > 15) {372 if (opcode1.type != OP_IM8 || opcode1.e.v > 15) {
391 tcc_error("opcode1 of instruction '%s' must be an immediate value between 0 and 15", get_tok_str(token, NULL));373 tcc_error("opcode1 of instruction '%s' must be an immediate value between 0 and 15", get_tok_str(token, NULL));
392 return;
393 }374 }
394 375
395 for (i = 0; i < 3; ++i) {376 for (i = 0; i < 3; ++i) {
396 if (tok == ',')377 skip(',');
397 next();
398 else
399 expect("','");
400 if (i == 0 && token != TOK_ASM_cdp2 && (ARM_INSTRUCTION_GROUP(token) == TOK_ASM_mrceq || ARM_INSTRUCTION_GROUP(token) == TOK_ASM_mcreq)) {378 if (i == 0 && token != TOK_ASM_cdp2 && (ARM_INSTRUCTION_GROUP(token) == TOK_ASM_mrceq || ARM_INSTRUCTION_GROUP(token) == TOK_ASM_mcreq)) {
401 if (tok >= TOK_ASM_r0 && tok <= TOK_ASM_r15) {379 if (tok >= TOK_ASM_r0 && tok <= TOK_ASM_r15) {
402 registers[i] = tok - TOK_ASM_r0;380 registers[i] = tok - TOK_ASM_r0;
403 next();381 next();
404 } else {382 } else {
405 expect("'r<number>'");383 expect("'r<number>'");
406 return;
407 }384 }
408 } else {385 } else {
409 if (tok >= TOK_ASM_c0 && tok <= TOK_ASM_c15) {386 if (tok >= TOK_ASM_c0 && tok <= TOK_ASM_c15) {
@@ -411,7 +388,6 @@ static void asm_coprocessor_opcode(TCCState *s1, int token) { · 1 unmodified line
411 next();388 next();
412 } else {389 } else {
413 expect("'c<number>'");390 expect("'c<number>'");
414 return;
415 }391 }
416 }392 }
417 }393 }
@@ -424,7 +400,6 @@ static void asm_coprocessor_opcode(TCCState *s1, int token) { · 6 unmodified lines
424 }400 }
425 if (opcode2.type != OP_IM8 || opcode2.e.v > 15) {401 if (opcode2.type != OP_IM8 || opcode2.e.v > 15) {
426 tcc_error("opcode2 of instruction '%s' must be an immediate value between 0 and 15", get_tok_str(token, NULL));402 tcc_error("opcode2 of instruction '%s' must be an immediate value between 0 and 15", get_tok_str(token, NULL));
427 return;
428 }403 }
429 404
430 if (token == TOK_ASM_cdp2) {405 if (token == TOK_ASM_cdp2) {
@@ -446,7 +421,6 @@ static void asm_coprocessor_opcode(TCCState *s1, int token) { · 15 unmodified lines
446 // opcode1 encoding changes! highest and lowest bit gone.421 // opcode1 encoding changes! highest and lowest bit gone.
447 if (opcode1.e.v > 7) {422 if (opcode1.e.v > 7) {
448 tcc_error("opcode1 of instruction '%s' must be an immediate value between 0 and 7", get_tok_str(token, NULL));423 tcc_error("opcode1 of instruction '%s' must be an immediate value between 0 and 7", get_tok_str(token, NULL));
449 return;
450 }424 }
451 asm_emit_coprocessor_opcode(high_nibble, coprocessor, (opcode1.e.v << 1) | mrc, registers[0], registers[1], registers[2], opcode2.e.v, 1);425 asm_emit_coprocessor_opcode(high_nibble, coprocessor, (opcode1.e.v << 1) | mrc, registers[0], registers[1], registers[2], opcode2.e.v, 1);
452 break;426 break;
@@ -490,10 +464,8 @@ static void asm_block_data_transfer_opcode(TCCState *s1, int token) · 37 unmodified lines
490 }464 }
491 if (nb_ops < 1) {465 if (nb_ops < 1) {
492 expect("at least one operand");466 expect("at least one operand");
493 return;
494 } else if (ops[nb_ops - 1].type != OP_REGSET32) {467 } else if (ops[nb_ops - 1].type != OP_REGSET32) {
495 expect("(last operand) register list");468 expect("(last operand) register list");
496 return;
497 }469 }
498 470
499 // block data transfer: 1 0 0 P U S W L << 20 (general case):471 // block data transfer: 1 0 0 P U S W L << 20 (general case):
@@ -683,12 +655,10 @@ static void asm_data_processing_opcode(TCCState *s1, int token) · 183 unmodified lines
683 } else if (nb_ops == 3) {655 } else if (nb_ops == 3) {
684 if (opcode_nos == 0xd || opcode_nos == 0xf || opcode_nos == 0xa || opcode_nos == 0xb || opcode_nos == 0x8 || opcode_nos == 0x9) { // mov, mvn, cmp, cmn, tst, teq656 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
685 tcc_error("'%s' cannot be used with three operands", get_tok_str(token, NULL));657 tcc_error("'%s' cannot be used with three operands", get_tok_str(token, NULL));
686 return;
687 }658 }
688 }659 }
689 if (nb_ops != 3) {660 if (nb_ops != 3) {
690 expect("two or three operands");661 expect("two or three operands");
691 return;
692 } else {662 } else {
693 uint32_t opcode = 0;663 uint32_t opcode = 0;
694 uint32_t immediate_value;664 uint32_t immediate_value;
@@ -697,7 +667,6 @@ static void asm_data_processing_opcode(TCCState *s1, int token) · 2 unmodified lines
697 if ((ops[0].type == OP_REG32 && ops[0].reg == 15) ||667 if ((ops[0].type == OP_REG32 && ops[0].reg == 15) ||
698 (ops[1].type == OP_REG32 && ops[1].reg == 15)) {668 (ops[1].type == OP_REG32 && ops[1].reg == 15)) {
699 tcc_error("Using the 'pc' register in data processing instructions that have a register-controlled shift is not implemented by ARM");669 tcc_error("Using the 'pc' register in data processing instructions that have a register-controlled shift is not implemented by ARM");
700 return;
701 }670 }
702 }671 }
703 672
@@ -806,7 +775,6 @@ static void asm_data_processing_opcode(TCCState *s1, int token) · 102 unmodified lines
806 if (half_immediate_rotation >= 16) {775 if (half_immediate_rotation >= 16) {
807 immediate_value = ops[2].e.v;776 immediate_value = ops[2].e.v;
808 tcc_error("immediate value 0x%X cannot be encoded into ARM immediate", (unsigned) immediate_value);777 tcc_error("immediate value 0x%X cannot be encoded into ARM immediate", (unsigned) immediate_value);
809 return;
810 }778 }
811 operands |= immediate_value;779 operands |= immediate_value;
812 operands |= half_immediate_rotation << 8;780 operands |= half_immediate_rotation << 8;
@@ -846,12 +814,10 @@ static void asm_shift_opcode(TCCState *s1, int token) · 33 unmodified lines
846 }814 }
847 if (nb_ops < 2) {815 if (nb_ops < 2) {
848 expect("at least two operands");816 expect("at least two operands");
849 return;
850 }817 }
851 818
852 if (ops[0].type != OP_REG32) {819 if (ops[0].type != OP_REG32) {
853 expect("(destination operand) register");820 expect("(destination operand) register");
854 return;
855 } else821 } else
856 operands |= ENCODE_RD(ops[0].reg);822 operands |= ENCODE_RD(ops[0].reg);
857 823
@@ -876,7 +842,6 @@ static void asm_shift_opcode(TCCState *s1, int token) · 18 unmodified lines
876 }842 }
877 if (nb_ops != 3) {843 if (nb_ops != 3) {
878 expect("two or three operands");844 expect("two or three operands");
879 return;
880 }845 }
881 846
882 switch (ARM_INSTRUCTION_GROUP(token)) {847 switch (ARM_INSTRUCTION_GROUP(token)) {
@@ -896,7 +861,6 @@ static void asm_shift_opcode(TCCState *s1, int token) · 13 unmodified lines
896 operands |= ENCODE_IMMEDIATE_FLAG;861 operands |= ENCODE_IMMEDIATE_FLAG;
897 operands |= ops[1].e.v;862 operands |= ops[1].e.v;
898 tcc_error("Using an immediate value as the source operand is not possible with '%s' instruction on ARM", get_tok_str(token, NULL));863 tcc_error("Using an immediate value as the source operand is not possible with '%s' instruction on ARM", get_tok_str(token, NULL));
899 return;
900 }864 }
901 865
902 switch (ops[2].type) {866 switch (ops[2].type) {
@@ -934,7 +898,6 @@ static void asm_shift_opcode(TCCState *s1, int token) · 31 unmodified lines
934 break;898 break;
935 default:899 default:
936 expect("shift instruction");900 expect("shift instruction");
937 return;
938 }901 }
939 asm_emit_opcode(token, opcode | operands);902 asm_emit_opcode(token, opcode | operands);
940}903}
@@ -963,7 +926,6 @@ static void asm_multiplication_opcode(TCCState *s1, int token) · 22 unmodified lines
963 break;926 break;
964 default:927 default:
965 expect("at least three operands");928 expect("at least three operands");
966 return;
967 }929 }
968 nb_ops = 3;930 nb_ops = 3;
969 }931 }
@@ -1037,7 +999,6 @@ static void asm_long_multiplication_opcode(TCCState *s1, int token) · 67 unmodified lines
1037 }999 }
1038 if (nb_ops != 4) {1000 if (nb_ops != 4) {
1039 expect("four operands");1001 expect("four operands");
1040 return;
1041 }1002 }
1042 1003
1043 // long multiply (special case):1004 // long multiply (special case):
@@ -1117,12 +1078,10 @@ static void asm_single_data_transfer_opcode(TCCState *s1, int token) · 73 unmodified lines
1117 opcode |= ENCODE_RD(ops[0].reg);1078 opcode |= ENCODE_RD(ops[0].reg);
1118 else {1079 else {
1119 expect("(destination operand) register");1080 expect("(destination operand) register");
1120 return;
1121 }1081 }
1122 if (tok != ',')1082 if (tok != ',')
1123 expect("at least two arguments");1083 expect("at least two arguments");
1124 else1084 next(); // skip ','
1125 next(); // skip ','
1126 1085
1127 switch (ARM_INSTRUCTION_GROUP(token)) {1086 switch (ARM_INSTRUCTION_GROUP(token)) {
1128 case TOK_ASM_strexbeq:1087 case TOK_ASM_strexbeq:
@@ -1130,7 +1089,6 @@ static void asm_single_data_transfer_opcode(TCCState *s1, int token) · 1 unmodified line
1130 parse_operand(s1, &strex_operand);1089 parse_operand(s1, &strex_operand);
1131 if (strex_operand.type != OP_REG32) {1090 if (strex_operand.type != OP_REG32) {
1132 expect("register");1091 expect("register");
1133 return;
1134 }1092 }
1135 if (tok != ',')1093 if (tok != ',')
1136 expect("at least three arguments");1094 expect("at least three arguments");
@@ -1139,17 +1097,12 @@ static void asm_single_data_transfer_opcode(TCCState *s1, int token) · 2 unmodified lines
1139 break;1097 break;
1140 }1098 }
1141 1099
1142 if (tok != '[')1100 skip('[');
1143 expect("'['");
1144 else
1145 next(); // skip '['
1146
1147 parse_operand(s1, &ops[1]);1101 parse_operand(s1, &ops[1]);
1148 if (ops[1].type == OP_REG32)1102 if (ops[1].type == OP_REG32)
1149 opcode |= ENCODE_RN(ops[1].reg);1103 opcode |= ENCODE_RN(ops[1].reg);
1150 else {1104 else {
1151 expect("(first source operand) register");1105 expect("(first source operand) register");
1152 return;
1153 }1106 }
1154 if (tok == ']') {1107 if (tok == ']') {
1155 next();1108 next();
@@ -1166,7 +1119,6 @@ static void asm_single_data_transfer_opcode(TCCState *s1, int token) · 10 unmodified lines
1166 if (ops[2].type == OP_REG32) {1119 if (ops[2].type == OP_REG32) {
1167 if (ops[2].reg == 15) {1120 if (ops[2].reg == 15) {
1168 tcc_error("Using 'pc' for register offset in '%s' is not implemented by ARM", get_tok_str(token, NULL));1121 tcc_error("Using 'pc' for register offset in '%s' is not implemented by ARM", get_tok_str(token, NULL));
1169 return;
1170 }1122 }
1171 if (tok == ',') {1123 if (tok == ',') {
1172 next();1124 next();
@@ -1182,10 +1134,7 @@ static void asm_single_data_transfer_opcode(TCCState *s1, int token) · 9 unmodified lines
1182 opcode |= 1 << 24; // add offset before transfer1134 opcode |= 1 << 24; // add offset before transfer
1183 }1135 }
1184 if (!closed_bracket) {1136 if (!closed_bracket) {
1185 if (tok != ']')1137 skip(']');
1186 expect("']'");
1187 else
1188 next(); // skip ']'
1189 opcode |= 1 << 24; // add offset before transfer1138 opcode |= 1 << 24; // add offset before transfer
1190 if (tok == '!') {1139 if (tok == '!') {
1191 exclam = 1;1140 exclam = 1;
@@ -1257,14 +1206,11 @@ static void asm_single_data_transfer_opcode(TCCState *s1, int token) · 65 unmodified lines
1257 case TOK_ASM_strexeq:1206 case TOK_ASM_strexeq:
1258 if ((opcode & 0xFFF) || nb_shift) {1207 if ((opcode & 0xFFF) || nb_shift) {
1259 tcc_error("neither offset nor shift allowed with 'strex'");1208 tcc_error("neither offset nor shift allowed with 'strex'");
1260 return;
1261 } else if (opcode & ENCODE_IMMEDIATE_FLAG) { // if set, it means it's NOT immediate1209 } else if (opcode & ENCODE_IMMEDIATE_FLAG) { // if set, it means it's NOT immediate
1262 tcc_error("offset not allowed with 'strex'");1210 tcc_error("offset not allowed with 'strex'");
1263 return;
1264 }1211 }
1265 if ((opcode & (1 << 24)) == 0) { // add offset after transfer1212 if ((opcode & (1 << 24)) == 0) { // add offset after transfer
1266 tcc_error("adding offset after transfer not allowed with 'strex'");1213 tcc_error("adding offset after transfer not allowed with 'strex'");
1267 return;
1268 }1214 }
1269 1215
1270 opcode |= 0xf90; // Used to mean: barrel shifter is enabled, barrel shift register is r15, mode is LSL1216 opcode |= 0xf90; // Used to mean: barrel shifter is enabled, barrel shift register is r15, mode is LSL
@@ -1277,14 +1223,11 @@ static void asm_single_data_transfer_opcode(TCCState *s1, int token) · 6 unmodified lines
1277 case TOK_ASM_ldrexeq:1223 case TOK_ASM_ldrexeq:
1278 if ((opcode & 0xFFF) || nb_shift) {1224 if ((opcode & 0xFFF) || nb_shift) {
1279 tcc_error("neither offset nor shift allowed with 'ldrex'");1225 tcc_error("neither offset nor shift allowed with 'ldrex'");
1280 return;
1281 } else if (opcode & ENCODE_IMMEDIATE_FLAG) { // if set, it means it's NOT immediate1226 } else if (opcode & ENCODE_IMMEDIATE_FLAG) { // if set, it means it's NOT immediate
1282 tcc_error("offset not allowed with 'ldrex'");1227 tcc_error("offset not allowed with 'ldrex'");
1283 return;
1284 }1228 }
1285 if ((opcode & (1 << 24)) == 0) { // add offset after transfer1229 if ((opcode & (1 << 24)) == 0) { // add offset after transfer
1286 tcc_error("adding offset after transfer not allowed with 'ldrex'");1230 tcc_error("adding offset after transfer not allowed with 'ldrex'");
1287 return;
1288 }1231 }
1289 opcode |= 1 << 20; // L1232 opcode |= 1 << 20; // L
1290 opcode |= 0x00f;1233 opcode |= 0x00f;
@@ -1313,10 +1256,9 @@ static void asm_emit_coprocessor_data_transfer(uint32_t high_nibble, uint8_t cp_ · 22 unmodified lines
1313 //assert(CRd < 16);1256 //assert(CRd < 16);
1314 opcode |= ENCODE_RD(CRd);1257 opcode |= ENCODE_RD(CRd);
1315 1258
1316 if (Rn->type != OP_REG32) {1259 if (Rn->type != OP_REG32)
1317 expect("register");1260 expect("register");
1318 return;1261
1319 }
1320 //assert(Rn->reg < 16);1262 //assert(Rn->reg < 16);
1321 opcode |= ENCODE_RN(Rn->reg);1263 opcode |= ENCODE_RN(Rn->reg);
1322 if (preincrement)1264 if (preincrement)
@@ -1335,12 +1277,10 @@ static void asm_emit_coprocessor_data_transfer(uint32_t high_nibble, uint8_t cp_ · 12 unmodified lines
1335 opcode |= 1 << 23; // up1277 opcode |= 1 << 23; // up
1336 if (v & 3) {1278 if (v & 3) {
1337 tcc_error("immediate offset must be a multiple of 4");1279 tcc_error("immediate offset must be a multiple of 4");
1338 return;
1339 }1280 }
1340 v >>= 2;1281 v >>= 2;
1341 if (v > 255) {1282 if (v > 255) {
1342 tcc_error("immediate offset must be between -1020 and 1020");1283 tcc_error("immediate offset must be between -1020 and 1020");
1343 return;
1344 }1284 }
1345 opcode |= v;1285 opcode |= v;
1346 } else if (offset->type == OP_REG32) {1286 } else if (offset->type == OP_REG32) {
@@ -1349,7 +1289,6 @@ static void asm_emit_coprocessor_data_transfer(uint32_t high_nibble, uint8_t cp_ · 2 unmodified lines
1349 opcode |= ENCODE_IMMEDIATE_FLAG; /* if set, it means it's NOT immediate */1289 opcode |= ENCODE_IMMEDIATE_FLAG; /* if set, it means it's NOT immediate */
1350 opcode |= offset->reg;1290 opcode |= offset->reg;
1351 tcc_error("Using register offset to register address is not possible here");1291 tcc_error("Using register offset to register address is not possible here");
1352 return;
1353 } else if (offset->type == OP_VREG64) {1292 } else if (offset->type == OP_VREG64) {
1354 opcode |= 16;1293 opcode |= 16;
1355 opcode |= offset->reg;1294 opcode |= offset->reg;
@@ -1380,36 +1319,22 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *s1, int token) · 24 unmodified lines
1380 next();1319 next();
1381 } else {1320 } else {
1382 expect("'c<number>'");1321 expect("'c<number>'");
1383 return;
1384 }1322 }
1385 1323
1386 if (tok == ',')1324 skip(',');
1387 next();
1388 else
1389 expect("','");
1390 1325
1391 if (tok >= TOK_ASM_c0 && tok <= TOK_ASM_c15) {1326 if (tok >= TOK_ASM_c0 && tok <= TOK_ASM_c15) {
1392 coprocessor_destination_register = tok - TOK_ASM_c0;1327 coprocessor_destination_register = tok - TOK_ASM_c0;
1393 next();1328 next();
1394 } else {1329 } else {
1395 expect("'c<number>'");1330 expect("'c<number>'");
1396 return;
1397 }1331 }
1398 1332
1399 if (tok == ',')1333 skip(',');
1400 next();1334 skip('[');
1401 else
1402 expect("','");
1403
1404 if (tok != '[')
1405 expect("'['");
1406 else
1407 next(); // skip '['
1408
1409 parse_operand(s1, &ops[1]);1335 parse_operand(s1, &ops[1]);
1410 if (ops[1].type != OP_REG32) {1336 if (ops[1].type != OP_REG32) {
1411 expect("(first source operand) register");1337 expect("(first source operand) register");
1412 return;
1413 }1338 }
1414 if (tok == ']') {1339 if (tok == ']') {
1415 next();1340 next();
@@ -1426,11 +1351,9 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *s1, int token) · 10 unmodified lines
1426 if (ops[2].type == OP_REG32) {1351 if (ops[2].type == OP_REG32) {
1427 if (ops[2].reg == 15) {1352 if (ops[2].reg == 15) {
1428 tcc_error("Using 'pc' for register offset in '%s' is not implemented by ARM", get_tok_str(token, NULL));1353 tcc_error("Using 'pc' for register offset in '%s' is not implemented by ARM", get_tok_str(token, NULL));
1429 return;
1430 }1354 }
1431 } else if (ops[2].type == OP_VREG64) {1355 } else if (ops[2].type == OP_VREG64) {
1432 tcc_error("'%s' does not support VFP register operand", get_tok_str(token, NULL));1356 tcc_error("'%s' does not support VFP register operand", get_tok_str(token, NULL));
1433 return;
1434 }1357 }
1435 } else {1358 } else {
1436 // end of input expression in brackets--assume 0 offset1359 // end of input expression in brackets--assume 0 offset
@@ -1439,10 +1362,7 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *s1, int token) · 2 unmodified lines
1439 preincrement = 1; // add offset before transfer1362 preincrement = 1; // add offset before transfer
1440 }1363 }
1441 if (!closed_bracket) {1364 if (!closed_bracket) {
1442 if (tok != ']')1365 skip(']');
1443 expect("']'");
1444 else
1445 next(); // skip ']'
1446 preincrement = 1; // add offset before transfer1366 preincrement = 1; // add offset before transfer
1447 if (tok == '!') {1367 if (tok == '!') {
1448 exclam = 1;1368 exclam = 1;
@@ -1511,40 +1431,26 @@ static void asm_floating_point_single_data_transfer_opcode(TCCState *s1, int tok · 62 unmodified lines
1511 next();1431 next();
1512 } else {1432 } else {
1513 expect("floating point register");1433 expect("floating point register");
1514 return;
1515 }1434 }
1516 1435
1517 if (tok == ',')1436 skip(',');
1518 next();1437 skip('[');
1519 else
1520 expect("','");
1521
1522 if (tok != '[')
1523 expect("'['");
1524 else
1525 next(); // skip '['
1526
1527 parse_operand(s1, &ops[1]);1438 parse_operand(s1, &ops[1]);
1528 if (ops[1].type != OP_REG32) {1439 if (ops[1].type != OP_REG32) {
1529 expect("(first source operand) register");1440 expect("(first source operand) register");
1530 return;
1531 }1441 }
1532 if (tok == ',') {1442 if (tok == ',') {
1533 next(); // skip ','1443 next(); // skip ','
1534 parse_operand(s1, &ops[2]);1444 parse_operand(s1, &ops[2]);
1535 if (ops[2].type != OP_IM8 && ops[2].type != OP_IM8N) {1445 if (ops[2].type != OP_IM8 && ops[2].type != OP_IM8N) {
1536 expect("immediate offset");1446 expect("immediate offset");
1537 return;
1538 }1447 }
1539 } else {1448 } else {
1540 // end of input expression in brackets--assume 0 offset1449 // end of input expression in brackets--assume 0 offset
1541 ops[2].type = OP_IM8;1450 ops[2].type = OP_IM8;
1542 ops[2].e.v = 0;1451 ops[2].e.v = 0;
1543 }1452 }
1544 if (tok != ']')1453 skip(']');
1545 expect("']'");
1546 else
1547 next(); // skip ']'
1548 1454
1549 switch (ARM_INSTRUCTION_GROUP(token)) {1455 switch (ARM_INSTRUCTION_GROUP(token)) {
1550 case TOK_ASM_vldreq:1456 case TOK_ASM_vldreq:
@@ -1583,19 +1489,10 @@ static void asm_floating_point_block_data_transfer_opcode(TCCState *s1, int toke · 32 unmodified lines
1583 op0_exclam = 1;1489 op0_exclam = 1;
1584 next(); // skip '!'1490 next(); // skip '!'
1585 }1491 }
1586 if (tok == ',')1492 skip(',');
1587 next(); // skip comma
1588 else {
1589 expect("','");
1590 return;
1591 }
1592 }1493 }
1593 1494
1594 if (tok != '{') {1495 skip('{');
1595 expect("'{'");
1596 return;
1597 }
1598 next(); // skip '{'
1599 first_regset_register = asm_parse_vfp_regvar(tok, 1);1496 first_regset_register = asm_parse_vfp_regvar(tok, 1);
1600 if ((first_regset_register = asm_parse_vfp_regvar(tok, 1)) != -1) {1497 if ((first_regset_register = asm_parse_vfp_regvar(tok, 1)) != -1) {
1601 coprocessor = CP_DOUBLE_PRECISION_FLOAT;1498 coprocessor = CP_DOUBLE_PRECISION_FLOAT;
@@ -1605,7 +1502,6 @@ static void asm_floating_point_block_data_transfer_opcode(TCCState *s1, int toke · 3 unmodified lines
1605 next();1502 next();
1606 } else {1503 } else {
1607 expect("floating-point register");1504 expect("floating-point register");
1608 return;
1609 }1505 }
1610 1506
1611 if (tok == '-') {1507 if (tok == '-') {
@@ -1614,21 +1510,14 @@ static void asm_floating_point_block_data_transfer_opcode(TCCState *s1, int toke · 2 unmodified lines
1614 next();1510 next();
1615 else {1511 else {
1616 expect("floating-point register");1512 expect("floating-point register");
1617 return;
1618 }1513 }
1619 } else1514 } else
1620 last_regset_register = first_regset_register;1515 last_regset_register = first_regset_register;
1621 1516
1622 if (last_regset_register < first_regset_register) {1517 if (last_regset_register < first_regset_register) {
1623 tcc_error("registers will be processed in ascending order by hardware--but are not specified in ascending order here");1518 tcc_error("registers will be processed in ascending order by hardware--but are not specified in ascending order here");
1624 return;
1625 }
1626 if (tok != '}') {
1627 expect("'}'");
1628 return;
1629 }1519 }
1630 next(); // skip '}'1520 skip('}');
1631
1632 // Note: 0 (one down) is not implemented by us regardless.1521 // Note: 0 (one down) is not implemented by us regardless.
1633 regset_item_count = last_regset_register - first_regset_register + 1;1522 regset_item_count = last_regset_register - first_regset_register + 1;
1634 if (coprocessor == CP_DOUBLE_PRECISION_FLOAT)1523 if (coprocessor == CP_DOUBLE_PRECISION_FLOAT)
@@ -1659,7 +1548,6 @@ static void asm_floating_point_block_data_transfer_opcode(TCCState *s1, int toke · 24 unmodified lines
1659 break;1548 break;
1660 default:1549 default:
1661 expect("floating point block data transfer instruction");1550 expect("floating point block data transfer instruction");
1662 return;
1663 }1551 }
1664 if (ops[0].type != OP_REG32)1552 if (ops[0].type != OP_REG32)
1665 expect("(first operand) register");1553 expect("(first operand) register");
@@ -1713,7 +1601,6 @@ static uint32_t vmov_parse_immediate_value() { · 47 unmodified lines
1713 1601
1714 if (tok != TOK_PPNUM) {1602 if (tok != TOK_PPNUM) {
1715 expect("immediate value");1603 expect("immediate value");
1716 return 0;
1717 }1604 }
1718 p = tokc.str.data;1605 p = tokc.str.data;
1719 errno = 0;1606 errno = 0;
@@ -1721,7 +1608,6 @@ static uint32_t vmov_parse_immediate_value() { · 1 unmodified line
1721 1608
1722 if (errno || integral_value >= 32) {1609 if (errno || integral_value >= 32) {
1723 tcc_error("invalid floating-point immediate value");1610 tcc_error("invalid floating-point immediate value");
1724 return 0;
1725 }1611 }
1726 1612
1727 value = (uint32_t) integral_value * VMOV_ONE;1613 value = (uint32_t) integral_value * VMOV_ONE;
@@ -1754,7 +1640,6 @@ static uint8_t vmov_encode_immediate_value(uint32_t value) · 26 unmodified lines
1754 }1640 }
1755 if (r == -1 || value < beginning || value > end) {1641 if (r == -1 || value < beginning || value > end) {
1756 tcc_error("invalid decimal number for vmov: %d", value);1642 tcc_error("invalid decimal number for vmov: %d", value);
1757 return 0;
1758 }1643 }
1759 n = vmov_linear_approx_index(beginning, end, value);1644 n = vmov_linear_approx_index(beginning, end, value);
1760 return n | (((3 - r) & 0x7) << 4);1645 return n | (((3 - r) & 0x7) << 4);
@@ -1788,7 +1673,6 @@ static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *s · 27 unmodified lines
1788 operands[1] = 5;1673 operands[1] = 5;
1789 if (immediate_value) {1674 if (immediate_value) {
1790 expect("Immediate value 0");1675 expect("Immediate value 0");
1791 return;
1792 }1676 }
1793 break;1677 break;
1794 case TOK_ASM_vcmpeeq_f32:1678 case TOK_ASM_vcmpeeq_f32:
@@ -1797,7 +1681,6 @@ static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *s · 2 unmodified lines
1797 operands[1] = 5;1681 operands[1] = 5;
1798 if (immediate_value) {1682 if (immediate_value) {
1799 expect("Immediate value 0");1683 expect("Immediate value 0");
1800 return;
1801 }1684 }
1802 break;1685 break;
1803 case TOK_ASM_vmoveq_f32:1686 case TOK_ASM_vmoveq_f32:
@@ -1813,7 +1696,6 @@ static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *s · 9 unmodified lines
1813 break;1696 break;
1814 default:1697 default:
1815 expect("known floating point with immediate instruction");1698 expect("known floating point with immediate instruction");
1816 return;
1817 }1699 }
1818 1700
1819 if (coprocessor == CP_SINGLE_PRECISION_FLOAT) {1701 if (coprocessor == CP_SINGLE_PRECISION_FLOAT) {
@@ -1833,7 +1715,6 @@ static void asm_floating_point_reg_arm_reg_transfer_opcode_tail(TCCState *s1, in · 13 unmodified lines
1833 // "vmov.f32 r2, s3" or "vmov.f32 s3, r2"1715 // "vmov.f32 r2, s3" or "vmov.f32 s3, r2"
1834 if (nb_ops != 2 || nb_arm_regs != 1) {1716 if (nb_ops != 2 || nb_arm_regs != 1) {
1835 tcc_error("vmov.f32 only implemented for one VFP register operand and one ARM register operands");1717 tcc_error("vmov.f32 only implemented for one VFP register operand and one ARM register operands");
1836 return;
1837 }1718 }
1838 if (ops[0].type != OP_REG32) { // determine mode: load or store1719 if (ops[0].type != OP_REG32) { // determine mode: load or store
1839 // need to swap operands 0 and 11720 // need to swap operands 0 and 1
@@ -1860,7 +1741,6 @@ static void asm_floating_point_reg_arm_reg_transfer_opcode_tail(TCCState *s1, in · 20 unmodified lines
1860 case CP_DOUBLE_PRECISION_FLOAT:1741 case CP_DOUBLE_PRECISION_FLOAT:
1861 if (nb_ops != 3 || nb_arm_regs != 2) {1742 if (nb_ops != 3 || nb_arm_regs != 2) {
1862 tcc_error("vmov.f32 only implemented for one VFP register operand and two ARM register operands");1743 tcc_error("vmov.f32 only implemented for one VFP register operand and two ARM register operands");
1863 return;
1864 }1744 }
1865 // Determine whether it's a store into a VFP register (vmov "d1, r2, r3") rather than "vmov r2, r3, d1"1745 // Determine whether it's a store into a VFP register (vmov "d1, r2, r3") rather than "vmov r2, r3, d1"
1866 if (ops[0].type == OP_VREG64) {1746 if (ops[0].type == OP_VREG64) {
@@ -1873,11 +1753,9 @@ static void asm_floating_point_reg_arm_reg_transfer_opcode_tail(TCCState *s1, in · 6 unmodified lines
1873 memcpy(&ops[2], &temp, sizeof(ops[2]));1753 memcpy(&ops[2], &temp, sizeof(ops[2]));
1874 } else {1754 } else {
1875 tcc_error("vmov.f64 only implemented for one VFP register operand and two ARM register operands");1755 tcc_error("vmov.f64 only implemented for one VFP register operand and two ARM register operands");
1876 return;
1877 }1756 }
1878 } else if (ops[0].type != OP_REG32 || ops[1].type != OP_REG32 || ops[2].type != OP_VREG64) {1757 } else if (ops[0].type != OP_REG32 || ops[1].type != OP_REG32 || ops[2].type != OP_VREG64) {
1879 tcc_error("vmov.f64 only implemented for one VFP register operand and two ARM register operands");1758 tcc_error("vmov.f64 only implemented for one VFP register operand and two ARM register operands");
1880 return;
1881 } else {1759 } else {
1882 opcode1 |= 1;1760 opcode1 |= 1;
1883 }1761 }
@@ -1915,7 +1793,6 @@ static void asm_floating_point_vcvt_data_processing_opcode(TCCState *s1, int tok · 31 unmodified lines
1915 break;1793 break;
1916 default:1794 default:
1917 tcc_error("Unknown coprocessor for instruction '%s'", get_tok_str(token, NULL));1795 tcc_error("Unknown coprocessor for instruction '%s'", get_tok_str(token, NULL));
1918 return;
1919 }1796 }
1920 1797
1921 parse_operand(s1, &ops[0]);1798 parse_operand(s1, &ops[0]);
@@ -1942,10 +1819,7 @@ static void asm_floating_point_vcvt_data_processing_opcode(TCCState *s1, int tok · 20 unmodified lines
1942 break;1819 break;
1943 }1820 }
1944 1821
1945 if (tok == ',')1822 skip(',');
1946 next();
1947 else
1948 expect("','");
1949 parse_operand(s1, &ops[2]);1823 parse_operand(s1, &ops[2]);
1950 1824
1951 switch (ARM_INSTRUCTION_GROUP(token)) {1825 switch (ARM_INSTRUCTION_GROUP(token)) {
@@ -1977,7 +1851,6 @@ static void asm_floating_point_vcvt_data_processing_opcode(TCCState *s1, int tok · 25 unmodified lines
1977 if (ops[0].type == OP_VREG64 && ops[2].type == OP_VREG32) {1851 if (ops[0].type == OP_VREG64 && ops[2].type == OP_VREG32) {
1978 } else {1852 } else {
1979 expect("d<number>, s<number>");1853 expect("d<number>, s<number>");
1980 return;
1981 }1854 }
1982 break;1855 break;
1983 default:1856 default:
@@ -1985,13 +1858,11 @@ static void asm_floating_point_vcvt_data_processing_opcode(TCCState *s1, int tok · 1 unmodified line
1985 if (ops[0].type == OP_VREG32 && ops[2].type == OP_VREG32) {1858 if (ops[0].type == OP_VREG32 && ops[2].type == OP_VREG32) {
1986 } else {1859 } else {
1987 expect("s<number>, s<number>");1860 expect("s<number>, s<number>");
1988 return;
1989 }1861 }
1990 } else if (coprocessor == CP_DOUBLE_PRECISION_FLOAT) {1862 } else if (coprocessor == CP_DOUBLE_PRECISION_FLOAT) {
1991 if (ops[0].type == OP_VREG32 && ops[2].type == OP_VREG64) {1863 if (ops[0].type == OP_VREG32 && ops[2].type == OP_VREG64) {
1992 } else {1864 } else {
1993 expect("s<number>, d<number>");1865 expect("s<number>, d<number>");
1994 return;
1995 }1866 }
1996 }1867 }
1997 }1868 }
@@ -2074,16 +1945,13 @@ static void asm_floating_point_data_processing_opcode(TCCState *s1, int token) { · 76 unmodified lines
2074 } else if (ops[nb_ops].type == OP_VREG32) {1945 } else if (ops[nb_ops].type == OP_VREG32) {
2075 if (coprocessor != CP_SINGLE_PRECISION_FLOAT) {1946 if (coprocessor != CP_SINGLE_PRECISION_FLOAT) {
2076 expect("'s<number>'");1947 expect("'s<number>'");
2077 return;
2078 }1948 }
2079 } else if (ops[nb_ops].type == OP_VREG64) {1949 } else if (ops[nb_ops].type == OP_VREG64) {
2080 if (coprocessor != CP_DOUBLE_PRECISION_FLOAT) {1950 if (coprocessor != CP_DOUBLE_PRECISION_FLOAT) {
2081 expect("'d<number>'");1951 expect("'d<number>'");
2082 return;
2083 }1952 }
2084 } else {1953 } else {
2085 expect("floating point register");1954 expect("floating point register");
2086 return;
2087 }1955 }
2088 ++nb_ops;1956 ++nb_ops;
2089 if (tok == ',')1957 if (tok == ',')
@@ -2100,7 +1968,6 @@ static void asm_floating_point_data_processing_opcode(TCCState *s1, int token) { · 10 unmodified lines
2100 }1968 }
2101 if (nb_ops < 3) {1969 if (nb_ops < 3) {
2102 tcc_error("Not enough operands for '%s' (%u)", get_tok_str(token, NULL), nb_ops);1970 tcc_error("Not enough operands for '%s' (%u)", get_tok_str(token, NULL), nb_ops);
2103 return;
2104 }1971 }
2105 }1972 }
2106 1973
@@ -2199,7 +2066,6 @@ static void asm_floating_point_data_processing_opcode(TCCState *s1, int token) { · 92 unmodified lines
2199 break;2066 break;
2200 default:2067 default:
2201 expect("known floating point instruction");2068 expect("known floating point instruction");
2202 return;
2203 }2069 }
2204 2070
2205 if (coprocessor == CP_SINGLE_PRECISION_FLOAT) {2071 if (coprocessor == CP_SINGLE_PRECISION_FLOAT) {
@@ -2256,46 +2122,34 @@ static void asm_floating_point_status_register_opcode(TCCState* s1, int token) · 50 unmodified lines
2256 parse_operand(s1, &arm_operand);2122 parse_operand(s1, &arm_operand);
2257 if (arm_operand.type == OP_REG32 && arm_operand.reg == 15) {2123 if (arm_operand.type == OP_REG32 && arm_operand.reg == 15) {
2258 tcc_error("'%s' does not support 'pc' as operand", get_tok_str(token, NULL));2124 tcc_error("'%s' does not support 'pc' as operand", get_tok_str(token, NULL));
2259 return;
2260 }2125 }
2261 }2126 }
2262 2127
2263 if (tok != ',')2128 skip(',');
2264 expect("','");
2265 else
2266 next(); // skip ','
2267 vfp_sys_reg = asm_parse_vfp_status_regvar(tok);2129 vfp_sys_reg = asm_parse_vfp_status_regvar(tok);
2268 next(); // skip vfp sys reg2130 next(); // skip vfp sys reg
2269 if (arm_operand.type == OP_REG32 && arm_operand.reg == 15 && vfp_sys_reg != 1) {2131 if (arm_operand.type == OP_REG32 && arm_operand.reg == 15 && vfp_sys_reg != 1) {
2270 tcc_error("'%s' only supports the variant 'vmrs apsr_nzcv, fpscr' here", get_tok_str(token, NULL));2132 tcc_error("'%s' only supports the variant 'vmrs apsr_nzcv, fpscr' here", get_tok_str(token, NULL));
2271 return;
2272 }2133 }
2273 break;2134 break;
2274 case TOK_ASM_vmsreq:2135 case TOK_ASM_vmsreq:
2275 opcode = 0xe;2136 opcode = 0xe;
2276 vfp_sys_reg = asm_parse_vfp_status_regvar(tok);2137 vfp_sys_reg = asm_parse_vfp_status_regvar(tok);
2277 next(); // skip vfp sys reg2138 next(); // skip vfp sys reg
2278 if (tok != ',')2139 skip(',');
2279 expect("','");
2280 else
2281 next(); // skip ','
2282 parse_operand(s1, &arm_operand);2140 parse_operand(s1, &arm_operand);
2283 if (arm_operand.type == OP_REG32 && arm_operand.reg == 15) {2141 if (arm_operand.type == OP_REG32 && arm_operand.reg == 15) {
2284 tcc_error("'%s' does not support 'pc' as operand", get_tok_str(token, NULL));2142 tcc_error("'%s' does not support 'pc' as operand", get_tok_str(token, NULL));
2285 return;
2286 }2143 }
2287 break;2144 break;
2288 default:2145 default:
2289 expect("floating point status register instruction");2146 expect("floating point status register instruction");
2290 return;
2291 }2147 }
2292 if (vfp_sys_reg == -1) {2148 if (vfp_sys_reg == -1) {
2293 expect("VFP system register");2149 expect("VFP system register");
2294 return;
2295 }2150 }
2296 if (arm_operand.type != OP_REG32) {2151 if (arm_operand.type != OP_REG32) {
2297 expect("ARM register");2152 expect("ARM register");
2298 return;
2299 }2153 }
2300 asm_emit_coprocessor_opcode(condition_code_of_token(token), coprocessor, opcode, arm_operand.reg, vfp_sys_reg, 0x10, 0, 0);2154 asm_emit_coprocessor_opcode(condition_code_of_token(token), coprocessor, opcode, arm_operand.reg, vfp_sys_reg, 0x10, 0, 0);
2301}2155}
@@ -2327,24 +2181,17 @@ static void asm_misc_single_data_transfer_opcode(TCCState *s1, int token) · 25 unmodified lines
2327 opcode |= ENCODE_RD(ops[0].reg);2181 opcode |= ENCODE_RD(ops[0].reg);
2328 else {2182 else {
2329 expect("(destination operand) register");2183 expect("(destination operand) register");
2330 return;
2331 }2184 }
2332 if (tok != ',')2185 if (tok != ',')
2333 expect("at least two arguments");2186 expect("at least two arguments");
2334 else2187 else
2335 next(); // skip ','2188 next(); // skip ','
2336 2189 skip('[');
2337 if (tok != '[')
2338 expect("'['");
2339 else
2340 next(); // skip '['
2341
2342 parse_operand(s1, &ops[1]);2190 parse_operand(s1, &ops[1]);
2343 if (ops[1].type == OP_REG32)2191 if (ops[1].type == OP_REG32)
2344 opcode |= ENCODE_RN(ops[1].reg);2192 opcode |= ENCODE_RN(ops[1].reg);
2345 else {2193 else {
2346 expect("(first source operand) register");2194 expect("(first source operand) register");
2347 return;
2348 }2195 }
2349 if (tok == ']') {2196 if (tok == ']') {
2350 next();2197 next();
@@ -2365,10 +2212,7 @@ static void asm_misc_single_data_transfer_opcode(TCCState *s1, int token) · 14 unmodified lines
2365 opcode |= 1 << 24; // add offset before transfer2212 opcode |= 1 << 24; // add offset before transfer
2366 }2213 }
2367 if (!closed_bracket) {2214 if (!closed_bracket) {
2368 if (tok != ']')2215 skip(']');
2369 expect("']'");
2370 else
2371 next(); // skip ']'
2372 opcode |= 1 << 24; // add offset before transfer2216 opcode |= 1 << 24; // add offset before transfer
2373 if (tok == '!') {2217 if (tok == '!') {
2374 exclam = 1;2218 exclam = 1;
@@ -2379,7 +2223,6 @@ static void asm_misc_single_data_transfer_opcode(TCCState *s1, int token) · 4 unmodified lines
2379 if (exclam) {2223 if (exclam) {
2380 if ((opcode & (1 << 24)) == 0) {2224 if ((opcode & (1 << 24)) == 0) {
2381 tcc_error("result of '%s' would be unpredictable here", get_tok_str(token, NULL));2225 tcc_error("result of '%s' would be unpredictable here", get_tok_str(token, NULL));
2382 return;
2383 }2226 }
2384 opcode |= 1 << 21; // write offset back into register2227 opcode |= 1 << 21; // write offset back into register
2385 }2228 }
@@ -2465,7 +2308,6 @@ static void asm_branch_opcode(TCCState *s1, int token) · 79 unmodified lines
2465 esym = elfsym(e.sym);2308 esym = elfsym(e.sym);
2466 if (!esym || esym->st_shndx != cur_text_section->sh_num) {2309 if (!esym || esym->st_shndx != cur_text_section->sh_num) {
2467 tcc_error("invalid branch target");2310 tcc_error("invalid branch target");
2468 return;
2469 }2311 }
2470 jmp_disp = encbranchoffset(ind, e.v + esym->st_value, 1);2312 jmp_disp = encbranchoffset(ind, e.v + esym->st_value, 1);
2471 break;2313 break;
@@ -2518,7 +2360,6 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 46 unmodified lines
2518 return;2360 return;
2519 default:2361 default:
2520 expect("instruction");2362 expect("instruction");
2521 return;
2522 }2363 }
2523 }2364 }
2524 2365
@@ -2740,7 +2581,6 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 215 unmodified lines
2740ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier)2581ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier)
2741{2582{
2742 int r, reg, size, val;2583 int r, reg, size, val;
2743 char buf[64];
2744 2584
2745 r = sv->r;2585 r = sv->r;
2746 if ((r & VT_VALMASK) == VT_CONST) {2586 if ((r & VT_VALMASK) == VT_CONST) {
@@ -2767,19 +2607,16 @@ ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier) · 20 unmodified lines
2767 val = sv->c.i;2607 val = sv->c.i;
2768 if (modifier == 'n')2608 if (modifier == 'n')
2769 val = -val;2609 val = -val;
2770 snprintf(buf, sizeof(buf), "%d", (int) sv->c.i);2610 cstr_printf(add_str, "%d", (int) sv->c.i);
2771 cstr_cat(add_str, buf, -1);
2772 no_offset:;2611 no_offset:;
2773 } else if ((r & VT_VALMASK) == VT_LOCAL) {2612 } else if ((r & VT_VALMASK) == VT_LOCAL) {
2774 snprintf(buf, sizeof(buf), "[fp,#%d]", (int) sv->c.i);2613 cstr_printf(add_str, "[fp,#%d]", (int) sv->c.i);
2775 cstr_cat(add_str, buf, -1);
2776 } else if (r & VT_LVAL) {2614 } else if (r & VT_LVAL) {
2777 reg = r & VT_VALMASK;2615 reg = r & VT_VALMASK;
2778 if (reg >= VT_CONST)2616 if (reg >= VT_CONST)
2779 tcc_internal_error("");2617 tcc_internal_error("");
2780 snprintf(buf, sizeof(buf), "[%s]",2618 cstr_printf(add_str, "[%s]",
2781 get_tok_str(TOK_ASM_r0 + reg, NULL));2619 get_tok_str(TOK_ASM_r0 + reg, NULL));
2782 cstr_cat(add_str, buf, -1);
2783 } else {2620 } else {
2784 /* register case */2621 /* register case */
2785 reg = r & VT_VALMASK;2622 reg = r & VT_VALMASK;
@@ -2808,8 +2645,7 @@ ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier) · 22 unmodified lines
2808 reg = TOK_ASM_r0 + reg;2645 reg = TOK_ASM_r0 + reg;
2809 break;2646 break;
2810 }2647 }
2811 snprintf(buf, sizeof(buf), "%s", get_tok_str(reg, NULL));2648 cstr_printf(add_str, "%s", get_tok_str(reg, NULL));
2812 cstr_cat(add_str, buf, -1);
2813 }2649 }
2814}2650}
2815 2651
@@ -2928,7 +2764,6 @@ static inline int constraint_priority(const char *str) · 112 unmodified lines
2928 break;2764 break;
2929 default:2765 default:
2930 tcc_error("unknown constraint '%c'", c);2766 tcc_error("unknown constraint '%c'", c);
2931 pr = 0;
2932 }2767 }
2933 if (pr > priority)2768 if (pr > priority)
2934 priority = pr;2769 priority = pr;
arm-link.c+3−3
@@ -30,7 +30,7 @@ enum float_abi { · 29 unmodified lines
30#ifdef NEED_RELOC_TYPE30#ifdef NEED_RELOC_TYPE
31/* Returns 1 for a code relocation, 0 for a data relocation. For unknown31/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
32 relocations, returns -1. */32 relocations, returns -1. */
33int code_reloc (int reloc_type)33ST_FUNC int code_reloc (int reloc_type)
34{34{
35 switch (reloc_type) {35 switch (reloc_type) {
36 case R_ARM_MOVT_ABS:36 case R_ARM_MOVT_ABS:
@@ -68,7 +68,7 @@ int code_reloc (int reloc_type) · 31 unmodified lines
68/* Returns an enumerator to describe whether and when the relocation needs a68/* Returns an enumerator to describe whether and when the relocation needs a
69 GOT and/or PLT entry to be created. See tcc.h for a description of the69 GOT and/or PLT entry to be created. See tcc.h for a description of the
70 different values. */70 different values. */
71int gotplt_entry_type (int reloc_type)71ST_FUNC int gotplt_entry_type (int reloc_type)
72{72{
73 switch (reloc_type) {73 switch (reloc_type) {
74 case R_ARM_NONE:74 case R_ARM_NONE:
@@ -179,7 +179,7 @@ ST_FUNC void relocate_plt(TCCState *s1) · 104 unmodified lines
179#endif179#endif
180#endif180#endif
181 181
182void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)182ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
183{183{
184 ElfW(Sym) *sym;184 ElfW(Sym) *sym;
185 int sym_index, esym_index;185 int sym_index, esym_index;
arm64-link.c+3−3
@@ -24,7 +24,7 @@ · 23 unmodified lines
24#ifdef NEED_RELOC_TYPE24#ifdef NEED_RELOC_TYPE
25/* Returns 1 for a code relocation, 0 for a data relocation. For unknown25/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
26 relocations, returns -1. */26 relocations, returns -1. */
27int code_reloc (int reloc_type)27ST_FUNC int code_reloc (int reloc_type)
28{28{
29 switch (reloc_type) {29 switch (reloc_type) {
30 case R_AARCH64_ABS32:30 case R_AARCH64_ABS32:
@@ -58,7 +58,7 @@ int code_reloc (int reloc_type) · 27 unmodified lines
58/* Returns an enumerator to describe whether and when the relocation needs a58/* Returns an enumerator to describe whether and when the relocation needs a
59 GOT and/or PLT entry to be created. See tcc.h for a description of the59 GOT and/or PLT entry to be created. See tcc.h for a description of the
60 different values. */60 different values. */
61int gotplt_entry_type (int reloc_type)61ST_FUNC int gotplt_entry_type (int reloc_type)
62{62{
63 switch (reloc_type) {63 switch (reloc_type) {
64 case R_AARCH64_PREL32:64 case R_AARCH64_PREL32:
@@ -168,7 +168,7 @@ ST_FUNC void relocate_plt(TCCState *s1) · 103 unmodified lines
168#endif168#endif
169#endif169#endif
170 170
171void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)171ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
172{172{
173 int sym_index = ELFW(R_SYM)(rel->r_info), esym_index;173 int sym_index = ELFW(R_SYM)(rel->r_info), esym_index;
174#ifdef DEBUG_RELOC174#ifdef DEBUG_RELOC
c67-link.c+3−3
@@ -24,7 +24,7 @@ · 23 unmodified lines
24 24
25/* Returns 1 for a code relocation, 0 for a data relocation. For unknown25/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
26 relocations, returns -1. */26 relocations, returns -1. */
27int code_reloc (int reloc_type)27ST_FUNC int code_reloc (int reloc_type)
28{28{
29 switch (reloc_type) {29 switch (reloc_type) {
30 case R_C60_32:30 case R_C60_32:
@@ -45,7 +45,7 @@ int code_reloc (int reloc_type) · 14 unmodified lines
45/* Returns an enumerator to describe whether and when the relocation needs a45/* Returns an enumerator to describe whether and when the relocation needs a
46 GOT and/or PLT entry to be created. See tcc.h for a description of the46 GOT and/or PLT entry to be created. See tcc.h for a description of the
47 different values. */47 different values. */
48int gotplt_entry_type (int reloc_type)48ST_FUNC int gotplt_entry_type (int reloc_type)
49{49{
50 switch (reloc_type) {50 switch (reloc_type) {
51 case R_C60_32:51 case R_C60_32:
@@ -91,7 +91,7 @@ ST_FUNC void relocate_plt(TCCState *s1) · 39 unmodified lines
91 }91 }
92}92}
93 93
94void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)94ST_FUNC void 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+6−19
@@ -143,10 +143,12 @@ enum { · 142 unmodified lines
143# define TREG_XAX TREG_RAX143# define TREG_XAX TREG_RAX
144# define TREG_XCX TREG_RCX144# define TREG_XCX TREG_RCX
145# define TREG_XDX TREG_RDX145# define TREG_XDX TREG_RDX
146# define TOK_ASM_xax TOK_ASM_rax
146#else147#else
147# define TREG_XAX TREG_EAX148# define TREG_XAX TREG_EAX
148# define TREG_XCX TREG_ECX149# define TREG_XCX TREG_ECX
149# define TREG_XDX TREG_EDX150# define TREG_XDX TREG_EDX
151# define TOK_ASM_xax TOK_ASM_eax
150#endif152#endif
151 153
152typedef struct ASMInstr {154typedef struct ASMInstr {
@@ -1505,7 +1507,6 @@ ST_FUNC void subst_asm_operand(CString *add_str, · 1352 unmodified lines
1505 SValue *sv, int modifier)1507 SValue *sv, int modifier)
1506{1508{
1507 int r, reg, size, val;1509 int r, reg, size, val;
1508 char buf[64];
1509 1510
1510 r = sv->r;1511 r = sv->r;
1511 if ((r & VT_VALMASK) == VT_CONST) {1512 if ((r & VT_VALMASK) == VT_CONST) {
@@ -1532,32 +1533,19 @@ ST_FUNC void subst_asm_operand(CString *add_str, · 20 unmodified lines
1532 val = sv->c.i;1533 val = sv->c.i;
1533 if (modifier == 'n')1534 if (modifier == 'n')
1534 val = -val;1535 val = -val;
1535 snprintf(buf, sizeof(buf), "%d", (int)sv->c.i);1536 cstr_printf(add_str, "%d", (int)sv->c.i);
1536 cstr_cat(add_str, buf, -1);
1537 no_offset:;1537 no_offset:;
1538#ifdef TCC_TARGET_X86_641538#ifdef TCC_TARGET_X86_64
1539 if (r & VT_LVAL)1539 if (r & VT_LVAL)
1540 cstr_cat(add_str, "(%rip)", -1);1540 cstr_cat(add_str, "(%rip)", -1);
1541#endif1541#endif
1542 } else if ((r & VT_VALMASK) == VT_LOCAL) {1542 } else if ((r & VT_VALMASK) == VT_LOCAL) {
1543#ifdef TCC_TARGET_X86_641543 cstr_printf(add_str, "%d(%%%s)", (int)sv->c.i, get_tok_str(TOK_ASM_xax + 5, NULL));
1544 snprintf(buf, sizeof(buf), "%d(%%rbp)", (int)sv->c.i);
1545#else
1546 snprintf(buf, sizeof(buf), "%d(%%ebp)", (int)sv->c.i);
1547#endif
1548 cstr_cat(add_str, buf, -1);
1549 } else if (r & VT_LVAL) {1544 } else if (r & VT_LVAL) {
1550 reg = r & VT_VALMASK;1545 reg = r & VT_VALMASK;
1551 if (reg >= VT_CONST)1546 if (reg >= VT_CONST)
1552 tcc_internal_error("");1547 tcc_internal_error("");
1553 snprintf(buf, sizeof(buf), "(%%%s)",1548 cstr_printf(add_str, "(%%%s)", get_tok_str(TOK_ASM_xax + reg, NULL));
1554#ifdef TCC_TARGET_X86_64
1555 get_tok_str(TOK_ASM_rax + reg, NULL)
1556#else
1557 get_tok_str(TOK_ASM_eax + reg, NULL)
1558#endif
1559 );
1560 cstr_cat(add_str, buf, -1);
1561 } else {1549 } else {
1562 /* register case */1550 /* register case */
1563 reg = r & VT_VALMASK;1551 reg = r & VT_VALMASK;
@@ -1617,8 +1605,7 @@ ST_FUNC void subst_asm_operand(CString *add_str, · 53 unmodified lines
1617 break;1605 break;
1618#endif1606#endif
1619 }1607 }
1620 snprintf(buf, sizeof(buf), "%%%s", get_tok_str(reg, NULL));1608 cstr_printf(add_str, "%%%s", get_tok_str(reg, NULL));
1621 cstr_cat(add_str, buf, -1);
1622 }1609 }
1623}1610}
1624 1611
i386-gen.c+8−24
@@ -410,9 +410,7 @@ ST_FUNC void gfunc_call(int nb_args) · 409 unmodified lines
410{410{
411 int size, align, r, args_size, i, func_call;411 int size, align, r, args_size, i, func_call;
412 Sym *func_sym;412 Sym *func_sym;
413 // Look ahead to the function on the stack to get the function call type413
414 int func_call2 = ((vtop - nb_args)->type.ref)->f.func_call;
415
416#ifdef CONFIG_TCC_BCHECK414#ifdef CONFIG_TCC_BCHECK
417 if (tcc_state->do_bounds_check)415 if (tcc_state->do_bounds_check)
418 gbound_args(nb_args);416 gbound_args(nb_args);
@@ -420,12 +418,6 @@ ST_FUNC void gfunc_call(int nb_args) · 1 unmodified line
420 418
421 args_size = 0;419 args_size = 0;
422 for(i = 0;i < nb_args; i++) {420 for(i = 0;i < nb_args; i++) {
423 if (func_call2 == FUNC_THISCALL && i == (nb_args - 1)) {
424 // If thiscall, zap the last push, as it is `this`. Instead, mov into ecx
425 size = 0;
426 load(get_reg(RC_ECX), vtop);
427 }
428 else
429 if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {421 if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
430 size = type_size(&vtop->type, &align);422 size = type_size(&vtop->type, &align);
431 /* align to stack align size */423 /* align to stack align size */
@@ -486,12 +478,15 @@ ST_FUNC void gfunc_call(int nb_args) · 54 unmodified lines
486 func_call = func_sym->f.func_call;478 func_call = func_sym->f.func_call;
487 /* fast call case */479 /* fast call case */
488 if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) ||480 if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) ||
489 func_call == FUNC_FASTCALLW) {481 func_call == FUNC_FASTCALLW || func_call == FUNC_THISCALL) {
490 int fastcall_nb_regs;482 int fastcall_nb_regs;
491 const uint8_t *fastcall_regs_ptr;483 const uint8_t *fastcall_regs_ptr;
492 if (func_call == FUNC_FASTCALLW) {484 if (func_call == FUNC_FASTCALLW) {
493 fastcall_regs_ptr = fastcallw_regs;485 fastcall_regs_ptr = fastcallw_regs;
494 fastcall_nb_regs = 2;486 fastcall_nb_regs = 2;
487 } else if (func_call == FUNC_THISCALL) {
488 fastcall_regs_ptr = fastcallw_regs;
489 fastcall_nb_regs = 1;
495 } else {490 } else {
496 fastcall_regs_ptr = fastcall_regs;491 fastcall_regs_ptr = fastcall_regs;
497 fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;492 fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
@@ -531,7 +526,6 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 33 unmodified lines
531 const uint8_t *fastcall_regs_ptr;526 const uint8_t *fastcall_regs_ptr;
532 Sym *sym;527 Sym *sym;
533 CType *type;528 CType *type;
534 int thiscall_nb_regs;
535 529
536 sym = func_type->ref;530 sym = func_type->ref;
537 func_call = sym->f.func_call;531 func_call = sym->f.func_call;
@@ -545,15 +539,13 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 7 unmodified lines
545 } else if (func_call == FUNC_FASTCALLW) {539 } else if (func_call == FUNC_FASTCALLW) {
546 fastcall_nb_regs = 2;540 fastcall_nb_regs = 2;
547 fastcall_regs_ptr = fastcallw_regs;541 fastcall_regs_ptr = fastcallw_regs;
542 } else if (func_call == FUNC_THISCALL) {
543 fastcall_nb_regs = 1;
544 fastcall_regs_ptr = fastcallw_regs;
548 } else {545 } else {
549 fastcall_nb_regs = 0;546 fastcall_nb_regs = 0;
550 fastcall_regs_ptr = NULL;547 fastcall_regs_ptr = NULL;
551 }548 }
552
553 if (func_call == FUNC_THISCALL) {
554 thiscall_nb_regs = 1;
555 }
556
557 param_index = 0;549 param_index = 0;
558 550
559 ind += FUNC_PROLOG_SIZE;551 ind += FUNC_PROLOG_SIZE;
@@ -589,14 +581,6 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 29 unmodified lines
589 o(0x89); /* movl */581 o(0x89); /* movl */
590 gen_modrm(fastcall_regs_ptr[param_index], VT_LOCAL, NULL, loc);582 gen_modrm(fastcall_regs_ptr[param_index], VT_LOCAL, NULL, loc);
591 param_addr = loc;583 param_addr = loc;
592 }
593 else if(param_index < thiscall_nb_regs) {
594 /* Why ? */
595 /* save THISCALL register; ECX */
596 loc -= 4;
597 o(0x89); /* movl */
598 gen_modrm(TREG_ECX, VT_LOCAL, NULL, loc);
599 param_addr = loc;
600 } else {584 } else {
601 param_addr = addr;585 param_addr = addr;
602 addr += size;586 addr += size;
i386-link.c+3−3
@@ -25,7 +25,7 @@ · 24 unmodified lines
25#ifdef NEED_RELOC_TYPE25#ifdef NEED_RELOC_TYPE
26/* Returns 1 for a code relocation, 0 for a data relocation. For unknown26/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
27 relocations, returns -1. */27 relocations, returns -1. */
28int code_reloc (int reloc_type)28ST_FUNC int code_reloc (int reloc_type)
29{29{
30 switch (reloc_type) {30 switch (reloc_type) {
31 case R_386_RELATIVE:31 case R_386_RELATIVE:
@@ -55,7 +55,7 @@ int code_reloc (int reloc_type) · 23 unmodified lines
55/* Returns an enumerator to describe whether and when the relocation needs a55/* Returns an enumerator to describe whether and when the relocation needs a
56 GOT and/or PLT entry to be created. See tcc.h for a description of the56 GOT and/or PLT entry to be created. See tcc.h for a description of the
57 different values. */57 different values. */
58int gotplt_entry_type (int reloc_type)58ST_FUNC int gotplt_entry_type (int reloc_type)
59{59{
60 switch (reloc_type) {60 switch (reloc_type) {
61 case R_386_RELATIVE:61 case R_386_RELATIVE:
@@ -171,7 +171,7 @@ ST_FUNC void relocate_plt(TCCState *s1) · 109 unmodified lines
171#endif171#endif
172#endif172#endif
173 173
174void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)174ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
175{175{
176 int sym_index, esym_index;176 int sym_index, esym_index;
177 177
libtcc.c+27−17
@@ -201,7 +201,8 @@ ST_FUNC char *tcc_load_text(int fd) · 200 unmodified lines
201{201{
202 int len = lseek(fd, 0, SEEK_END);202 int len = lseek(fd, 0, SEEK_END);
203 char *buf = load_data(fd, 0, len + 1);203 char *buf = load_data(fd, 0, len + 1);
204 buf[len] = 0;204 if (buf)
205 buf[len] = 0;
205 return buf;206 return buf;
206}207}
207 208
@@ -336,7 +337,8 @@ PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line) · 128 unmodified lines
336{337{
337 int ofs;338 int ofs;
338 mem_debug_header_t *header;339 mem_debug_header_t *header;
339 340 if (!size)
341 return NULL;
340 header = tcc_malloc(sizeof(mem_debug_header_t) + size);342 header = tcc_malloc(sizeof(mem_debug_header_t) + size);
341 header->magic1 = MEM_DEBUG_MAGIC1;343 header->magic1 = MEM_DEBUG_MAGIC1;
342 header->magic2 = MEM_DEBUG_MAGIC2;344 header->magic2 = MEM_DEBUG_MAGIC2;
@@ -346,7 +348,6 @@ PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line) · 3 unmodified lines
346 ofs = strlen(file) - MEM_DEBUG_FILE_LEN;348 ofs = strlen(file) - MEM_DEBUG_FILE_LEN;
347 strncpy(header->file_name, file + (ofs > 0 ? ofs : 0), MEM_DEBUG_FILE_LEN);349 strncpy(header->file_name, file + (ofs > 0 ? ofs : 0), MEM_DEBUG_FILE_LEN);
348 header->file_name[MEM_DEBUG_FILE_LEN] = 0;350 header->file_name[MEM_DEBUG_FILE_LEN] = 0;
349
350 WAIT_SEM(&mem_sem);351 WAIT_SEM(&mem_sem);
351 header->next = mem_debug_chain;352 header->next = mem_debug_chain;
352 header->prev = NULL;353 header->prev = NULL;
@@ -357,7 +358,6 @@ PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line) · 4 unmodified lines
357 if (mem_cur_size > mem_max_size)358 if (mem_cur_size > mem_max_size)
358 mem_max_size = mem_cur_size;359 mem_max_size = mem_cur_size;
359 POST_SEM(&mem_sem);360 POST_SEM(&mem_sem);
360
361 return MEM_USER_PTR(header);361 return MEM_USER_PTR(header);
362}362}
363 363
@@ -367,7 +367,6 @@ PUB_FUNC void tcc_free_debug(void *ptr) · 3 unmodified lines
367 if (!ptr)367 if (!ptr)
368 return;368 return;
369 header = malloc_check(ptr, "tcc_free");369 header = malloc_check(ptr, "tcc_free");
370
371 WAIT_SEM(&mem_sem);370 WAIT_SEM(&mem_sem);
372 mem_cur_size -= header->size;371 mem_cur_size -= header->size;
373 header->size = (unsigned)-1;372 header->size = (unsigned)-1;
@@ -385,7 +384,8 @@ PUB_FUNC void *tcc_mallocz_debug(unsigned long size, const char *file, int line) · 11 unmodified lines
385{384{
386 void *ptr;385 void *ptr;
387 ptr = tcc_malloc_debug(size,file,line);386 ptr = tcc_malloc_debug(size,file,line);
388 memset(ptr, 0, size);387 if (size)
388 memset(ptr, 0, size);
389 return ptr;389 return ptr;
390}390}
391 391
@@ -393,10 +393,14 @@ PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file · 1 unmodified line
393{393{
394 mem_debug_header_t *header;394 mem_debug_header_t *header;
395 int mem_debug_chain_update = 0;395 int mem_debug_chain_update = 0;
396
396 if (!ptr)397 if (!ptr)
397 return tcc_malloc_debug(size, file, line);398 return tcc_malloc_debug(size, file, line);
399 if (!size) {
400 tcc_free_debug(ptr);
401 return NULL;
402 }
398 header = malloc_check(ptr, "tcc_realloc");403 header = malloc_check(ptr, "tcc_realloc");
399
400 WAIT_SEM(&mem_sem);404 WAIT_SEM(&mem_sem);
401 mem_cur_size -= header->size;405 mem_cur_size -= header->size;
402 mem_debug_chain_update = (header == mem_debug_chain);406 mem_debug_chain_update = (header == mem_debug_chain);
@@ -413,7 +417,6 @@ PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file · 10 unmodified lines
413 if (mem_cur_size > mem_max_size)417 if (mem_cur_size > mem_max_size)
414 mem_max_size = mem_cur_size;418 mem_max_size = mem_cur_size;
415 POST_SEM(&mem_sem);419 POST_SEM(&mem_sem);
416
417 return MEM_USER_PTR(header);420 return MEM_USER_PTR(header);
418}421}
419 422
@@ -441,6 +444,7 @@ PUB_FUNC void tcc_memcheck(int d) · 21 unmodified lines
441 }444 }
442 fflush(stderr);445 fflush(stderr);
443 mem_cur_size = 0;446 mem_cur_size = 0;
447 mem_max_size = 0;
444 mem_debug_chain = NULL;448 mem_debug_chain = NULL;
445#if MEM_DEBUG-0 == 2449#if MEM_DEBUG-0 == 2
446 exit(2);450 exit(2);
@@ -1425,24 +1429,24 @@ static int tcc_set_linker(TCCState *s, const char *option) · 978 unmodified lines
1425 s->pe_stack_size = strtoul(p, &end, 10);1429 s->pe_stack_size = strtoul(p, &end, 10);
1426 } else if (link_option(option, "subsystem=", &p)) {1430 } else if (link_option(option, "subsystem=", &p)) {
1427#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)1431#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1428 if (!strcmp(p, "native")) {1432 if (strstart("native", &p)) {
1429 s->pe_subsystem = 1;1433 s->pe_subsystem = 1;
1430 } else if (!strcmp(p, "console")) {1434 } else if (strstart("console", &p)) {
1431 s->pe_subsystem = 3;1435 s->pe_subsystem = 3;
1432 } else if (!strcmp(p, "gui") || !strcmp(p, "windows")) {1436 } else if (strstart("gui", &p) || strstart("windows", &p)) {
1433 s->pe_subsystem = 2;1437 s->pe_subsystem = 2;
1434 } else if (!strcmp(p, "posix")) {1438 } else if (strstart("posix", &p)) {
1435 s->pe_subsystem = 7;1439 s->pe_subsystem = 7;
1436 } else if (!strcmp(p, "efiapp")) {1440 } else if (strstart("efiapp", &p)) {
1437 s->pe_subsystem = 10;1441 s->pe_subsystem = 10;
1438 } else if (!strcmp(p, "efiboot")) {1442 } else if (strstart("efiboot", &p)) {
1439 s->pe_subsystem = 11;1443 s->pe_subsystem = 11;
1440 } else if (!strcmp(p, "efiruntime")) {1444 } else if (strstart("efiruntime", &p)) {
1441 s->pe_subsystem = 12;1445 s->pe_subsystem = 12;
1442 } else if (!strcmp(p, "efirom")) {1446 } else if (strstart("efirom", &p)) {
1443 s->pe_subsystem = 13;1447 s->pe_subsystem = 13;
1444#elif defined(TCC_TARGET_ARM)1448#elif defined(TCC_TARGET_ARM)
1445 if (!strcmp(p, "wince")) {1449 if (strstart("wince", &p)) {
1446 s->pe_subsystem = 9;1450 s->pe_subsystem = 9;
1447#endif1451#endif
1448 } else1452 } else
@@ -2211,3 +2215,9 @@ PUB_FUNC void tcc_print_stats(TCCState *s1, unsigned total_time) · 762 unmodified lines
2211 fprintf(stderr, " %d max (bytes)\n", mem_max_size);2215 fprintf(stderr, " %d max (bytes)\n", mem_max_size);
2212#endif2216#endif
2213}2217}
2218
2219#if ONE_SOURCE
2220# undef malloc
2221# undef realloc
2222# undef free
2223#endif
riscv64-asm.c+28−108
@@ -48,6 +48,10 @@ typedef struct Operand { · 47 unmodified lines
48 };48 };
49} Operand;49} Operand;
50 50
51static const Operand zero = { OP_REG, { 0 }};
52static const Operand ra = { OP_REG, { 1 }};
53static const Operand zimm = { OP_IM12S };
54
51static void asm_binary_opcode(TCCState* s1, int token);55static void asm_binary_opcode(TCCState* s1, int token);
52ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str);56ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str);
53ST_FUNC void asm_compute_constraints(ASMOperand *operands, int nb_operands, int nb_outputs, const uint8_t *clobber_regs, int *pout_reg);57ST_FUNC void asm_compute_constraints(ASMOperand *operands, int nb_operands, int nb_outputs, const uint8_t *clobber_regs, int *pout_reg);
@@ -128,9 +132,6 @@ static void asm_emit_opcode(uint32_t opcode) { · 74 unmodified lines
128 132
129static void asm_nullary_opcode(TCCState *s1, int token)133static void asm_nullary_opcode(TCCState *s1, int token)
130{134{
131 static const Operand nil = {.type = OP_REG};
132 static const Operand zimm = {.type = OP_IM12S};
133
134 switch (token) {135 switch (token) {
135 // Sync instructions136 // Sync instructions
136 137
@@ -150,7 +151,7 @@ static void asm_nullary_opcode(TCCState *s1, int token) · 13 unmodified lines
150 // Other151 // Other
151 152
152 case TOK_ASM_nop:153 case TOK_ASM_nop:
153 asm_emit_i(token, (4 << 2) | 3, &nil, &nil, &zimm);154 asm_emit_i(token, (4 << 2) | 3, &zero, &zero, &zimm);
154 return;155 return;
155 156
156 case TOK_ASM_wfi:157 case TOK_ASM_wfi:
@@ -165,10 +166,10 @@ static void asm_nullary_opcode(TCCState *s1, int token) · 8 unmodified lines
165 166
166 /* C extension */167 /* C extension */
167 case TOK_ASM_c_ebreak:168 case TOK_ASM_c_ebreak:
168 asm_emit_cr(token, 2 | (9 << 12), &nil, &nil);169 asm_emit_cr(token, 2 | (9 << 12), &zero, &zero);
169 return;170 return;
170 case TOK_ASM_c_nop:171 case TOK_ASM_c_nop:
171 asm_emit_ci(token, 1, &nil, &zimm);172 asm_emit_ci(token, 1, &zero, &zimm);
172 return;173 return;
173 174
174 default:175 default:
@@ -266,33 +267,24 @@ static void parse_jump_offset_operand(TCCState *s1, Operand *op){ · 91 unmodified lines
266static void parse_operands(TCCState *s1, Operand* ops, int count){267static void parse_operands(TCCState *s1, Operand* ops, int count){
267 int i;268 int i;
268 for (i = 0; i < count; i++) {269 for (i = 0; i < count; i++) {
269 if ( i != 0 ) {270 if ( i != 0 )
270 if ( tok == ',')271 skip(',');
271 next();
272 else
273 expect("','");
274 }
275 parse_operand(s1, &ops[i]);272 parse_operand(s1, &ops[i]);
276 }273 }
277}274}
278 275
279/* parse `X, imm(Y)` to {X, Y, imm} operands */276/* parse `X, imm(Y)` to {X, Y, imm} operands */
280static void parse_mem_access_operands(TCCState *s1, Operand* ops){277static void parse_mem_access_operands(TCCState *s1, Operand* ops){
281 static const Operand zimm = {.type = OP_IM12S};
282 278
283 Operand op;279 Operand op;
284 280
285 parse_operand(s1, &ops[0]);281 parse_operand(s1, &ops[0]);
286 if ( tok == ',')282 skip(',');
287 next();
288 else
289 expect("','");
290
291 if ( tok == '(') {283 if ( tok == '(') {
292 /* `X, (Y)` case*/284 /* `X, (Y)` case*/
293 next();285 next();
294 parse_operand(s1, &ops[1]);286 parse_operand(s1, &ops[1]);
295 if ( tok == ')') next(); else expect("')'");287 skip(')');
296 ops[2] = zimm;288 ops[2] = zimm;
297 } else {289 } else {
298 parse_operand(s1, &ops[2]);290 parse_operand(s1, &ops[2]);
@@ -300,7 +292,7 @@ static void parse_mem_access_operands(TCCState *s1, Operand* ops){ · 1 unmodified line
300 /* `X, imm(Y)` case*/292 /* `X, imm(Y)` case*/
301 next();293 next();
302 parse_operand(s1, &ops[1]);294 parse_operand(s1, &ops[1]);
303 if ( tok == ')') next(); else expect("')'");295 skip(')');
304 } else {296 } else {
305 /* `X, Y` case*/297 /* `X, Y` case*/
306 /* we parsed Y thinking it was imm, swap and default imm to zero */298 /* we parsed Y thinking it was imm, swap and default imm to zero */
@@ -314,8 +306,6 @@ static void parse_mem_access_operands(TCCState *s1, Operand* ops){ · 7 unmodified lines
314 306
315/* This is special: First operand is optional */307/* This is special: First operand is optional */
316static void asm_jal_opcode(TCCState *s1, int token){308static void asm_jal_opcode(TCCState *s1, int token){
317 static const Operand ra = {.type = OP_REG, .reg = 1};
318 static const Operand zero = {.type = OP_REG};
319 Operand ops[2];309 Operand ops[2];
320 310
321 if (token == TOK_ASM_j ){311 if (token == TOK_ASM_j ){
@@ -333,8 +323,6 @@ static void asm_jal_opcode(TCCState *s1, int token){ · 11 unmodified lines
333 323
334/* This is special: It can be a pseudointruction or a instruction */324/* This is special: It can be a pseudointruction or a instruction */
335static void asm_jalr_opcode(TCCState *s1, int token){325static void asm_jalr_opcode(TCCState *s1, int token){
336 static const Operand zimm = {.type = OP_IM12S};
337 static const Operand ra = {.type = OP_REG, .reg = 1};
338 Operand ops[3];326 Operand ops[3];
339 Operand op;327 Operand op;
340 328
@@ -355,7 +343,7 @@ static void asm_jalr_opcode(TCCState *s1, int token){ · 14 unmodified lines
355 /* `X, (Y)` case*/343 /* `X, (Y)` case*/
356 next();344 next();
357 parse_operand(s1, &ops[1]);345 parse_operand(s1, &ops[1]);
358 if ( tok == ')') next(); else expect("')'");346 skip(')');
359 ops[2] = zimm;347 ops[2] = zimm;
360 } else {348 } else {
361 parse_operand(s1, &ops[2]);349 parse_operand(s1, &ops[2]);
@@ -363,7 +351,7 @@ static void asm_jalr_opcode(TCCState *s1, int token){ · 1 unmodified line
363 /* `X, imm(Y)` case*/351 /* `X, imm(Y)` case*/
364 next();352 next();
365 parse_operand(s1, &ops[1]);353 parse_operand(s1, &ops[1]);
366 if ( tok == ')') next(); else expect("')'");354 skip(')');
367 } else {355 } else {
368 /* `X, Y` case*/356 /* `X, Y` case*/
369 /* we parsed Y thinking it was imm, swap and default imm to zero */357 /* we parsed Y thinking it was imm, swap and default imm to zero */
@@ -382,8 +370,6 @@ static void asm_unary_opcode(TCCState *s1, int token) · 12 unmodified lines
382{370{
383 uint32_t opcode = (0x1C << 2) | 3 | (2 << 12);371 uint32_t opcode = (0x1C << 2) | 3 | (2 << 12);
384 Operand op;372 Operand op;
385 static const Operand zero = {.type = OP_REG};
386 static const Operand zimm = {.type = OP_IM12S};
387 373
388 parse_operands(s1, &op, 1);374 parse_operands(s1, &op, 1);
389 /* Note: Those all map to CSR--so they are pseudo-instructions. */375 /* Note: Those all map to CSR--so they are pseudo-instructions. */
@@ -451,14 +437,11 @@ static void asm_emit_u(int token, uint32_t opcode, const Operand* rd, const Oper · 61 unmodified lines
451{437{
452 if (rd->type != OP_REG) {438 if (rd->type != OP_REG) {
453 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));439 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));
454 return;
455 }440 }
456 if (rs2->type != OP_IM12S && rs2->type != OP_IM32) {441 if (rs2->type != OP_IM12S && rs2->type != OP_IM32) {
457 tcc_error("'%s': Expected second source operand that is an immediate value", get_tok_str(token, NULL));442 tcc_error("'%s': Expected second source operand that is an immediate value", get_tok_str(token, NULL));
458 return;
459 } else if (rs2->e.v >= 0x100000) {443 } else if (rs2->e.v >= 0x100000) {
460 tcc_error("'%s': Expected second source operand that is an immediate value between 0 and 0xfffff", get_tok_str(token, NULL));444 tcc_error("'%s': Expected second source operand that is an immediate value between 0 and 0xfffff", get_tok_str(token, NULL));
461 return;
462 }445 }
463 /* U-type instruction:446 /* U-type instruction:
464 31...12 imm[31:12]447 31...12 imm[31:12]
@@ -486,7 +469,7 @@ static void asm_fence_opcode(TCCState *s1, int token){ · 21 unmodified lines
486 if ( pred > 0xF || pred < 0) {469 if ( pred > 0xF || pred < 0) {
487 tcc_error("'%s': Expected first operand that is a valid predecessor operand", get_tok_str(token, NULL));470 tcc_error("'%s': Expected first operand that is a valid predecessor operand", get_tok_str(token, NULL));
488 }471 }
489 if ( tok == ',') next(); else expect("','");472 skip(',');
490 succ = parse_fence_operand();473 succ = parse_fence_operand();
491 if ( succ > 0xF || succ < 0) {474 if ( succ > 0xF || succ < 0) {
492 tcc_error("'%s': Expected second operand that is a valid successor operand", get_tok_str(token, NULL));475 tcc_error("'%s': Expected second operand that is a valid successor operand", get_tok_str(token, NULL));
@@ -497,8 +480,7 @@ static void asm_fence_opcode(TCCState *s1, int token){ · 4 unmodified lines
497 480
498static void asm_binary_opcode(TCCState* s1, int token)481static void asm_binary_opcode(TCCState* s1, int token)
499{482{
500 static const Operand zero = {.type = OP_REG, .reg = 0};483 Operand imm = { OP_IM12S };
501 Operand imm = {.type = OP_IM12S, .e = {.v = 0}};
502 Operand ops[2];484 Operand ops[2];
503 int32_t lo;485 int32_t lo;
504 uint32_t hi;486 uint32_t hi;
@@ -710,15 +692,12 @@ static void asm_emit_r(int token, uint32_t opcode, const Operand* rd, const Oper · 205 unmodified lines
710{692{
711 if (rd->type != OP_REG) {693 if (rd->type != OP_REG) {
712 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));694 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));
713 return;
714 }695 }
715 if (rs1->type != OP_REG) {696 if (rs1->type != OP_REG) {
716 tcc_error("'%s': Expected first source operand that is a register", get_tok_str(token, NULL));697 tcc_error("'%s': Expected first source operand that is a register", get_tok_str(token, NULL));
717 return;
718 }698 }
719 if (rs2->type != OP_REG) {699 if (rs2->type != OP_REG) {
720 tcc_error("'%s': Expected second source operand that is a register or immediate", get_tok_str(token, NULL));700 tcc_error("'%s': Expected second source operand that is a register or immediate", get_tok_str(token, NULL));
721 return;
722 }701 }
723 /* R-type instruction:702 /* R-type instruction:
724 31...25 funct7703 31...25 funct7
@@ -735,15 +714,12 @@ static void asm_emit_i(int token, uint32_t opcode, const Operand* rd, const Oper · 10 unmodified lines
735{714{
736 if (rd->type != OP_REG) {715 if (rd->type != OP_REG) {
737 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));716 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));
738 return;
739 }717 }
740 if (rs1->type != OP_REG) {718 if (rs1->type != OP_REG) {
741 tcc_error("'%s': Expected first source operand that is a register", get_tok_str(token, NULL));719 tcc_error("'%s': Expected first source operand that is a register", get_tok_str(token, NULL));
742 return;
743 }720 }
744 if (rs2->type != OP_IM12S) {721 if (rs2->type != OP_IM12S) {
745 tcc_error("'%s': Expected second source operand that is an immediate value between 0 and 8191", get_tok_str(token, NULL));722 tcc_error("'%s': Expected second source operand that is an immediate value between 0 and 8191", get_tok_str(token, NULL));
746 return;
747 }723 }
748 /* I-type instruction:724 /* I-type instruction:
749 31...20 imm[11:0]725 31...20 imm[11:0]
@@ -761,11 +737,9 @@ static void asm_emit_j(int token, uint32_t opcode, const Operand* rd, const Oper · 11 unmodified lines
761 737
762 if (rd->type != OP_REG) {738 if (rd->type != OP_REG) {
763 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));739 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));
764 return;
765 }740 }
766 if (rs2->type != OP_IM12S && rs2->type != OP_IM32) {741 if (rs2->type != OP_IM12S && rs2->type != OP_IM32) {
767 tcc_error("'%s': Expected second source operand that is an immediate value", get_tok_str(token, NULL));742 tcc_error("'%s': Expected second source operand that is an immediate value", get_tok_str(token, NULL));
768 return;
769 }743 }
770 744
771 imm = rs2->e.v;745 imm = rs2->e.v;
@@ -773,12 +747,10 @@ static void asm_emit_j(int token, uint32_t opcode, const Operand* rd, const Oper · 1 unmodified line
773 /* even offsets in a +- 1 MiB range */747 /* even offsets in a +- 1 MiB range */
774 if ((int)imm > (1 << 20) -1 || (int)imm <= -1 * ((1 << 20) -1)) {748 if ((int)imm > (1 << 20) -1 || (int)imm <= -1 * ((1 << 20) -1)) {
775 tcc_error("'%s': Expected second source operand that is an immediate value between 0 and 0x1fffff", get_tok_str(token, NULL));749 tcc_error("'%s': Expected second source operand that is an immediate value between 0 and 0x1fffff", get_tok_str(token, NULL));
776 return;
777 }750 }
778 751
779 if (imm & 1) {752 if (imm & 1) {
780 tcc_error("'%s': Expected second source operand that is an even immediate value", get_tok_str(token, NULL));753 tcc_error("'%s': Expected second source operand that is an even immediate value", get_tok_str(token, NULL));
781 return;
782 }754 }
783 /* J-type instruction:755 /* J-type instruction:
784 31 imm[20]756 31 imm[20]
@@ -851,11 +823,11 @@ static void asm_mem_access_opcode(TCCState *s1, int token) · 66 unmodified lines
851 }823 }
852}824}
853 825
854static void asm_branch_opcode(TCCState *s1, int token, int argc){826static void asm_branch_opcode(TCCState *s1, int token, int argc)
827{
855 Operand ops[3];828 Operand ops[3];
856 Operand zero = {.type = OP_REG};
857 parse_operands(s1, &ops[0], argc-1);829 parse_operands(s1, &ops[0], argc-1);
858 if ( tok == ',') next(); else { expect(","); }830 skip(',');
859 parse_branch_offset_operand(s1, &ops[argc-1]);831 parse_branch_offset_operand(s1, &ops[argc-1]);
860 832
861 switch(token){833 switch(token){
@@ -1118,22 +1090,21 @@ static void asm_ternary_opcode(TCCState *s1, int token) · 256 unmodified lines
1118 1090
1119static void asm_atomic_opcode(TCCState *s1, int token)1091static void asm_atomic_opcode(TCCState *s1, int token)
1120{1092{
1121 static const Operand zero = {.type = OP_REG};
1122 Operand ops[3];1093 Operand ops[3];
1123 1094
1124 parse_operand(s1, &ops[0]);1095 parse_operand(s1, &ops[0]);
1125 if ( tok == ',') next(); else expect("','");1096 skip(',');
1126 1097
1127 if ( token <= TOK_ASM_lr_d_aqrl && token >= TOK_ASM_lr_w ) {1098 if ( token <= TOK_ASM_lr_d_aqrl && token >= TOK_ASM_lr_w ) {
1128 ops[1] = zero;1099 ops[1] = zero;
1129 } else {1100 } else {
1130 parse_operand(s1, &ops[1]);1101 parse_operand(s1, &ops[1]);
1131 if ( tok == ',') next(); else expect("','");1102 skip(',');
1132 }1103 }
1133 1104
1134 if ( tok == '(') next(); else expect("'('");1105 skip('(');
1135 parse_operand(s1, &ops[2]);1106 parse_operand(s1, &ops[2]);
1136 if ( tok == ')') next(); else expect("')'");1107 skip(')');
1137 1108
1138 switch(token){1109 switch(token){
1139 case TOK_ASM_lr_w:1110 case TOK_ASM_lr_w:
@@ -1217,15 +1188,12 @@ static void asm_emit_s(int token, uint32_t opcode, const Operand* rs1, const Ope · 77 unmodified lines
1217{1188{
1218 if (rs1->type != OP_REG) {1189 if (rs1->type != OP_REG) {
1219 tcc_error("'%s': Expected first source operand that is a register", get_tok_str(token, NULL));1190 tcc_error("'%s': Expected first source operand that is a register", get_tok_str(token, NULL));
1220 return;
1221 }1191 }
1222 if (rs2->type != OP_REG) {1192 if (rs2->type != OP_REG) {
1223 tcc_error("'%s': Expected second source operand that is a register", get_tok_str(token, NULL));1193 tcc_error("'%s': Expected second source operand that is a register", get_tok_str(token, NULL));
1224 return;
1225 }1194 }
1226 if (imm->type != OP_IM12S) {1195 if (imm->type != OP_IM12S) {
1227 tcc_error("'%s': Expected third operand that is an immediate value between 0 and 8191", get_tok_str(token, NULL));1196 tcc_error("'%s': Expected third operand that is an immediate value between 0 and 8191", get_tok_str(token, NULL));
1228 return;
1229 }1197 }
1230 {1198 {
1231 uint16_t v = imm->e.v;1199 uint16_t v = imm->e.v;
@@ -1247,15 +1215,12 @@ static void asm_emit_b(int token, uint32_t opcode, const Operand *rs1, const Ope · 15 unmodified lines
1247 1215
1248 if (rs1->type != OP_REG) {1216 if (rs1->type != OP_REG) {
1249 tcc_error("'%s': Expected first source operand that is a register", get_tok_str(token, NULL));1217 tcc_error("'%s': Expected first source operand that is a register", get_tok_str(token, NULL));
1250 return;
1251 }1218 }
1252 if (rs2->type != OP_REG) {1219 if (rs2->type != OP_REG) {
1253 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));1220 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));
1254 return;
1255 }1221 }
1256 if (imm->type != OP_IM12S) {1222 if (imm->type != OP_IM12S) {
1257 tcc_error("'%s': Expected second source operand that is an immediate value between 0 and 8191", get_tok_str(token, NULL));1223 tcc_error("'%s': Expected second source operand that is an immediate value between 0 and 8191", get_tok_str(token, NULL));
1258 return;
1259 }1224 }
1260 1225
1261 offset = imm->e.v;1226 offset = imm->e.v;
@@ -1541,7 +1506,6 @@ static int asm_parse_csrvar(int t) · 279 unmodified lines
1541ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier)1506ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier)
1542{1507{
1543 int r, reg, val;1508 int r, reg, val;
1544 char buf[64];
1545 1509
1546 r = sv->r;1510 r = sv->r;
1547 if ((r & VT_VALMASK) == VT_CONST) {1511 if ((r & VT_VALMASK) == VT_CONST) {
@@ -1572,13 +1536,11 @@ ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier) · 24 unmodified lines
1572 if (modifier == 'z' && sv->c.i == 0) {1536 if (modifier == 'z' && sv->c.i == 0) {
1573 cstr_cat(add_str, "zero", -1);1537 cstr_cat(add_str, "zero", -1);
1574 } else {1538 } else {
1575 snprintf(buf, sizeof(buf), "%d", (int) sv->c.i);1539 cstr_printf(add_str, "%d", (int) sv->c.i);
1576 cstr_cat(add_str, buf, -1);
1577 }1540 }
1578 no_offset:;1541 no_offset:;
1579 } else if ((r & VT_VALMASK) == VT_LOCAL) {1542 } else if ((r & VT_VALMASK) == VT_LOCAL) {
1580 snprintf(buf, sizeof(buf), "%d", (int) sv->c.i);1543 cstr_printf(add_str, "%d", (int) sv->c.i);
1581 cstr_cat(add_str, buf, -1);
1582 } else if (r & VT_LVAL) {1544 } else if (r & VT_LVAL) {
1583 reg = r & VT_VALMASK;1545 reg = r & VT_VALMASK;
1584 if (reg >= VT_CONST)1546 if (reg >= VT_CONST)
@@ -1591,8 +1553,7 @@ ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier) · 6 unmodified lines
1591 /* general purpose register */1553 /* general purpose register */
1592 reg = TOK_ASM_x0 + reg;1554 reg = TOK_ASM_x0 + reg;
1593 }1555 }
1594 snprintf(buf, sizeof(buf), "%s", get_tok_str(reg, NULL));1556 cstr_cat(add_str, get_tok_str(reg, NULL), -1);
1595 cstr_cat(add_str, buf, -1);
1596 } else {1557 } else {
1597 /* register case */1558 /* register case */
1598 reg = r & VT_VALMASK;1559 reg = r & VT_VALMASK;
@@ -1606,8 +1567,7 @@ ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier) · 7 unmodified lines
1606 /* general purpose register */1567 /* general purpose register */
1607 reg = TOK_ASM_x0 + reg;1568 reg = TOK_ASM_x0 + reg;
1608 }1569 }
1609 snprintf(buf, sizeof(buf), "%s", get_tok_str(reg, NULL));1570 cstr_cat(add_str, get_tok_str(reg, NULL), -1);
1610 cstr_cat(add_str, buf, -1);
1611 }1571 }
1612}1572}
1613 1573
@@ -1775,12 +1735,9 @@ static inline int constraint_priority(const char *str) · 161 unmodified lines
1775 pr = 4;1735 pr = 4;
1776 break;1736 break;
1777 case 'v':1737 case 'v':
1778 tcc_error("unimp: vector constraints '%d'", c);1738 tcc_error("unimp: constraint '%c'", c);
1779 pr = 0;
1780 break;
1781 default:1739 default:
1782 tcc_error("unknown constraint '%d'", c);1740 tcc_error("unknown constraint '%d'", c);
1783 pr = 0;
1784 }1741 }
1785 if (pr > priority)1742 if (pr > priority)
1786 priority = pr;1743 priority = pr;
@@ -2093,12 +2050,10 @@ static void asm_emit_ca(int token, uint16_t opcode, const Operand *rd, const Ope · 306 unmodified lines
2093 2050
2094 if (rd->type != OP_REG) {2051 if (rd->type != OP_REG) {
2095 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));2052 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));
2096 return;
2097 }2053 }
2098 2054
2099 if (rs2->type != OP_REG) {2055 if (rs2->type != OP_REG) {
2100 tcc_error("'%s': Expected source operand that is a register", get_tok_str(token, NULL));2056 tcc_error("'%s': Expected source operand that is a register", get_tok_str(token, NULL));
2101 return;
2102 }2057 }
2103 2058
2104 /* subtract index of x8 */2059 /* subtract index of x8 */
@@ -2108,12 +2063,10 @@ static void asm_emit_ca(int token, uint16_t opcode, const Operand *rd, const Ope · 3 unmodified lines
2108 /* only registers {x,f}8 to {x,f}15 are valid (3-bit) */2063 /* only registers {x,f}8 to {x,f}15 are valid (3-bit) */
2109 if (dst > 7) {2064 if (dst > 7) {
2110 tcc_error("'%s': Expected destination operand that is a valid C-extension register", get_tok_str(token, NULL));2065 tcc_error("'%s': Expected destination operand that is a valid C-extension register", get_tok_str(token, NULL));
2111 return;
2112 }2066 }
2113 2067
2114 if (src > 7) {2068 if (src > 7) {
2115 tcc_error("'%s': Expected source operand that is a valid C-extension register", get_tok_str(token, NULL));2069 tcc_error("'%s': Expected source operand that is a valid C-extension register", get_tok_str(token, NULL));
2116 return;
2117 }2070 }
2118 2071
2119 /* CA-type instruction:2072 /* CA-type instruction:
@@ -2133,26 +2086,22 @@ static void asm_emit_cb(int token, uint16_t opcode, const Operand *rs1, const Op · 13 unmodified lines
2133 2086
2134 if (rs1->type != OP_REG) {2087 if (rs1->type != OP_REG) {
2135 tcc_error("'%s': Expected source operand that is a register", get_tok_str(token, NULL));2088 tcc_error("'%s': Expected source operand that is a register", get_tok_str(token, NULL));
2136 return;
2137 }2089 }
2138 2090
2139 if (imm->type != OP_IM12S && imm->type != OP_IM32) {2091 if (imm->type != OP_IM12S && imm->type != OP_IM32) {
2140 tcc_error("'%s': Expected source operand that is an immediate value", get_tok_str(token, NULL));2092 tcc_error("'%s': Expected source operand that is an immediate value", get_tok_str(token, NULL));
2141 return;
2142 }2093 }
2143 2094
2144 offset = imm->e.v;2095 offset = imm->e.v;
2145 2096
2146 if (offset & 1) {2097 if (offset & 1) {
2147 tcc_error("'%s': Expected source operand that is an even immediate value", get_tok_str(token, NULL));2098 tcc_error("'%s': Expected source operand that is an even immediate value", get_tok_str(token, NULL));
2148 return;
2149 }2099 }
2150 2100
2151 src = rs1->reg - 8;2101 src = rs1->reg - 8;
2152 2102
2153 if (src > 7) {2103 if (src > 7) {
2154 tcc_error("'%s': Expected source operand that is a valid C-extension register", get_tok_str(token, NULL));2104 tcc_error("'%s': Expected source operand that is a valid C-extension register", get_tok_str(token, NULL));
2155 return;
2156 }2105 }
2157 2106
2158 /* CB-type instruction:2107 /* CB-type instruction:
@@ -2187,12 +2136,10 @@ static void asm_emit_ci(int token, uint16_t opcode, const Operand *rd, const Ope · 28 unmodified lines
2187 2136
2188 if (rd->type != OP_REG) {2137 if (rd->type != OP_REG) {
2189 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));2138 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));
2190 return;
2191 }2139 }
2192 2140
2193 if (imm->type != OP_IM12S && imm->type != OP_IM32) {2141 if (imm->type != OP_IM12S && imm->type != OP_IM32) {
2194 tcc_error("'%s': Expected source operand that is an immediate value", get_tok_str(token, NULL));2142 tcc_error("'%s': Expected source operand that is an immediate value", get_tok_str(token, NULL));
2195 return;
2196 }2143 }
2197 2144
2198 immediate = imm->e.v;2145 immediate = imm->e.v;
@@ -2241,31 +2188,26 @@ static void asm_emit_ciw(int token, uint16_t opcode, const Operand *rd, const Op · 42 unmodified lines
2241 2188
2242 if (rd->type != OP_REG) {2189 if (rd->type != OP_REG) {
2243 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));2190 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));
2244 return;
2245 }2191 }
2246 2192
2247 if (imm->type != OP_IM12S && imm->type != OP_IM32) {2193 if (imm->type != OP_IM12S && imm->type != OP_IM32) {
2248 tcc_error("'%s': Expected source operand that is an immediate value", get_tok_str(token, NULL));2194 tcc_error("'%s': Expected source operand that is an immediate value", get_tok_str(token, NULL));
2249 return;
2250 }2195 }
2251 2196
2252 dst = rd->reg - 8;2197 dst = rd->reg - 8;
2253 2198
2254 if (dst > 7) {2199 if (dst > 7) {
2255 tcc_error("'%s': Expected destination operand that is a valid C-extension register", get_tok_str(token, NULL));2200 tcc_error("'%s': Expected destination operand that is a valid C-extension register", get_tok_str(token, NULL));
2256 return;
2257 }2201 }
2258 2202
2259 nzuimm = imm->e.v;2203 nzuimm = imm->e.v;
2260 2204
2261 if (nzuimm > 0x3fc) {2205 if (nzuimm > 0x3fc) {
2262 tcc_error("'%s': Expected source operand that is an immediate value between 0 and 0x3ff", get_tok_str(token, NULL));2206 tcc_error("'%s': Expected source operand that is an immediate value between 0 and 0x3ff", get_tok_str(token, NULL));
2263 return;
2264 }2207 }
2265 2208
2266 if (nzuimm & 3) {2209 if (nzuimm & 3) {
2267 tcc_error("'%s': Expected source operand that is a non-zero immediate value divisible by 4", get_tok_str(token, NULL));2210 tcc_error("'%s': Expected source operand that is a non-zero immediate value divisible by 4", get_tok_str(token, NULL));
2268 return;
2269 }2211 }
2270 2212
2271 /* CIW-type instruction:2213 /* CIW-type instruction:
@@ -2285,14 +2227,12 @@ static void asm_emit_cj(int token, uint16_t opcode, const Operand *imm) · 13 unmodified lines
2285 /* +-2 KiB range */2227 /* +-2 KiB range */
2286 if (imm->type != OP_IM12S) {2228 if (imm->type != OP_IM12S) {
2287 tcc_error("'%s': Expected source operand that is a 12-bit immediate value", get_tok_str(token, NULL));2229 tcc_error("'%s': Expected source operand that is a 12-bit immediate value", get_tok_str(token, NULL));
2288 return;
2289 }2230 }
2290 2231
2291 offset = imm->e.v;2232 offset = imm->e.v;
2292 2233
2293 if (offset & 1) {2234 if (offset & 1) {
2294 tcc_error("'%s': Expected source operand that is an even immediate value", get_tok_str(token, NULL));2235 tcc_error("'%s': Expected source operand that is an even immediate value", get_tok_str(token, NULL));
2295 return;
2296 }2236 }
2297 2237
2298 /* CJ-type instruction:2238 /* CJ-type instruction:
@@ -2311,17 +2251,14 @@ static void asm_emit_cl(int token, uint16_t opcode, const Operand *rd, const Ope · 12 unmodified lines
2311 2251
2312 if (rd->type != OP_REG) {2252 if (rd->type != OP_REG) {
2313 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));2253 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));
2314 return;
2315 }2254 }
2316 2255
2317 if (rs1->type != OP_REG) {2256 if (rs1->type != OP_REG) {
2318 tcc_error("'%s': Expected source operand that is a register", get_tok_str(token, NULL));2257 tcc_error("'%s': Expected source operand that is a register", get_tok_str(token, NULL));
2319 return;
2320 }2258 }
2321 2259
2322 if (imm->type != OP_IM12S && imm->type != OP_IM32) {2260 if (imm->type != OP_IM12S && imm->type != OP_IM32) {
2323 tcc_error("'%s': Expected source operand that is an immediate value", get_tok_str(token, NULL));2261 tcc_error("'%s': Expected source operand that is an immediate value", get_tok_str(token, NULL));
2324 return;
2325 }2262 }
2326 2263
2327 dst = rd->reg - 8;2264 dst = rd->reg - 8;
@@ -2329,24 +2266,20 @@ static void asm_emit_cl(int token, uint16_t opcode, const Operand *rd, const Ope · 1 unmodified line
2329 2266
2330 if (dst > 7) {2267 if (dst > 7) {
2331 tcc_error("'%s': Expected destination operand that is a valid C-extension register", get_tok_str(token, NULL));2268 tcc_error("'%s': Expected destination operand that is a valid C-extension register", get_tok_str(token, NULL));
2332 return;
2333 }2269 }
2334 2270
2335 if (src > 7) {2271 if (src > 7) {
2336 tcc_error("'%s': Expected source operand that is a valid C-extension register", get_tok_str(token, NULL));2272 tcc_error("'%s': Expected source operand that is a valid C-extension register", get_tok_str(token, NULL));
2337 return;
2338 }2273 }
2339 2274
2340 offset = imm->e.v;2275 offset = imm->e.v;
2341 2276
2342 if (offset > 0xff) {2277 if (offset > 0xff) {
2343 tcc_error("'%s': Expected source operand that is an immediate value between 0 and 0xff", get_tok_str(token, NULL));2278 tcc_error("'%s': Expected source operand that is an immediate value between 0 and 0xff", get_tok_str(token, NULL));
2344 return;
2345 }2279 }
2346 2280
2347 if (offset & 3) {2281 if (offset & 3) {
2348 tcc_error("'%s': Expected source operand that is an immediate value divisible by 4", get_tok_str(token, NULL));2282 tcc_error("'%s': Expected source operand that is an immediate value divisible by 4", get_tok_str(token, NULL));
2349 return;
2350 }2283 }
2351 2284
2352 /* CL-type instruction:2285 /* CL-type instruction:
@@ -2378,12 +2311,10 @@ static void asm_emit_cr(int token, uint16_t opcode, const Operand *rd, const Ope · 25 unmodified lines
2378{2311{
2379 if (rd->type != OP_REG) {2312 if (rd->type != OP_REG) {
2380 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));2313 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));
2381 return;
2382 }2314 }
2383 2315
2384 if (rs2->type != OP_REG) {2316 if (rs2->type != OP_REG) {
2385 tcc_error("'%s': Expected source operand that is a register", get_tok_str(token, NULL));2317 tcc_error("'%s': Expected source operand that is a register", get_tok_str(token, NULL));
2386 return;
2387 }2318 }
2388 2319
2389 /* CR-type instruction:2320 /* CR-type instruction:
@@ -2403,17 +2334,14 @@ static void asm_emit_cs(int token, uint16_t opcode, const Operand *rs2, const Op · 13 unmodified lines
2403 2334
2404 if (rs2->type != OP_REG) {2335 if (rs2->type != OP_REG) {
2405 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));2336 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));
2406 return;
2407 }2337 }
2408 2338
2409 if (rs1->type != OP_REG) {2339 if (rs1->type != OP_REG) {
2410 tcc_error("'%s': Expected source operand that is a register", get_tok_str(token, NULL));2340 tcc_error("'%s': Expected source operand that is a register", get_tok_str(token, NULL));
2411 return;
2412 }2341 }
2413 2342
2414 if (imm->type != OP_IM12S && imm->type != OP_IM32) {2343 if (imm->type != OP_IM12S && imm->type != OP_IM32) {
2415 tcc_error("'%s': Expected source operand that is an immediate value", get_tok_str(token, NULL));2344 tcc_error("'%s': Expected source operand that is an immediate value", get_tok_str(token, NULL));
2416 return;
2417 }2345 }
2418 2346
2419 base = rs1->reg - 8;2347 base = rs1->reg - 8;
@@ -2421,24 +2349,20 @@ static void asm_emit_cs(int token, uint16_t opcode, const Operand *rs2, const Op · 1 unmodified line
2421 2349
2422 if (base > 7) {2350 if (base > 7) {
2423 tcc_error("'%s': Expected destination operand that is a valid C-extension register", get_tok_str(token, NULL));2351 tcc_error("'%s': Expected destination operand that is a valid C-extension register", get_tok_str(token, NULL));
2424 return;
2425 }2352 }
2426 2353
2427 if (src > 7) {2354 if (src > 7) {
2428 tcc_error("'%s': Expected source operand that is a valid C-extension register", get_tok_str(token, NULL));2355 tcc_error("'%s': Expected source operand that is a valid C-extension register", get_tok_str(token, NULL));
2429 return;
2430 }2356 }
2431 2357
2432 offset = imm->e.v;2358 offset = imm->e.v;
2433 2359
2434 if (offset > 0xff) {2360 if (offset > 0xff) {
2435 tcc_error("'%s': Expected source operand that is an immediate value between 0 and 0xff", get_tok_str(token, NULL));2361 tcc_error("'%s': Expected source operand that is an immediate value between 0 and 0xff", get_tok_str(token, NULL));
2436 return;
2437 }2362 }
2438 2363
2439 if (offset & 3) {2364 if (offset & 3) {
2440 tcc_error("'%s': Expected source operand that is an immediate value divisible by 4", get_tok_str(token, NULL));2365 tcc_error("'%s': Expected source operand that is an immediate value divisible by 4", get_tok_str(token, NULL));
2441 return;
2442 }2366 }
2443 2367
2444 /* CS-type instruction:2368 /* CS-type instruction:
@@ -2471,24 +2395,20 @@ static void asm_emit_css(int token, uint16_t opcode, const Operand *rs2, const O · 26 unmodified lines
2471 2395
2472 if (rs2->type != OP_REG) {2396 if (rs2->type != OP_REG) {
2473 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));2397 tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));
2474 return;
2475 }2398 }
2476 2399
2477 if (imm->type != OP_IM12S && imm->type != OP_IM32) {2400 if (imm->type != OP_IM12S && imm->type != OP_IM32) {
2478 tcc_error("'%s': Expected source operand that is an immediate value", get_tok_str(token, NULL));2401 tcc_error("'%s': Expected source operand that is an immediate value", get_tok_str(token, NULL));
2479 return;
2480 }2402 }
2481 2403
2482 offset = imm->e.v;2404 offset = imm->e.v;
2483 2405
2484 if (offset > 0xff) {2406 if (offset > 0xff) {
2485 tcc_error("'%s': Expected source operand that is an immediate value between 0 and 0xff", get_tok_str(token, NULL));2407 tcc_error("'%s': Expected source operand that is an immediate value between 0 and 0xff", get_tok_str(token, NULL));
2486 return;
2487 }2408 }
2488 2409
2489 if (offset & 3) {2410 if (offset & 3) {
2490 tcc_error("'%s': Expected source operand that is an immediate value divisible by 4", get_tok_str(token, NULL));2411 tcc_error("'%s': Expected source operand that is an immediate value divisible by 4", get_tok_str(token, NULL));
2491 return;
2492 }2412 }
2493 2413
2494 /* CSS-type instruction:2414 /* CSS-type instruction:
riscv64-link.c+3−3
@@ -24,7 +24,7 @@ · 23 unmodified lines
24 24
25/* Returns 1 for a code relocation, 0 for a data relocation. For unknown25/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
26 relocations, returns -1. */26 relocations, returns -1. */
27int code_reloc (int reloc_type)27ST_FUNC int code_reloc (int reloc_type)
28{28{
29 switch (reloc_type) {29 switch (reloc_type) {
30 30
@@ -62,7 +62,7 @@ int code_reloc (int reloc_type) · 31 unmodified lines
62/* Returns an enumerator to describe whether and when the relocation needs a62/* Returns an enumerator to describe whether and when the relocation needs a
63 GOT and/or PLT entry to be created. See tcc.h for a description of the63 GOT and/or PLT entry to be created. See tcc.h for a description of the
64 different values. */64 different values. */
65int gotplt_entry_type (int reloc_type)65ST_FUNC int gotplt_entry_type (int reloc_type)
66{66{
67 switch (reloc_type) {67 switch (reloc_type) {
68 case R_RISCV_ALIGN:68 case R_RISCV_ALIGN:
@@ -169,7 +169,7 @@ ST_FUNC void relocate_plt(TCCState *s1) · 100 unmodified lines
169 }169 }
170}170}
171 171
172void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr,172ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr,
173 addr_t addr, addr_t val)173 addr_t addr, addr_t val)
174{174{
175 uint64_t off64;175 uint64_t off64;
tcc.h+4−5
@@ -89,7 +89,6 @@ extern long double strtold (const char *__nptr, char **__endptr); · 88 unmodified lines
89# ifndef va_copy89# ifndef va_copy
90# define va_copy(a,b) a = b90# define va_copy(a,b) a = b
91# endif91# endif
92# undef CONFIG_TCC_STATIC
93#endif92#endif
94 93
95#ifndef O_BINARY94#ifndef O_BINARY
@@ -487,7 +486,7 @@ typedef int nwchar_t; · 391 unmodified lines
487typedef struct CString {486typedef struct CString {
488 int size; /* size in bytes */487 int size; /* size in bytes */
489 int size_allocated;488 int size_allocated;
490 void *data; /* either 'char *' or 'nwchar_t *' */489 char *data; /* nwchar_t* in cases */
491} CString;490} CString;
492 491
493/* type definition */492/* type definition */
@@ -1157,7 +1156,7 @@ struct filespec { · 663 unmodified lines
1157#define TOK_TWODOTS 0xa2 /* C++ token ? */1156#define TOK_TWODOTS 0xa2 /* C++ token ? */
1158#define TOK_TWOSHARPS 0xa3 /* ## preprocessing token */1157#define TOK_TWOSHARPS 0xa3 /* ## preprocessing token */
1159#define TOK_PLCHLDR 0xa4 /* placeholder token as defined in C99 */1158#define TOK_PLCHLDR 0xa4 /* placeholder token as defined in C99 */
1160#define TOK_PPJOIN 0xa6 /* A '##' in the right position to mean pasting */1159#define TOK_PPJOIN (TOK_TWOSHARPS | SYM_FIELD) /* A '##' in a macro to mean pasting */
1161#define TOK_SOTYPE 0xa7 /* alias of '(' for parsing sizeof (type) */1160#define TOK_SOTYPE 0xa7 /* alias of '(' for parsing sizeof (type) */
1162 1161
1163/* assignment operators */1162/* assignment operators */
@@ -1253,8 +1252,8 @@ ST_FUNC void libc_free(void *ptr); · 89 unmodified lines
1253PUB_FUNC int _tcc_error_noabort(const char *fmt, ...) PRINTF_LIKE(1,2);1252PUB_FUNC int _tcc_error_noabort(const char *fmt, ...) PRINTF_LIKE(1,2);
1254PUB_FUNC NORETURN void _tcc_error(const char *fmt, ...) PRINTF_LIKE(1,2);1253PUB_FUNC NORETURN void _tcc_error(const char *fmt, ...) PRINTF_LIKE(1,2);
1255PUB_FUNC void _tcc_warning(const char *fmt, ...) PRINTF_LIKE(1,2);1254PUB_FUNC void _tcc_warning(const char *fmt, ...) PRINTF_LIKE(1,2);
1256#define tcc_internal_error(msg) tcc_error("internal compiler error\n"\1255#define tcc_internal_error(msg) \
1257 "%s:%d: in %s(): " msg, __FILE__,__LINE__,__FUNCTION__)1256 tcc_error("internal compiler error in %s:%d: %s", __FUNCTION__,__LINE__,msg)
1258 1257
1259/* other utilities */1258/* other utilities */
1260ST_FUNC void dynarray_add(void *ptab, int *nb_ptr, void *data);1259ST_FUNC void dynarray_add(void *ptab, int *nb_ptr, void *data);
tccelf.c+9−20
@@ -153,9 +153,12 @@ ST_FUNC void tccelf_begin_file(TCCState *s1) · 152 unmodified lines
153 s = s1->symtab, s->reloc = s->hash, s->hash = NULL;153 s = s1->symtab, s->reloc = s->hash, s->hash = NULL;
154#if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE154#if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
155 s1->uw_sym = 0;155 s1->uw_sym = 0;
156 s1->uw_offs = 0;
156#endif157#endif
157}158}
158 159
160static void update_relocs(TCCState *s1, Section *s, int *old_to_new_syms, int first_sym);
161
159/* At the end of compilation, convert any UNDEF syms to global, and merge162/* At the end of compilation, convert any UNDEF syms to global, and merge
160 with previously existing symbols */163 with previously existing symbols */
161ST_FUNC void tccelf_end_file(TCCState *s1)164ST_FUNC void tccelf_end_file(TCCState *s1)
@@ -172,7 +175,6 @@ ST_FUNC void tccelf_end_file(TCCState *s1) · 10 unmodified lines
172 175
173 for (i = 0; i < nb_syms; ++i) {176 for (i = 0; i < nb_syms; ++i) {
174 ElfSym *sym = (ElfSym*)s->data + first_sym + i;177 ElfSym *sym = (ElfSym*)s->data + first_sym + i;
175
176 if (sym->st_shndx == SHN_UNDEF) {178 if (sym->st_shndx == SHN_UNDEF) {
177 int sym_bind = ELFW(ST_BIND)(sym->st_info);179 int sym_bind = ELFW(ST_BIND)(sym->st_info);
178 int sym_type = ELFW(ST_TYPE)(sym->st_info);180 int sym_type = ELFW(ST_TYPE)(sym->st_info);
@@ -187,26 +189,12 @@ ST_FUNC void tccelf_end_file(TCCState *s1) · 8 unmodified lines
187#endif189#endif
188 sym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);190 sym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
189 }191 }
190
191 tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info,192 tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info,
192 sym->st_other, sym->st_shndx, (char*)s->link->data + sym->st_name);193 sym->st_other, sym->st_shndx, (char*)s->link->data + sym->st_name);
193 }194 }
194 /* now update relocations */195 /* now update relocations */
195 for (i = 1; i < s1->nb_sections; i++) {196 update_relocs(s1, s, tr, first_sym);
196 Section *sr = s1->sections[i];
197 if (sr->sh_type == SHT_RELX && sr->link == s) {
198 ElfW_Rel *rel = (ElfW_Rel*)(sr->data + sr->sh_offset);
199 ElfW_Rel *rel_end = (ElfW_Rel*)(sr->data + sr->data_offset);
200 for (; rel < rel_end; ++rel) {
201 int n = ELFW(R_SYM)(rel->r_info) - first_sym;
202 if (n < 0) /* zero sym_index in reloc (can happen with asm) */
203 continue;
204 rel->r_info = ELFW(R_INFO)(tr[n], ELFW(R_TYPE)(rel->r_info));
205 }
206 }
207 }
208 tcc_free(tr);197 tcc_free(tr);
209
210 /* record text/data/bss output for -bench info */198 /* record text/data/bss output for -bench info */
211 for (i = 0; i < 4; ++i) {199 for (i = 0; i < 4; ++i) {
212 s = s1->sections[i + 1];200 s = s1->sections[i + 1];
@@ -801,7 +789,7 @@ ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc) · 588 unmodified lines
801 return &s1->sym_attrs[index];789 return &s1->sym_attrs[index];
802}790}
803 791
804static void modify_reloctions_old_to_new(TCCState *s1, Section *s, int *old_to_new_syms)792static void update_relocs(TCCState *s1, Section *s, int *old_to_new_syms, int first_sym)
805{793{
806 int i, type, sym_index;794 int i, type, sym_index;
807 Section *sr;795 Section *sr;
@@ -813,6 +801,8 @@ static void modify_reloctions_old_to_new(TCCState *s1, Section *s, int *old_to_n · 5 unmodified lines
813 for_each_elem(sr, 0, rel, ElfW_Rel) {801 for_each_elem(sr, 0, rel, ElfW_Rel) {
814 sym_index = ELFW(R_SYM)(rel->r_info);802 sym_index = ELFW(R_SYM)(rel->r_info);
815 type = ELFW(R_TYPE)(rel->r_info);803 type = ELFW(R_TYPE)(rel->r_info);
804 if ((sym_index -= first_sym) < 0)
805 continue; /* zero sym_index in reloc (can happen with asm) */
816 sym_index = old_to_new_syms[sym_index];806 sym_index = old_to_new_syms[sym_index];
817 rel->r_info = ELFW(R_INFO)(sym_index, type);807 rel->r_info = ELFW(R_INFO)(sym_index, type);
818 }808 }
@@ -863,8 +853,7 @@ static void sort_syms(TCCState *s1, Section *s) · 44 unmodified lines
863 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));853 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
864 tcc_free(new_syms);854 tcc_free(new_syms);
865 855
866 modify_reloctions_old_to_new(s1, s, old_to_new_syms);856 update_relocs(s1, s, old_to_new_syms, 0);
867
868 tcc_free(old_to_new_syms);857 tcc_free(old_to_new_syms);
869}858}
870 859
@@ -1012,7 +1001,7 @@ static void update_gnu_hash(TCCState *s1, Section *gnu_hash) · 141 unmodified lines
1012 tcc_free(buck);1001 tcc_free(buck);
1013 tcc_free(nextbuck);1002 tcc_free(nextbuck);
1014 1003
1015 modify_reloctions_old_to_new(s1, dynsym, old_to_new_syms);1004 update_relocs(s1, dynsym, old_to_new_syms, 0);
1016 1005
1017 /* modify the versions */1006 /* modify the versions */
1018 vs = versym_section;1007 vs = versym_section;
tccgen.c+51−54
@@ -657,8 +657,6 @@ ST_FUNC Sym *sym_find2(Sym *s, int v) · 656 unmodified lines
657 while (s) {657 while (s) {
658 if (s->v == v)658 if (s->v == v)
659 return s;659 return s;
660 else if (s->v == -1)
661 return NULL;
662 s = s->prev;660 s = s->prev;
663 }661 }
664 return NULL;662 return NULL;
@@ -1398,6 +1396,7 @@ ST_FUNC void save_reg_upstack(int r, int n) · 733 unmodified lines
1398 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;1396 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
1399 } else {1397 } else {
1400 p->r = VT_LVAL | VT_LOCAL;1398 p->r = VT_LVAL | VT_LOCAL;
1399 p->type.t &= ~VT_ARRAY; /* cannot combine VT_LVAL with VT_ARRAY */
1401 }1400 }
1402 p->sym = NULL;1401 p->sym = NULL;
1403 p->r2 = VT_CONST;1402 p->r2 = VT_CONST;
@@ -2838,14 +2837,25 @@ static int compare_types(CType *type1, CType *type2, int unqualified) · 1434 unmodified lines
2838 }2837 }
2839}2838}
2840 2839
2840#define CMP_OP 'C'
2841#define SHIFT_OP 'S'
2842
2841/* Check if OP1 and OP2 can be "combined" with operation OP, the combined2843/* Check if OP1 and OP2 can be "combined" with operation OP, the combined
2842 type is stored in DEST if non-null (except for pointer plus/minus) . */2844 type is stored in DEST if non-null (except for pointer plus/minus) . */
2843static int combine_types(CType *dest, SValue *op1, SValue *op2, int op)2845static int combine_types(CType *dest, SValue *op1, SValue *op2, int op)
2844{2846{
2845 CType *type1 = &op1->type, *type2 = &op2->type, type;2847 CType *type1, *type2, type;
2846 int t1 = type1->t, t2 = type2->t, bt1 = t1 & VT_BTYPE, bt2 = t2 & VT_BTYPE;2848 int t1, t2, bt1, bt2;
2847 int ret = 1;2849 int ret = 1;
2848 2850
2851 /* for shifts, 'combine' only left operand */
2852 if (op == SHIFT_OP)
2853 op2 = op1;
2854
2855 type1 = &op1->type, type2 = &op2->type;
2856 t1 = type1->t, t2 = type2->t;
2857 bt1 = t1 & VT_BTYPE, bt2 = t2 & VT_BTYPE;
2858
2849 type.t = VT_VOID;2859 type.t = VT_VOID;
2850 type.ref = NULL;2860 type.ref = NULL;
2851 2861
@@ -2854,7 +2864,10 @@ static int combine_types(CType *dest, SValue *op1, SValue *op2, int op) · 2 unmodified lines
2854 /* NOTE: as an extension, we accept void on only one side */2864 /* NOTE: as an extension, we accept void on only one side */
2855 type.t = VT_VOID;2865 type.t = VT_VOID;
2856 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {2866 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
2857 if (op == '+') ; /* Handled in caller */2867 if (op == '+') {
2868 if (!is_integer_btype(bt1 == VT_PTR ? bt2 : bt1))
2869 ret = 0;
2870 }
2858 /* http://port70.net/~nsz/c/c99/n1256.html#6.5.15p6 */2871 /* http://port70.net/~nsz/c/c99/n1256.html#6.5.15p6 */
2859 /* If one is a null ptr constant the result type is the other. */2872 /* If one is a null ptr constant the result type is the other. */
2860 else if (is_null_pointer (op2)) type = *type1;2873 else if (is_null_pointer (op2)) type = *type1;
@@ -2862,7 +2875,7 @@ static int combine_types(CType *dest, SValue *op1, SValue *op2, int op) · 1 unmodified line
2862 else if (bt1 != bt2) {2875 else if (bt1 != bt2) {
2863 /* accept comparison or cond-expr between pointer and integer2876 /* accept comparison or cond-expr between pointer and integer
2864 with a warning */2877 with a warning */
2865 if ((op == '?' || TOK_ISCOND(op))2878 if ((op == '?' || op == CMP_OP)
2866 && (is_integer_btype(bt1) || is_integer_btype(bt2)))2879 && (is_integer_btype(bt1) || is_integer_btype(bt2)))
2867 tcc_warning("pointer/integer mismatch in %s",2880 tcc_warning("pointer/integer mismatch in %s",
2868 op == '?' ? "conditional expression" : "comparison");2881 op == '?' ? "conditional expression" : "comparison");
@@ -2877,7 +2890,7 @@ static int combine_types(CType *dest, SValue *op1, SValue *op2, int op) · 8 unmodified lines
2877 int newquals, copied = 0;2890 int newquals, copied = 0;
2878 if (pbt1 != VT_VOID && pbt2 != VT_VOID2891 if (pbt1 != VT_VOID && pbt2 != VT_VOID
2879 && !compare_types(pt1, pt2, 1/*unqualif*/)) {2892 && !compare_types(pt1, pt2, 1/*unqualif*/)) {
2880 if (op != '?' && !TOK_ISCOND(op))2893 if (op != '?' && op != CMP_OP)
2881 ret = 0;2894 ret = 0;
2882 else2895 else
2883 type_incompatibility_warning(type1, type2,2896 type_incompatibility_warning(type1, type2,
@@ -2918,7 +2931,7 @@ static int combine_types(CType *dest, SValue *op1, SValue *op2, int op) · 34 unmodified lines
2918 }2931 }
2919 }2932 }
2920 }2933 }
2921 if (TOK_ISCOND(op))2934 if (op == CMP_OP)
2922 type.t = VT_SIZE_T;2935 type.t = VT_SIZE_T;
2923 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {2936 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
2924 if (op != '?' || !compare_types(type1, type2, 1))2937 if (op != '?' || !compare_types(type1, type2, 1))
@@ -2961,6 +2974,12 @@ ST_FUNC void gen_op(int op) · 36 unmodified lines
2961{2974{
2962 int t1, t2, bt1, bt2, t;2975 int t1, t2, bt1, bt2, t;
2963 CType type1, combtype;2976 CType type1, combtype;
2977 int op_class = op;
2978
2979 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
2980 op_class = SHIFT_OP;
2981 else if (TOK_ISCOND(op)) /* == != > ... */
2982 op_class = CMP_OP;
2964 2983
2965redo:2984redo:
2966 t1 = vtop[-1].type.t;2985 t1 = vtop[-1].type.t;
@@ -2980,18 +2999,19 @@ redo: · 13 unmodified lines
2980 vswap();2999 vswap();
2981 }3000 }
2982 goto redo;3001 goto redo;
2983 } else if (!combine_types(&combtype, vtop - 1, vtop, op)) {3002 } else if (!combine_types(&combtype, vtop - 1, vtop, op_class)) {
3003op_err:
2984 tcc_error("invalid operand types for binary operation");3004 tcc_error("invalid operand types for binary operation");
2985 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {3005 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
2986 /* at least one operand is a pointer */3006 /* at least one operand is a pointer */
2987 /* relational op: must be both pointers */3007 /* relational op: must be both pointers */
2988 int align;3008 int align;
2989 if (TOK_ISCOND(op))3009 if (op_class == CMP_OP)
2990 goto std_op;3010 goto std_op;
2991 /* if both pointers, then it must be the '-' op */3011 /* if both pointers, then it must be the '-' op */
2992 if (bt1 == VT_PTR && bt2 == VT_PTR) {3012 if (bt1 == VT_PTR && bt2 == VT_PTR) {
2993 if (op != '-')3013 if (op != '-')
2994 tcc_error("cannot use pointers here");3014 goto op_err;
2995 vpush_type_size(pointed_type(&vtop[-1].type), &align);3015 vpush_type_size(pointed_type(&vtop[-1].type), &align);
2996 vtop->type.t &= ~VT_UNSIGNED;3016 vtop->type.t &= ~VT_UNSIGNED;
2997 vrott(3);3017 vrott(3);
@@ -3002,14 +3022,15 @@ redo: · 4 unmodified lines
3002 } else {3022 } else {
3003 /* exactly one pointer : must be '+' or '-'. */3023 /* exactly one pointer : must be '+' or '-'. */
3004 if (op != '-' && op != '+')3024 if (op != '-' && op != '+')
3005 tcc_error("cannot use pointers here");3025 goto op_err;
3006 /* Put pointer as first operand */3026 /* Put pointer as first operand */
3007 if (bt2 == VT_PTR) {3027 if (bt2 == VT_PTR) {
3008 vswap();3028 vswap();
3009 t = t1, t1 = t2, t2 = t;3029 t = t1, t1 = t2, t2 = t;
3030 bt2 = bt1;
3010 }3031 }
3011#if PTR_SIZE == 43032#if PTR_SIZE == 4
3012 if ((vtop[0].type.t & VT_BTYPE) == VT_LLONG)3033 if (bt2 == VT_LLONG)
3013 /* XXX: truncate here because gen_opl can't handle ptr + long long */3034 /* XXX: truncate here because gen_opl can't handle ptr + long long */
3014 gen_cast_s(VT_INT);3035 gen_cast_s(VT_INT);
3015#endif3036#endif
@@ -3039,17 +3060,15 @@ redo: · 23 unmodified lines
3039 /* floats can only be used for a few operations */3060 /* floats can only be used for a few operations */
3040 if (is_float(combtype.t)3061 if (is_float(combtype.t)
3041 && op != '+' && op != '-' && op != '*' && op != '/'3062 && op != '+' && op != '-' && op != '*' && op != '/'
3042 && !TOK_ISCOND(op))3063 && op_class != CMP_OP) {
3043 tcc_error("invalid operands for binary operation");3064 goto op_err;
3044 else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
3045 t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
3046 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (t | VT_UNSIGNED))
3047 t |= VT_UNSIGNED;
3048 t |= (VT_LONG & t1);
3049 combtype.t = t;
3050 }3065 }
3051 std_op:3066 std_op:
3052 t = t2 = combtype.t;3067 t = t2 = combtype.t;
3068 /* special case for shifts and long long: we keep the shift as
3069 an integer */
3070 if (op_class == SHIFT_OP)
3071 t2 = VT_INT;
3053 /* XXX: currently, some unsigned operations are explicit, so3072 /* XXX: currently, some unsigned operations are explicit, so
3054 we modify them here */3073 we modify them here */
3055 if (t & VT_UNSIGNED) {3074 if (t & VT_UNSIGNED) {
@@ -3071,16 +3090,12 @@ redo: · 15 unmodified lines
3071 vswap();3090 vswap();
3072 gen_cast_s(t);3091 gen_cast_s(t);
3073 vswap();3092 vswap();
3074 /* special case for shifts and long long: we keep the shift as
3075 an integer */
3076 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
3077 t2 = VT_INT;
3078 gen_cast_s(t2);3093 gen_cast_s(t2);
3079 if (is_float(t))3094 if (is_float(t))
3080 gen_opif(op);3095 gen_opif(op);
3081 else3096 else
3082 gen_opic(op);3097 gen_opic(op);
3083 if (TOK_ISCOND(op)) {3098 if (op_class == CMP_OP) {
3084 /* relational op: the result is an int */3099 /* relational op: the result is an int */
3085 vtop->type.t = VT_INT;3100 vtop->type.t = VT_INT;
3086 } else {3101 } else {
@@ -3416,13 +3431,10 @@ ST_FUNC int type_size(CType *type, int *a) · 329 unmodified lines
3416 } else if (bt == VT_PTR) {3431 } else if (bt == VT_PTR) {
3417 if (type->t & VT_ARRAY) {3432 if (type->t & VT_ARRAY) {
3418 int ts;3433 int ts;
3419
3420 s = type->ref;3434 s = type->ref;
3421 ts = type_size(&s->type, a);3435 ts = type_size(&s->type, a);
3422
3423 if (ts < 0 && s->c < 0)3436 if (ts < 0 && s->c < 0)
3424 ts = -ts;3437 ts = -ts;
3425
3426 return ts * s->c;3438 return ts * s->c;
3427 } else {3439 } else {
3428 *a = PTR_SIZE;3440 *a = PTR_SIZE;
@@ -3435,18 +3447,9 @@ ST_FUNC int type_size(CType *type, int *a) · 6 unmodified lines
3435 *a = LDOUBLE_ALIGN;3447 *a = LDOUBLE_ALIGN;
3436 return LDOUBLE_SIZE;3448 return LDOUBLE_SIZE;
3437 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {3449 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
3438#ifdef TCC_TARGET_I3863450#if (defined TCC_TARGET_I386 && !defined TCC_TARGET_PE) \
3439#ifdef TCC_TARGET_PE3451 || (defined TCC_TARGET_ARM && !defined TCC_ARM_EABI)
3440 *a = 8;
3441#else
3442 *a = 4;
3443#endif
3444#elif defined(TCC_TARGET_ARM)
3445#ifdef TCC_ARM_EABI
3446 *a = 8;
3447#else
3448 *a = 4;3452 *a = 4;
3449#endif
3450#else3453#else
3451 *a = 8;3454 *a = 8;
3452#endif3455#endif
@@ -3974,12 +3977,12 @@ redo: · 521 unmodified lines
3974 case TOK_FASTCALL2:3977 case TOK_FASTCALL2:
3975 case TOK_FASTCALL3:3978 case TOK_FASTCALL3:
3976 ad->f.func_call = FUNC_FASTCALLW;3979 ad->f.func_call = FUNC_FASTCALLW;
3977 break; 3980 break;
3978 case TOK_THISCALL1:3981 case TOK_THISCALL1:
3979 case TOK_THISCALL2:3982 case TOK_THISCALL2:
3980 case TOK_THISCALL3:3983 case TOK_THISCALL3:
3981 ad->f.func_call = FUNC_THISCALL;3984 ad->f.func_call = FUNC_THISCALL;
3982 break; 3985 break;
3983#endif3986#endif
3984 case TOK_MODE:3987 case TOK_MODE:
3985 skip('(');3988 skip('(');
@@ -5714,16 +5717,12 @@ ST_FUNC void unary(void) · 1728 unmodified lines
5714 case TOK_builtin_return_address:5717 case TOK_builtin_return_address:
5715 {5718 {
5716 int tok1 = tok;5719 int tok1 = tok;
5717 int64_t level;5720 int level;
5718 next();5721 next();
5719 skip('(');5722 skip('(');
5720 level = expr_const64();5723 level = expr_const();
5721 if (level < 0) {5724 if (level < 0)
5722 tcc_error("%s only takes positive integers",5725 tcc_error("%s only takes positive integers", get_tok_str(tok1, 0));
5723 tok1 == TOK_builtin_return_address ?
5724 "__builtin_return_address" :
5725 "__builtin_frame_address");
5726 }
5727 skip(')');5726 skip(')');
5728 type.t = VT_VOID;5727 type.t = VT_VOID;
5729 mk_pointer(&type);5728 mk_pointer(&type);
@@ -7400,12 +7399,10 @@ static void init_putz(init_params *p, unsigned long c, int size) · 1670 unmodified lines
7400 } else {7399 } else {
7401 vpush_helper_func(TOK_memset);7400 vpush_helper_func(TOK_memset);
7402 vseti(VT_LOCAL, c);7401 vseti(VT_LOCAL, c);
7403#ifdef TCC_TARGET_ARM
7404 vpushs(size);
7405 vpushi(0);
7406#else
7407 vpushi(0);7402 vpushi(0);
7408 vpushs(size);7403 vpushs(size);
7404#if defined TCC_TARGET_ARM && defined TCC_ARM_EABI
7405 vswap(); /* using __aeabi_memset(void*, size_t, int) */
7409#endif7406#endif
7410 gfunc_call(3);7407 gfunc_call(3);
7411 }7408 }
tccpe.c+5−2
@@ -889,7 +889,7 @@ static void pe_build_imports(struct pe_info *pe) · 888 unmodified lines
889 889
890 dllindex = p->dll_index;890 dllindex = p->dll_index;
891 if (dllindex)891 if (dllindex)
892 name = tcc_basename((dllref = pe->s1->loaded_dlls[dllindex-1])->name);892 name = (dllref = pe->s1->loaded_dlls[dllindex-1])->name;
893 else893 else
894 name = "", dllref = NULL;894 name = "", dllref = NULL;
895 895
@@ -1767,6 +1767,9 @@ static int pe_load_def(TCCState *s1, int fd) · 871 unmodified lines
1767 char dllname[80], *buf, *line, *p, *x, next;1767 char dllname[80], *buf, *line, *p, *x, next;
1768 1768
1769 buf = tcc_load_text(fd);1769 buf = tcc_load_text(fd);
1770 if (!buf)
1771 return ret;
1772
1770 for (line = buf;; ++line) {1773 for (line = buf;; ++line) {
1771 p = get_token(&line, &next);1774 p = get_token(&line, &next);
1772 if (!(*p && *p != ';'))1775 if (!(*p && *p != ';'))
@@ -1815,7 +1818,7 @@ quit: · 42 unmodified lines
1815static int pe_load_dll(TCCState *s1, int fd, const char *filename)1818static int pe_load_dll(TCCState *s1, int fd, const char *filename)
1816{1819{
1817 char *p, *q;1820 char *p, *q;
1818 DLLReference *ref = tcc_add_dllref(s1, filename, 0);1821 DLLReference *ref = tcc_add_dllref(s1, tcc_basename(filename), 0);
1819 if (ref->found)1822 if (ref->found)
1820 return 0;1823 return 0;
1821 if (get_dllexports(fd, &p))1824 if (get_dllexports(fd, &p))
tccpp.c+32−31
@@ -92,7 +92,6 @@ static const unsigned char tok_two_chars[] = · 91 unmodified lines
92 '-','>', TOK_ARROW,92 '-','>', TOK_ARROW,
93 '.','.', TOK_TWODOTS,93 '.','.', TOK_TWODOTS,
94 '#','#', TOK_TWOSHARPS,94 '#','#', TOK_TWOSHARPS,
95 '#','#', TOK_PPJOIN,
96 095 0
97};96};
98 97
@@ -137,10 +136,8 @@ ST_FUNC void expect(const char *msg) · 38 unmodified lines
137 136
138#define TOKSYM_TAL_SIZE (768 * 1024) /* allocator for tiny TokenSym in table_ident */137#define TOKSYM_TAL_SIZE (768 * 1024) /* allocator for tiny TokenSym in table_ident */
139#define TOKSTR_TAL_SIZE (768 * 1024) /* allocator for tiny TokenString instances */138#define TOKSTR_TAL_SIZE (768 * 1024) /* allocator for tiny TokenString instances */
140#define CSTR_TAL_SIZE (256 * 1024) /* allocator for tiny CString instances */139#define TOKSYM_TAL_LIMIT 256 /* prefer unique limits to distinguish allocators debug msgs */
141#define TOKSYM_TAL_LIMIT 256 /* prefer unique limits to distinguish allocators debug msgs */140#define TOKSTR_TAL_LIMIT 1024 /* 256 * sizeof(int) */
142#define TOKSTR_TAL_LIMIT 128 /* 32 * sizeof(int) */
143#define CSTR_TAL_LIMIT 1024
144 141
145typedef struct TinyAlloc {142typedef struct TinyAlloc {
146 unsigned limit;143 unsigned limit;
@@ -185,8 +182,8 @@ tail_call: · 38 unmodified lines
185 if (!al)182 if (!al)
186 return;183 return;
187#ifdef TAL_INFO184#ifdef TAL_INFO
188 fprintf(stderr, "limit=%5d, size=%5g MB, nb_peak=%6d, nb_total=%8d, nb_missed=%6d, usage=%5.1f%%\n",185 fprintf(stderr, "limit %4d size %7d nb_peak %5d nb_total %7d nb_missed %5d usage %5.1f%%\n",
189 al->limit, al->size / 1024.0 / 1024.0, al->nb_peak, al->nb_total, al->nb_missed,186 al->limit, al->size, al->nb_peak, al->nb_total, al->nb_missed,
190 (al->peak_p - al->buffer) * 100.0 / al->size);187 (al->peak_p - al->buffer) * 100.0 / al->size);
191#endif188#endif
192#if TAL_DEBUG && TAL_DEBUG != 3 /* do not check TAL leaks with -DMEM_DEBUG=3 */189#if TAL_DEBUG && TAL_DEBUG != 3 /* do not check TAL leaks with -DMEM_DEBUG=3 */
@@ -345,7 +342,7 @@ ST_INLN void cstr_ccat(CString *cstr, int ch) · 152 unmodified lines
345 size = cstr->size + 1;342 size = cstr->size + 1;
346 if (size > cstr->size_allocated)343 if (size > cstr->size_allocated)
347 cstr_realloc(cstr, size);344 cstr_realloc(cstr, size);
348 ((unsigned char *)cstr->data)[size - 1] = ch;345 cstr->data[size - 1] = ch;
349 cstr->size = size;346 cstr->size = size;
350}347}
351 348
@@ -368,6 +365,7 @@ ST_INLN void cstr_u8cat(CString *cstr, int ch) · 16 unmodified lines
368 cstr_cat(cstr, buf, e - buf);365 cstr_cat(cstr, buf, e - buf);
369}366}
370 367
368/* add string of 'len', or of its len/len+1 when 'len' == -1/0 */
371ST_FUNC void cstr_cat(CString *cstr, const char *str, int len)369ST_FUNC void cstr_cat(CString *cstr, const char *str, int len)
372{370{
373 int size;371 int size;
@@ -376,7 +374,7 @@ ST_FUNC void cstr_cat(CString *cstr, const char *str, int len) · 2 unmodified lines
376 size = cstr->size + len;374 size = cstr->size + len;
377 if (size > cstr->size_allocated)375 if (size > cstr->size_allocated)
378 cstr_realloc(cstr, size);376 cstr_realloc(cstr, size);
379 memmove(((unsigned char *)cstr->data) + cstr->size, str, len);377 memmove(cstr->data + cstr->size, str, len);
380 cstr->size = size;378 cstr->size = size;
381}379}
382 380
@@ -387,7 +385,7 @@ ST_FUNC void cstr_wccat(CString *cstr, int ch) · 4 unmodified lines
387 size = cstr->size + sizeof(nwchar_t);385 size = cstr->size + sizeof(nwchar_t);
388 if (size > cstr->size_allocated)386 if (size > cstr->size_allocated)
389 cstr_realloc(cstr, size);387 cstr_realloc(cstr, size);
390 *(nwchar_t *)(((unsigned char *)cstr->data) + size - sizeof(nwchar_t)) = ch;388 *(nwchar_t *)(cstr->data + size - sizeof(nwchar_t)) = ch;
391 cstr->size = size;389 cstr->size = size;
392}390}
393 391
@@ -418,7 +416,7 @@ ST_FUNC int cstr_vprintf(CString *cstr, const char *fmt, va_list ap) · 24 unmodified lines
418 cstr_realloc(cstr, size);416 cstr_realloc(cstr, size);
419 size = cstr->size_allocated - cstr->size;417 size = cstr->size_allocated - cstr->size;
420 va_copy(v, ap);418 va_copy(v, ap);
421 len = vsnprintf((char*)cstr->data + cstr->size, size, fmt, v);419 len = vsnprintf(cstr->data + cstr->size, size, fmt, v);
422 va_end(v);420 va_end(v);
423 if (len >= 0 && len < size)421 if (len >= 0 && len < size)
424 break;422 break;
@@ -1920,7 +1918,8 @@ ST_FUNC void preprocess(int is_bof) · 1495 unmodified lines
1920 if (file->fd > 0)1918 if (file->fd > 0)
1921 total_lines += file->line_num - n;1919 total_lines += file->line_num - n;
1922 file->line_num = n;1920 file->line_num = n;
1923 break;1921 goto ignore; /* skip optional level number */
1922
1924 case TOK_ERROR:1923 case TOK_ERROR:
1925 case TOK_WARNING:1924 case TOK_WARNING:
1926 q = buf;1925 q = buf;
@@ -3070,12 +3069,13 @@ static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args) · 1143 unmodified lines
3070/* handle the '##' operator. return the resulting string (which must be freed). */3069/* handle the '##' operator. return the resulting string (which must be freed). */
3071static inline int *macro_twosharps(const int *ptr0)3070static inline int *macro_twosharps(const int *ptr0)
3072{3071{
3073 int t1, t2, n;3072 int t1, t2, n, l;
3074 CValue cv1, cv2;3073 CValue cv1, cv2;
3075 TokenString macro_str1;3074 TokenString macro_str1;
3076 const int *ptr;3075 const int *ptr;
3077 3076
3078 tok_str_new(&macro_str1);3077 tok_str_new(&macro_str1);
3078 cstr_reset(&tokcstr);
3079 for (ptr = ptr0;;) {3079 for (ptr = ptr0;;) {
3080 TOK_GET(&t1, &ptr, &cv1);3080 TOK_GET(&t1, &ptr, &cv1);
3081 if (t1 == 0)3081 if (t1 == 0)
@@ -3090,29 +3090,31 @@ static inline int *macro_twosharps(const int *ptr0) · 8 unmodified lines
3090 while ((t2 = *++ptr) == ' ' || t2 == TOK_PPJOIN)3090 while ((t2 = *++ptr) == ' ' || t2 == TOK_PPJOIN)
3091 ;3091 ;
3092 TOK_GET(&t2, &ptr, &cv2);3092 TOK_GET(&t2, &ptr, &cv2);
3093 if (t1 == TOK_PLCHLDR && t2 == TOK_PLCHLDR)3093 if (t2 == TOK_PLCHLDR)
3094 continue;3094 continue;
3095 cstr_reset(&tokcstr);3095 if (t1 != TOK_PLCHLDR) {
3096 if (t1 != TOK_PLCHLDR)
3097 cstr_cat(&tokcstr, get_tok_str(t1, &cv1), -1);3096 cstr_cat(&tokcstr, get_tok_str(t1, &cv1), -1);
3098 n = tokcstr.size;3097 t1 = TOK_PLCHLDR;
3099 if (t2 != TOK_PLCHLDR)3098 }
3100 cstr_cat(&tokcstr, get_tok_str(t2, &cv2), -1);3099 cstr_cat(&tokcstr, get_tok_str(t2, &cv2), -1);
3101 cstr_ccat(&tokcstr, '\0');3100 }
3102 //printf("paste <%s>\n", (char*)tokcstr.data);3101 if (tokcstr.size) {
3102 cstr_ccat(&tokcstr, 0);
3103 tcc_open_bf(tcc_state, ":paste:", tokcstr.size);3103 tcc_open_bf(tcc_state, ":paste:", tokcstr.size);
3104 memcpy(file->buffer, tokcstr.data, tokcstr.size);3104 memcpy(file->buffer, tokcstr.data, tokcstr.size);
3105 tok_flags = 0; /* don't interpret '#' */3105 tok_flags = 0; /* don't interpret '#' */
3106 next_nomacro();3106 for (n = 0;;n = l) {
3107 if (*file->buf_ptr == 0) {3107 next_nomacro();
3108 t1 = tok, cv1 = tokc;3108 tok_str_add2(&macro_str1, tok, &tokc);
3109 } else {3109 if (*file->buf_ptr == 0)
3110 break;
3111 tok_str_add(&macro_str1, ' ');
3112 l = file->buf_ptr - file->buffer;
3110 tcc_warning("pasting \"%.*s\" and \"%s\" does not give a valid"3113 tcc_warning("pasting \"%.*s\" and \"%s\" does not give a valid"
3111 " preprocessing token", n, file->buffer, file->buffer + n);3114 " preprocessing token", l - n, file->buffer + n, file->buf_ptr);
3112 tok_str_add2(&macro_str1, t1, &cv1);
3113 t1 = t2, cv1 = cv2;
3114 }3115 }
3115 tcc_close();3116 tcc_close();
3117 cstr_reset(&tokcstr);
3116 }3118 }
3117 if (t1 != TOK_PLCHLDR)3119 if (t1 != TOK_PLCHLDR)
3118 tok_str_add2(&macro_str1, t1, &cv1);3120 tok_str_add2(&macro_str1, t1, &cv1);
@@ -3450,9 +3452,8 @@ redo: · 331 unmodified lines
3450 /* do nothing */3452 /* do nothing */
3451 } else {3453 } else {
3452 ++macro_ptr;3454 ++macro_ptr;
3453 if (t >= TOK_IDENT) {3455 t &= ~SYM_FIELD; /* remove 'nosubst' marker */
3454 t &= ~SYM_FIELD; /* remove 'nosubst' marker */3456 if (t == '\\') {
3455 } else if (t == '\\') {
3456 if (!(parse_flags & PARSE_FLAG_ACCEPT_STRAYS))3457 if (!(parse_flags & PARSE_FLAG_ACCEPT_STRAYS))
3457 tcc_error("stray '\\' in program");3458 tcc_error("stray '\\' in program");
3458 }3459 }
tests/tests2/60_errors_and_warnings.c+7−0
@@ -483,4 +483,11 @@ struct A { · 482 unmodified lines
483# if X(1,2) //undefined function macro483# if X(1,2) //undefined function macro
484# endif484# endif
485 485
486#elif defined test_pointer_plus_double
487
488int *invalid_operation(int *p, double d)
489{
490 return p + d;
491}
492
486#endif493#endif
tests/tests2/60_errors_and_warnings.expect+3−0
@@ -237,3 +237,6 @@ arg[1] = "Y" · 236 unmodified lines
237 237
238[test_pp_error_2]238[test_pp_error_2]
23960_errors_and_warnings.c:483: error: bad preprocessor expression: #if 0 ( 1 , 2 )23960_errors_and_warnings.c:483: error: bad preprocessor expression: #if 0 ( 1 , 2 )
240
241[test_pointer_plus_double]
24260_errors_and_warnings.c:490: error: invalid operand types for binary operation
tests/thiscall/thiscall-test.c+0−17
@@ -1,17 +0,0 @@
1#ifndef __thiscall
2 #define __thiscall __attribute__((thiscall))
3#endif
4#ifndef __cdecl
5 #define __cdecl __attribute__((cdecl))
6#endif
7#ifndef __stdcall
8 #define __stdcall __attribute__((stdcall))
9#endif
10
11void ( __thiscall * const thisCall1 ) ( void * _this, int a ) = ( void ( __thiscall * ) ( void * _this, int a ) ) 0x4788a0;
12
13int main() {
14 thisCall1((void*) 0xDEADBEEF, 1000);
15
16 return 1;
17}
x86_64-link.c+3−3
@@ -25,7 +25,7 @@ · 24 unmodified lines
25#ifdef NEED_RELOC_TYPE25#ifdef NEED_RELOC_TYPE
26/* Returns 1 for a code relocation, 0 for a data relocation. For unknown26/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
27 relocations, returns -1. */27 relocations, returns -1. */
28int code_reloc (int reloc_type)28ST_FUNC int code_reloc (int reloc_type)
29{29{
30 switch (reloc_type) {30 switch (reloc_type) {
31 case R_X86_64_32:31 case R_X86_64_32:
@@ -64,7 +64,7 @@ int code_reloc (int reloc_type) · 32 unmodified lines
64/* Returns an enumerator to describe whether and when the relocation needs a64/* Returns an enumerator to describe whether and when the relocation needs a
65 GOT and/or PLT entry to be created. See tcc.h for a description of the65 GOT and/or PLT entry to be created. See tcc.h for a description of the
66 different values. */66 different values. */
67int gotplt_entry_type (int reloc_type)67ST_FUNC int gotplt_entry_type (int reloc_type)
68{68{
69 switch (reloc_type) {69 switch (reloc_type) {
70 case R_X86_64_GLOB_DAT:70 case R_X86_64_GLOB_DAT:
@@ -186,7 +186,7 @@ ST_FUNC void relocate_plt(TCCState *s1) · 115 unmodified lines
186#endif186#endif
187#endif187#endif
188 188
189void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)189ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
190{190{
191 int sym_index, esym_index;191 int sym_index, esym_index;
192 192

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