Unified · Split
| @@ -24,9 +24,9 @@ · 23 unmodified lines | |||
| 24 | #define CONFIG_TCC_ASM | 24 | #define CONFIG_TCC_ASM |
| 25 | #define NB_ASM_REGS 16 | 25 | #define NB_ASM_REGS 16 |
| 26 | 26 | ||
| 27 | ST_FUNC void g(int c); | 27 | ST_FUNC void g(TCCState* S, int c); |
| 28 | ST_FUNC void gen_le16(int c); | 28 | ST_FUNC void gen_le16(TCCState* S, int c); |
| 29 | ST_FUNC void gen_le32(int c); | 29 | ST_FUNC void gen_le32(TCCState* S, int c); |
| 30 | 30 | ||
| 31 | /*************************************************************/ | 31 | /*************************************************************/ |
| 32 | #else | 32 | #else |
| @@ -92,7 +92,7 @@ static int asm_parse_vfp_status_regvar(int t) · 59 unmodified lines | |||
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | /* Parse a text containing operand and store the result in OP */ | 94 | /* Parse a text containing operand and store the result in OP */ |
| 95 | static void parse_operand(TCCState *s1, Operand *op) | 95 | static void parse_operand(TCCState *S, Operand *op) |
| 96 | { | 96 | { |
| 97 | ExprValue e; | 97 | ExprValue e; |
| 98 | int8_t reg; | 98 | int8_t reg; |
| @@ -100,54 +100,54 @@ static void parse_operand(TCCState *s1, Operand *op) · 1 unmodified line | |||
| 100 | 100 | ||
| 101 | op->type = 0; | 101 | op->type = 0; |
| 102 | 102 | ||
| 103 | if (tok == '{') { // regset literal | 103 | if (S->tccpp_tok == '{') { // regset literal |
| 104 | next(); // skip '{' | 104 | next(S); // skip '{' |
| 105 | while (tok != '}' && tok != TOK_EOF) { | 105 | while (S->tccpp_tok != '}' && S->tccpp_tok != TOK_EOF) { |
| 106 | reg = asm_parse_regvar(tok); | 106 | reg = asm_parse_regvar(S, S->tccpp_tok); |
| 107 | if (reg == -1) { | 107 | if (reg == -1) { |
| 108 | expect("register"); | 108 | expect(S, "register"); |
| 109 | return; | 109 | return; |
| 110 | } else | 110 | } else |
| 111 | next(); // skip register name | 111 | next(S); // skip register name |
| 112 | 112 | ||
| 113 | if ((1 << reg) < regset) | 113 | if ((1 << reg) < regset) |
| 114 | tcc_warning("registers will be processed in ascending order by hardware--but are not specified in ascending order here"); | 114 | tcc_warning(S, "registers will be processed in ascending order by hardware--but are not specified in ascending order here"); |
| 115 | regset |= 1 << reg; | 115 | regset |= 1 << reg; |
| 116 | if (tok != ',') | 116 | if (S->tccpp_tok != ',') |
| 117 | break; | 117 | break; |
| 118 | next(); // skip ',' | 118 | next(S); // skip ',' |
| 119 | } | 119 | } |
| 120 | if (tok != '}') | 120 | if (S->tccpp_tok != '}') |
| 121 | expect("'}'"); | 121 | expect(S, "'}'"); |
| 122 | next(); // skip '}' | 122 | next(S); // skip '}' |
| 123 | if (regset == 0) { | 123 | if (regset == 0) { |
| 124 | // ARM instructions don't support empty regset. | 124 | // ARM instructions don't support empty regset. |
| 125 | tcc_error("empty register list is not supported"); | 125 | tcc_error(S, "empty register list is not supported"); |
| 126 | } else { | 126 | } else { |
| 127 | op->type = OP_REGSET32; | 127 | op->type = OP_REGSET32; |
| 128 | op->regset = regset; | 128 | op->regset = regset; |
| 129 | } | 129 | } |
| 130 | return; | 130 | return; |
| 131 | } else if ((reg = asm_parse_regvar(tok)) != -1) { | 131 | } else if ((reg = asm_parse_regvar(S, S->tccpp_tok)) != -1) { |
| 132 | next(); // skip register name | 132 | next(S); // skip register name |
| 133 | op->type = OP_REG32; | 133 | op->type = OP_REG32; |
| 134 | op->reg = (uint8_t) reg; | 134 | op->reg = (uint8_t) reg; |
| 135 | return; | 135 | return; |
| 136 | } else if ((reg = asm_parse_vfp_regvar(tok, 0)) != -1) { | 136 | } else if ((reg = asm_parse_vfp_regvar(S->tccpp_tok, 0)) != -1) { |
| 137 | next(); // skip register name | 137 | next(S); // skip register name |
| 138 | op->type = OP_VREG32; | 138 | op->type = OP_VREG32; |
| 139 | op->reg = (uint8_t) reg; | 139 | op->reg = (uint8_t) reg; |
| 140 | return; | 140 | return; |
| 141 | } else if ((reg = asm_parse_vfp_regvar(tok, 1)) != -1) { | 141 | } else if ((reg = asm_parse_vfp_regvar(S->tccpp_tok, 1)) != -1) { |
| 142 | next(); // skip register name | 142 | next(S); // skip register name |
| 143 | op->type = OP_VREG64; | 143 | op->type = OP_VREG64; |
| 144 | op->reg = (uint8_t) reg; | 144 | op->reg = (uint8_t) reg; |
| 145 | return; | 145 | return; |
| 146 | } else if (tok == '#' || tok == '$') { | 146 | } else if (S->tccpp_tok == '#' || S->tccpp_tok == '$') { |
| 147 | /* constant value */ | 147 | /* constant value */ |
| 148 | next(); // skip '#' or '$' | 148 | next(S); // skip '#' or '$' |
| 149 | } | 149 | } |
| 150 | asm_expr(s1, &e); | 150 | asm_expr(S, &e); |
| 151 | op->type = OP_IM32; | 151 | op->type = OP_IM32; |
| 152 | op->e = e; | 152 | op->e = e; |
| 153 | if (!op->e.sym) { | 153 | if (!op->e.sym) { |
| @@ -156,64 +156,64 @@ static void parse_operand(TCCState *s1, Operand *op) · 2 unmodified lines | |||
| 156 | else if (op->e.v == (uint8_t)op->e.v) | 156 | else if (op->e.v == (uint8_t)op->e.v) |
| 157 | op->type = OP_IM8; | 157 | op->type = OP_IM8; |
| 158 | } else | 158 | } else |
| 159 | expect("operand"); | 159 | expect(S, "operand"); |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | /* XXX: make it faster ? */ | 162 | /* XXX: make it faster ? */ |
| 163 | ST_FUNC void g(int c) | 163 | ST_FUNC void g(TCCState* S, int c) |
| 164 | { | 164 | { |
| 165 | int ind1; | 165 | int ind1; |
| 166 | if (nocode_wanted) | 166 | if (S->tccgen_nocode_wanted) |
| 167 | return; | 167 | return; |
| 168 | ind1 = ind + 1; | 168 | ind1 = S->tccgen_ind + 1; |
| 169 | if (ind1 > cur_text_section->data_allocated) | 169 | if (ind1 > cur_text_section->data_allocated) |
| 170 | section_realloc(cur_text_section, ind1); | 170 | section_realloc(S, cur_text_section, ind1); |
| 171 | cur_text_section->data[ind] = c; | 171 | cur_text_section->data[S->tccgen_ind] = c; |
| 172 | ind = ind1; | 172 | S->tccgen_ind = ind1; |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | ST_FUNC void gen_le16 (int i) | 175 | ST_FUNC void gen_le16 (TCCState* S, int i) |
| 176 | { | 176 | { |
| 177 | g(i); | 177 | g(S, i); |
| 178 | g(i>>8); | 178 | g(S, i>>8); |
| 179 | } | 179 | } |
| 180 | 180 | ||
| 181 | ST_FUNC void gen_le32 (int i) | 181 | ST_FUNC void gen_le32 (TCCState* S, int i) |
| 182 | { | 182 | { |
| 183 | int ind1; | 183 | int ind1; |
| 184 | if (nocode_wanted) | 184 | if (S->tccgen_nocode_wanted) |
| 185 | return; | 185 | return; |
| 186 | ind1 = ind + 4; | 186 | ind1 = S->tccgen_ind + 4; |
| 187 | if (ind1 > cur_text_section->data_allocated) | 187 | if (ind1 > cur_text_section->data_allocated) |
| 188 | section_realloc(cur_text_section, ind1); | 188 | section_realloc(S, cur_text_section, ind1); |
| 189 | cur_text_section->data[ind++] = i & 0xFF; | 189 | cur_text_section->data[S->tccgen_ind++] = i & 0xFF; |
| 190 | cur_text_section->data[ind++] = (i >> 8) & 0xFF; | 190 | cur_text_section->data[S->tccgen_ind++] = (i >> 8) & 0xFF; |
| 191 | cur_text_section->data[ind++] = (i >> 16) & 0xFF; | 191 | cur_text_section->data[S->tccgen_ind++] = (i >> 16) & 0xFF; |
| 192 | cur_text_section->data[ind++] = (i >> 24) & 0xFF; | 192 | cur_text_section->data[S->tccgen_ind++] = (i >> 24) & 0xFF; |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | ST_FUNC void gen_expr32(ExprValue *pe) | 195 | ST_FUNC void gen_expr32(TCCState* S, ExprValue *pe) |
| 196 | { | 196 | { |
| 197 | gen_le32(pe->v); | 197 | gen_le32(S, pe->v); |
| 198 | } | 198 | } |
| 199 | 199 | ||
| 200 | static uint32_t condition_code_of_token(int token) { | 200 | static uint32_t condition_code_of_token(TCCState* S, int token) { |
| 201 | if (token < TOK_ASM_nopeq) { | 201 | if (token < TOK_ASM_nopeq) { |
| 202 | expect("condition-enabled instruction"); | 202 | expect(S, "condition-enabled instruction"); |
| 203 | return 0; | 203 | return 0; |
| 204 | } else | 204 | } else |
| 205 | return (token - TOK_ASM_nopeq) & 15; | 205 | return (token - TOK_ASM_nopeq) & 15; |
| 206 | } | 206 | } |
| 207 | 207 | ||
| 208 | static void asm_emit_opcode(int token, uint32_t opcode) { | 208 | static void asm_emit_opcode(TCCState* S, int token, uint32_t opcode) { |
| 209 | gen_le32((condition_code_of_token(token) << 28) | opcode); | 209 | gen_le32(S, (condition_code_of_token(S, token) << 28) | opcode); |
| 210 | } | 210 | } |
| 211 | 211 | ||
| 212 | static void asm_emit_unconditional_opcode(uint32_t opcode) { | 212 | static void asm_emit_unconditional_opcode(TCCState* S, uint32_t opcode) { |
| 213 | gen_le32(opcode); | 213 | gen_le32(S, opcode); |
| 214 | } | 214 | } |
| 215 | 215 | ||
| 216 | static void asm_emit_coprocessor_opcode(uint32_t high_nibble, uint8_t cp_number, uint8_t cp_opcode, uint8_t cp_destination_register, uint8_t cp_n_operand_register, uint8_t cp_m_operand_register, uint8_t cp_opcode2, int inter_processor_transfer) | 216 | static void asm_emit_coprocessor_opcode(TCCState* S, uint32_t high_nibble, uint8_t cp_number, uint8_t cp_opcode, uint8_t cp_destination_register, uint8_t cp_n_operand_register, uint8_t cp_m_operand_register, uint8_t cp_opcode2, int inter_processor_transfer) |
| 217 | { | 217 | { |
| 218 | uint32_t opcode = 0xe000000; | 218 | uint32_t opcode = 0xe000000; |
| 219 | if (inter_processor_transfer) | 219 | if (inter_processor_transfer) |
| @@ -230,69 +230,69 @@ static void asm_emit_coprocessor_opcode(uint32_t high_nibble, uint8_t cp_number, · 10 unmodified lines | |||
| 230 | opcode |= cp_opcode2 << 5; | 230 | opcode |= cp_opcode2 << 5; |
| 231 | //assert(cp_m_operand_register < 16); | 231 | //assert(cp_m_operand_register < 16); |
| 232 | opcode |= cp_m_operand_register; | 232 | opcode |= cp_m_operand_register; |
| 233 | asm_emit_unconditional_opcode((high_nibble << 28) | opcode); | 233 | asm_emit_unconditional_opcode(S, (high_nibble << 28) | opcode); |
| 234 | } | 234 | } |
| 235 | 235 | ||
| 236 | static void asm_nullary_opcode(int token) | 236 | static void asm_nullary_opcode(TCCState* S, int token) |
| 237 | { | 237 | { |
| 238 | switch (ARM_INSTRUCTION_GROUP(token)) { | 238 | switch (ARM_INSTRUCTION_GROUP(token)) { |
| 239 | case TOK_ASM_nopeq: | 239 | case TOK_ASM_nopeq: |
| 240 | asm_emit_opcode(token, 0xd << 21); // mov r0, r0 | 240 | asm_emit_opcode(S, token, 0xd << 21); // mov r0, r0 |
| 241 | break; | 241 | break; |
| 242 | case TOK_ASM_wfeeq: | 242 | case TOK_ASM_wfeeq: |
| 243 | asm_emit_opcode(token, 0x320f002); | 243 | asm_emit_opcode(S, token, 0x320f002); |
| 244 | case TOK_ASM_wfieq: | 244 | case TOK_ASM_wfieq: |
| 245 | asm_emit_opcode(token, 0x320f003); | 245 | asm_emit_opcode(S, token, 0x320f003); |
| 246 | break; | 246 | break; |
| 247 | default: | 247 | default: |
| 248 | expect("nullary instruction"); | 248 | expect(S, "nullary instruction"); |
| 249 | } | 249 | } |
| 250 | } | 250 | } |
| 251 | 251 | ||
| 252 | static void asm_unary_opcode(TCCState *s1, int token) | 252 | static void asm_unary_opcode(TCCState *S, int token) |
| 253 | { | 253 | { |
| 254 | Operand op; | 254 | Operand op; |
| 255 | parse_operand(s1, &op); | 255 | parse_operand(S, &op); |
| 256 | 256 | ||
| 257 | switch (ARM_INSTRUCTION_GROUP(token)) { | 257 | switch (ARM_INSTRUCTION_GROUP(token)) { |
| 258 | case TOK_ASM_swieq: | 258 | case TOK_ASM_swieq: |
| 259 | case TOK_ASM_svceq: | 259 | case TOK_ASM_svceq: |
| 260 | if (op.type != OP_IM8) | 260 | if (op.type != OP_IM8) |
| 261 | expect("immediate 8-bit unsigned integer"); | 261 | expect(S, "immediate 8-bit unsigned integer"); |
| 262 | else { | 262 | else { |
| 263 | /* Note: Dummy operand (ignored by processor): ARM ref documented 0...255, ARM instruction set documented 24 bit */ | 263 | /* Note: Dummy operand (ignored by processor): ARM ref documented 0...255, ARM instruction set documented 24 bit */ |
| 264 | asm_emit_opcode(token, (0xf << 24) | op.e.v); | 264 | asm_emit_opcode(S, token, (0xf << 24) | op.e.v); |
| 265 | } | 265 | } |
| 266 | break; | 266 | break; |
| 267 | default: | 267 | default: |
| 268 | expect("unary instruction"); | 268 | expect(S, "unary instruction"); |
| 269 | } | 269 | } |
| 270 | } | 270 | } |
| 271 | 271 | ||
| 272 | static void asm_binary_opcode(TCCState *s1, int token) | 272 | static void asm_binary_opcode(TCCState *S, int token) |
| 273 | { | 273 | { |
| 274 | Operand ops[2]; | 274 | Operand ops[2]; |
| 275 | Operand rotation; | 275 | Operand rotation; |
| 276 | uint32_t encoded_rotation = 0; | 276 | uint32_t encoded_rotation = 0; |
| 277 | uint64_t amount; | 277 | uint64_t amount; |
| 278 | parse_operand(s1, &ops[0]); | 278 | parse_operand(S, &ops[0]); |
| 279 | if (tok == ',') | 279 | if (S->tccpp_tok == ',') |
| 280 | next(); | 280 | next(S); |
| 281 | else | 281 | else |
| 282 | expect("','"); | 282 | expect(S, "','"); |
| 283 | parse_operand(s1, &ops[1]); | 283 | parse_operand(S, &ops[1]); |
| 284 | if (ops[0].type != OP_REG32) { | 284 | if (ops[0].type != OP_REG32) { |
| 285 | expect("(destination operand) register"); | 285 | expect(S, "(destination operand) register"); |
| 286 | return; | 286 | return; |
| 287 | } | 287 | } |
| 288 | 288 | ||
| 289 | if (ops[0].reg == 15) { | 289 | if (ops[0].reg == 15) { |
| 290 | tcc_error("'%s' does not support 'pc' as operand", get_tok_str(token, NULL)); | 290 | tcc_error(S, "'%s' does not support 'pc' as operand", get_tok_str(S, token, NULL)); |
| 291 | return; | 291 | return; |
| 292 | } | 292 | } |
| 293 | 293 | ||
| 294 | if (ops[0].reg == 13) | 294 | if (ops[0].reg == 13) |
| 295 | tcc_warning("Using 'sp' as operand with '%s' is deprecated by ARM", get_tok_str(token, NULL)); | 295 | tcc_warning(S, "Using 'sp' as operand with '%s' is deprecated by ARM", get_tok_str(S, token, NULL)); |
| 296 | 296 | ||
| 297 | if (ops[1].type != OP_REG32) { | 297 | if (ops[1].type != OP_REG32) { |
| 298 | switch (ARM_INSTRUCTION_GROUP(token)) { | 298 | switch (ARM_INSTRUCTION_GROUP(token)) { |
| @@ -303,38 +303,38 @@ static void asm_binary_opcode(TCCState *s1, int token) · 4 unmodified lines | |||
| 303 | uint16_t immediate_value = ops[1].e.v; | 303 | uint16_t immediate_value = ops[1].e.v; |
| 304 | switch (ARM_INSTRUCTION_GROUP(token)) { | 304 | switch (ARM_INSTRUCTION_GROUP(token)) { |
| 305 | case TOK_ASM_movteq: | 305 | case TOK_ASM_movteq: |
| 306 | asm_emit_opcode(token, 0x3400000 | (ops[0].reg << 12) | (immediate_value & 0xF000) << 4 | (immediate_value & 0xFFF)); | 306 | asm_emit_opcode(S, token, 0x3400000 | (ops[0].reg << 12) | (immediate_value & 0xF000) << 4 | (immediate_value & 0xFFF)); |
| 307 | break; | 307 | break; |
| 308 | case TOK_ASM_movweq: | 308 | case TOK_ASM_movweq: |
| 309 | asm_emit_opcode(token, 0x3000000 | (ops[0].reg << 12) | (immediate_value & 0xF000) << 4 | (immediate_value & 0xFFF)); | 309 | asm_emit_opcode(S, token, 0x3000000 | (ops[0].reg << 12) | (immediate_value & 0xF000) << 4 | (immediate_value & 0xFFF)); |
| 310 | break; | 310 | break; |
| 311 | } | 311 | } |
| 312 | } else | 312 | } else |
| 313 | expect("(source operand) immediate 16 bit value"); | 313 | expect(S, "(source operand) immediate 16 bit value"); |
| 314 | } else | 314 | } else |
| 315 | expect("(source operand) immediate"); | 315 | expect(S, "(source operand) immediate"); |
| 316 | break; | 316 | break; |
| 317 | default: | 317 | default: |
| 318 | expect("(source operand) register"); | 318 | expect(S, "(source operand) register"); |
| 319 | } | 319 | } |
| 320 | return; | 320 | return; |
| 321 | } | 321 | } |
| 322 | 322 | ||
| 323 | if (ops[1].reg == 15) { | 323 | if (ops[1].reg == 15) { |
| 324 | tcc_error("'%s' does not support 'pc' as operand", get_tok_str(token, NULL)); | 324 | tcc_error(S, "'%s' does not support 'pc' as operand", get_tok_str(S, token, NULL)); |
| 325 | return; | 325 | return; |
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | if (ops[1].reg == 13) | 328 | if (ops[1].reg == 13) |
| 329 | tcc_warning("Using 'sp' as operand with '%s' is deprecated by ARM", get_tok_str(token, NULL)); | 329 | tcc_warning(S, "Using 'sp' as operand with '%s' is deprecated by ARM", get_tok_str(S, token, NULL)); |
| 330 | 330 | ||
| 331 | if (tok == ',') { | 331 | if (S->tccpp_tok == ',') { |
| 332 | next(); // skip ',' | 332 | next(S); // skip ',' |
| 333 | if (tok == TOK_ASM_ror) { | 333 | if (S->tccpp_tok == TOK_ASM_ror) { |
| 334 | next(); // skip 'ror' | 334 | next(S); // skip 'ror' |
| 335 | parse_operand(s1, &rotation); | 335 | parse_operand(S, &rotation); |
| 336 | if (rotation.type != OP_IM8) { | 336 | if (rotation.type != OP_IM8) { |
| 337 | expect("immediate value for rotation"); | 337 | expect(S, "immediate value for rotation"); |
| 338 | return; | 338 | return; |
| 339 | } else { | 339 | } else { |
| 340 | amount = rotation.e.v; | 340 | amount = rotation.e.v; |
| @@ -349,7 +349,7 @@ static void asm_binary_opcode(TCCState *s1, int token) · 8 unmodified lines | |||
| 349 | encoded_rotation = 3 << 10; | 349 | encoded_rotation = 3 << 10; |
| 350 | break; | 350 | break; |
| 351 | default: | 351 | default: |
| 352 | expect("'8' or '16' or '24'"); | 352 | expect(S, "'8' or '16' or '24'"); |
| 353 | return; | 353 | return; |
| 354 | } | 354 | } |
| 355 | } | 355 | } |
| @@ -358,27 +358,27 @@ static void asm_binary_opcode(TCCState *s1, int token) · 2 unmodified lines | |||
| 358 | switch (ARM_INSTRUCTION_GROUP(token)) { | 358 | switch (ARM_INSTRUCTION_GROUP(token)) { |
| 359 | case TOK_ASM_clzeq: | 359 | case TOK_ASM_clzeq: |
| 360 | if (encoded_rotation) | 360 | if (encoded_rotation) |
| 361 | tcc_error("clz does not support rotation"); | 361 | tcc_error(S, "clz does not support rotation"); |
| 362 | asm_emit_opcode(token, 0x16f0f10 | (ops[0].reg << 12) | ops[1].reg); | 362 | asm_emit_opcode(S, token, 0x16f0f10 | (ops[0].reg << 12) | ops[1].reg); |
| 363 | break; | 363 | break; |
| 364 | case TOK_ASM_sxtbeq: | 364 | case TOK_ASM_sxtbeq: |
| 365 | asm_emit_opcode(token, 0x6af0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation); | 365 | asm_emit_opcode(S, token, 0x6af0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation); |
| 366 | break; | 366 | break; |
| 367 | case TOK_ASM_sxtheq: | 367 | case TOK_ASM_sxtheq: |
| 368 | asm_emit_opcode(token, 0x6bf0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation); | 368 | asm_emit_opcode(S, token, 0x6bf0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation); |
| 369 | break; | 369 | break; |
| 370 | case TOK_ASM_uxtbeq: | 370 | case TOK_ASM_uxtbeq: |
| 371 | asm_emit_opcode(token, 0x6ef0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation); | 371 | asm_emit_opcode(S, token, 0x6ef0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation); |
| 372 | break; | 372 | break; |
| 373 | case TOK_ASM_uxtheq: | 373 | case TOK_ASM_uxtheq: |
| 374 | asm_emit_opcode(token, 0x6ff0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation); | 374 | asm_emit_opcode(S, token, 0x6ff0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation); |
| 375 | break; | 375 | break; |
| 376 | default: | 376 | default: |
| 377 | expect("binary instruction"); | 377 | expect(S, "binary instruction"); |
| 378 | } | 378 | } |
| 379 | } | 379 | } |
| 380 | 380 | ||
| 381 | static void asm_coprocessor_opcode(TCCState *s1, int token) { | 381 | static void asm_coprocessor_opcode(TCCState *S, int token) { |
| 382 | uint8_t coprocessor; | 382 | uint8_t coprocessor; |
| 383 | Operand opcode1; | 383 | Operand opcode1; |
| 384 | Operand opcode2; | 384 | Operand opcode2; |
| @@ -387,70 +387,70 @@ static void asm_coprocessor_opcode(TCCState *s1, int token) { · 2 unmodified lines | |||
| 387 | uint8_t high_nibble; | 387 | uint8_t high_nibble; |
| 388 | uint8_t mrc = 0; | 388 | uint8_t mrc = 0; |
| 389 | 389 | ||
| 390 | if (tok >= TOK_ASM_p0 && tok <= TOK_ASM_p15) { | 390 | if (S->tccpp_tok >= TOK_ASM_p0 && S->tccpp_tok <= TOK_ASM_p15) { |
| 391 | coprocessor = tok - TOK_ASM_p0; | 391 | coprocessor = S->tccpp_tok - TOK_ASM_p0; |
| 392 | next(); | 392 | next(S); |
| 393 | } else { | 393 | } else { |
| 394 | expect("'p<number>'"); | 394 | expect(S, "'p<number>'"); |
| 395 | return; | 395 | return; |
| 396 | } | 396 | } |
| 397 | 397 | ||
| 398 | if (tok == ',') | 398 | if (S->tccpp_tok == ',') |
| 399 | next(); | 399 | next(S); |
| 400 | else | 400 | else |
| 401 | expect("','"); | 401 | expect(S, "','"); |
| 402 | 402 | ||
| 403 | parse_operand(s1, &opcode1); | 403 | parse_operand(S, &opcode1); |
| 404 | if (opcode1.type != OP_IM8 || opcode1.e.v > 15) { | 404 | if (opcode1.type != OP_IM8 || opcode1.e.v > 15) { |
| 405 | tcc_error("opcode1 of instruction '%s' must be an immediate value between 0 and 15", get_tok_str(token, NULL)); | 405 | tcc_error(S, "opcode1 of instruction '%s' must be an immediate value between 0 and 15", get_tok_str(S, token, NULL)); |
| 406 | return; | 406 | return; |
| 407 | } | 407 | } |
| 408 | 408 | ||
| 409 | for (i = 0; i < 3; ++i) { | 409 | for (i = 0; i < 3; ++i) { |
| 410 | if (tok == ',') | 410 | if (S->tccpp_tok == ',') |
| 411 | next(); | 411 | next(S); |
| 412 | else | 412 | else |
| 413 | expect("','"); | 413 | expect(S, "','"); |
| 414 | if (i == 0 && token != TOK_ASM_cdp2 && (ARM_INSTRUCTION_GROUP(token) == TOK_ASM_mrceq || ARM_INSTRUCTION_GROUP(token) == TOK_ASM_mcreq)) { | 414 | if (i == 0 && token != TOK_ASM_cdp2 && (ARM_INSTRUCTION_GROUP(token) == TOK_ASM_mrceq || ARM_INSTRUCTION_GROUP(token) == TOK_ASM_mcreq)) { |
| 415 | if (tok >= TOK_ASM_r0 && tok <= TOK_ASM_r15) { | 415 | if (S->tccpp_tok >= TOK_ASM_r0 && S->tccpp_tok <= TOK_ASM_r15) { |
| 416 | registers[i] = tok - TOK_ASM_r0; | 416 | registers[i] = S->tccpp_tok - TOK_ASM_r0; |
| 417 | next(); | 417 | next(S); |
| 418 | } else { | 418 | } else { |
| 419 | expect("'r<number>'"); | 419 | expect(S, "'r<number>'"); |
| 420 | return; | 420 | return; |
| 421 | } | 421 | } |
| 422 | } else { | 422 | } else { |
| 423 | if (tok >= TOK_ASM_c0 && tok <= TOK_ASM_c15) { | 423 | if (S->tccpp_tok >= TOK_ASM_c0 && S->tccpp_tok <= TOK_ASM_c15) { |
| 424 | registers[i] = tok - TOK_ASM_c0; | 424 | registers[i] = S->tccpp_tok - TOK_ASM_c0; |
| 425 | next(); | 425 | next(S); |
| 426 | } else { | 426 | } else { |
| 427 | expect("'c<number>'"); | 427 | expect(S, "'c<number>'"); |
| 428 | return; | 428 | return; |
| 429 | } | 429 | } |
| 430 | } | 430 | } |
| 431 | } | 431 | } |
| 432 | if (tok == ',') { | 432 | if (S->tccpp_tok == ',') { |
| 433 | next(); | 433 | next(S); |
| 434 | parse_operand(s1, &opcode2); | 434 | parse_operand(S, &opcode2); |
| 435 | } else { | 435 | } else { |
| 436 | opcode2.type = OP_IM8; | 436 | opcode2.type = OP_IM8; |
| 437 | opcode2.e.v = 0; | 437 | opcode2.e.v = 0; |
| 438 | } | 438 | } |
| 439 | if (opcode2.type != OP_IM8 || opcode2.e.v > 15) { | 439 | if (opcode2.type != OP_IM8 || opcode2.e.v > 15) { |
| 440 | tcc_error("opcode2 of instruction '%s' must be an immediate value between 0 and 15", get_tok_str(token, NULL)); | 440 | tcc_error(S, "opcode2 of instruction '%s' must be an immediate value between 0 and 15", get_tok_str(S, token, NULL)); |
| 441 | return; | 441 | return; |
| 442 | } | 442 | } |
| 443 | 443 | ||
| 444 | if (token == TOK_ASM_cdp2) { | 444 | if (token == TOK_ASM_cdp2) { |
| 445 | high_nibble = 0xF; | 445 | high_nibble = 0xF; |
| 446 | asm_emit_coprocessor_opcode(high_nibble, coprocessor, opcode1.e.v, registers[0], registers[1], registers[2], opcode2.e.v, 0); | 446 | asm_emit_coprocessor_opcode(S, high_nibble, coprocessor, opcode1.e.v, registers[0], registers[1], registers[2], opcode2.e.v, 0); |
| 447 | return; | 447 | return; |
| 448 | } else | 448 | } else |
| 449 | high_nibble = condition_code_of_token(token); | 449 | high_nibble = condition_code_of_token(S, token); |
| 450 | 450 | ||
| 451 | switch (ARM_INSTRUCTION_GROUP(token)) { | 451 | switch (ARM_INSTRUCTION_GROUP(token)) { |
| 452 | case TOK_ASM_cdpeq: | 452 | case TOK_ASM_cdpeq: |
| 453 | asm_emit_coprocessor_opcode(high_nibble, coprocessor, opcode1.e.v, registers[0], registers[1], registers[2], opcode2.e.v, 0); | 453 | asm_emit_coprocessor_opcode(S, high_nibble, coprocessor, opcode1.e.v, registers[0], registers[1], registers[2], opcode2.e.v, 0); |
| 454 | break; | 454 | break; |
| 455 | case TOK_ASM_mrceq: | 455 | case TOK_ASM_mrceq: |
| 456 | // opcode1 encoding changes! highest and lowest bit gone. | 456 | // opcode1 encoding changes! highest and lowest bit gone. |
| @@ -459,13 +459,13 @@ static void asm_coprocessor_opcode(TCCState *s1, int token) { · 2 unmodified lines | |||
| 459 | case TOK_ASM_mcreq: | 459 | case TOK_ASM_mcreq: |
| 460 | // opcode1 encoding changes! highest and lowest bit gone. | 460 | // opcode1 encoding changes! highest and lowest bit gone. |
| 461 | if (opcode1.e.v > 7) { | 461 | if (opcode1.e.v > 7) { |
| 462 | tcc_error("opcode1 of instruction '%s' must be an immediate value between 0 and 7", get_tok_str(token, NULL)); | 462 | tcc_error(S, "opcode1 of instruction '%s' must be an immediate value between 0 and 7", get_tok_str(S, token, NULL)); |
| 463 | return; | 463 | return; |
| 464 | } | 464 | } |
| 465 | asm_emit_coprocessor_opcode(high_nibble, coprocessor, (opcode1.e.v << 1) | mrc, registers[0], registers[1], registers[2], opcode2.e.v, 1); | 465 | asm_emit_coprocessor_opcode(S, high_nibble, coprocessor, (opcode1.e.v << 1) | mrc, registers[0], registers[1], registers[2], opcode2.e.v, 1); |
| 466 | break; | 466 | break; |
| 467 | default: | 467 | default: |
| 468 | expect("known instruction"); | 468 | expect(S, "known instruction"); |
| 469 | } | 469 | } |
| 470 | } | 470 | } |
| 471 | 471 | ||
| @@ -486,27 +486,27 @@ static void asm_coprocessor_opcode(TCCState *s1, int token) { · 14 unmodified lines | |||
| 486 | #define ENCODE_BARREL_SHIFTER_REGISTER(register_index) ((register_index) << 8) | 486 | #define ENCODE_BARREL_SHIFTER_REGISTER(register_index) ((register_index) << 8) |
| 487 | #define ENCODE_BARREL_SHIFTER_IMMEDIATE(value) ((value) << 7) | 487 | #define ENCODE_BARREL_SHIFTER_IMMEDIATE(value) ((value) << 7) |
| 488 | 488 | ||
| 489 | static void asm_block_data_transfer_opcode(TCCState *s1, int token) | 489 | static void asm_block_data_transfer_opcode(TCCState *S, int token) |
| 490 | { | 490 | { |
| 491 | uint32_t opcode; | 491 | uint32_t opcode; |
| 492 | int op0_exclam = 0; | 492 | int op0_exclam = 0; |
| 493 | Operand ops[2]; | 493 | Operand ops[2]; |
| 494 | int nb_ops = 1; | 494 | int nb_ops = 1; |
| 495 | parse_operand(s1, &ops[0]); | 495 | parse_operand(S, &ops[0]); |
| 496 | if (tok == '!') { | 496 | if (S->tccpp_tok == '!') { |
| 497 | op0_exclam = 1; | 497 | op0_exclam = 1; |
| 498 | next(); // skip '!' | 498 | next(S); // skip '!' |
| 499 | } | 499 | } |
| 500 | if (tok == ',') { | 500 | if (S->tccpp_tok == ',') { |
| 501 | next(); // skip comma | 501 | next(S); // skip comma |
| 502 | parse_operand(s1, &ops[1]); | 502 | parse_operand(S, &ops[1]); |
| 503 | ++nb_ops; | 503 | ++nb_ops; |
| 504 | } | 504 | } |
| 505 | if (nb_ops < 1) { | 505 | if (nb_ops < 1) { |
| 506 | expect("at least one operand"); | 506 | expect(S, "at least one operand"); |
| 507 | return; | 507 | return; |
| 508 | } else if (ops[nb_ops - 1].type != OP_REGSET32) { | 508 | } else if (ops[nb_ops - 1].type != OP_REGSET32) { |
| 509 | expect("(last operand) register list"); | 509 | expect(S, "(last operand) register list"); |
| 510 | return; | 510 | return; |
| 511 | } | 511 | } |
| 512 | 512 | ||
| @@ -522,9 +522,9 @@ static void asm_block_data_transfer_opcode(TCCState *s1, int token) · 9 unmodified lines | |||
| 522 | // Rn: base register | 522 | // Rn: base register |
| 523 | // Register List: bits 15...0 | 523 | // Register List: bits 15...0 |
| 524 | if (nb_ops != 1) | 524 | if (nb_ops != 1) |
| 525 | expect("exactly one operand"); | 525 | expect(S, "exactly one operand"); |
| 526 | else | 526 | else |
| 527 | asm_emit_opcode(token, (0x92d << 16) | ops[0].regset); // TODO: base register ? | 527 | asm_emit_opcode(S, token, (0x92d << 16) | ops[0].regset); // TODO: base register ? |
| 528 | break; | 528 | break; |
| 529 | case TOK_ASM_popeq: // TODO: Optimize 1-register case to: ldr ?, [sp], #4 | 529 | case TOK_ASM_popeq: // TODO: Optimize 1-register case to: ldr ?, [sp], #4 |
| 530 | // Instruction: 1 I=0 P=0 U=1 S=0 W=0 L=1 << 20, op 1101 | 530 | // Instruction: 1 I=0 P=0 U=1 S=0 W=0 L=1 << 20, op 1101 |
| @@ -532,9 +532,9 @@ static void asm_block_data_transfer_opcode(TCCState *s1, int token) · 1 unmodified line | |||
| 532 | // Rn: base register | 532 | // Rn: base register |
| 533 | // Register List: bits 15...0 | 533 | // Register List: bits 15...0 |
| 534 | if (nb_ops != 1) | 534 | if (nb_ops != 1) |
| 535 | expect("exactly one operand"); | 535 | expect(S, "exactly one operand"); |
| 536 | else | 536 | else |
| 537 | asm_emit_opcode(token, (0x8bd << 16) | ops[0].regset); // TODO: base register ? | 537 | asm_emit_opcode(S, token, (0x8bd << 16) | ops[0].regset); // TODO: base register ? |
| 538 | break; | 538 | break; |
| 539 | case TOK_ASM_stmdaeq: | 539 | case TOK_ASM_stmdaeq: |
| 540 | case TOK_ASM_ldmdaeq: | 540 | case TOK_ASM_ldmdaeq: |
| @@ -574,23 +574,23 @@ static void asm_block_data_transfer_opcode(TCCState *s1, int token) · 33 unmodified lines | |||
| 574 | opcode = 0x99 << 20; | 574 | opcode = 0x99 << 20; |
| 575 | break; | 575 | break; |
| 576 | default: | 576 | default: |
| 577 | tcc_error("internal error: This place should not be reached (fallback in asm_block_data_transfer_opcode)"); | 577 | tcc_error(S, "internal error: This place should not be reached (fallback in asm_block_data_transfer_opcode)"); |
| 578 | } | 578 | } |
| 579 | // operands: | 579 | // operands: |
| 580 | // Rn: first operand | 580 | // Rn: first operand |
| 581 | // Register List: lower bits | 581 | // Register List: lower bits |
| 582 | if (nb_ops != 2) | 582 | if (nb_ops != 2) |
| 583 | expect("exactly two operands"); | 583 | expect(S, "exactly two operands"); |
| 584 | else if (ops[0].type != OP_REG32) | 584 | else if (ops[0].type != OP_REG32) |
| 585 | expect("(first operand) register"); | 585 | expect(S, "(first operand) register"); |
| 586 | else { | 586 | else { |
| 587 | if (op0_exclam) | 587 | if (op0_exclam) |
| 588 | opcode |= 1 << 21; // writeback | 588 | opcode |= 1 << 21; // writeback |
| 589 | asm_emit_opcode(token, opcode | ENCODE_RN(ops[0].reg) | ops[1].regset); | 589 | asm_emit_opcode(S, token, opcode | ENCODE_RN(ops[0].reg) | ops[1].regset); |
| 590 | } | 590 | } |
| 591 | break; | 591 | break; |
| 592 | default: | 592 | default: |
| 593 | expect("block data transfer instruction"); | 593 | expect(S, "block data transfer instruction"); |
| 594 | } | 594 | } |
| 595 | } | 595 | } |
| 596 | 596 | ||
| @@ -600,17 +600,17 @@ static void asm_block_data_transfer_opcode(TCCState *s1, int token) · 3 unmodified lines | |||
| 600 | 600 | ||
| 601 | NB_SHIFT: will be set to 1 iff SHIFT is filled. Note that for rrx, there's no need to fill SHIFT. | 601 | NB_SHIFT: will be set to 1 iff SHIFT is filled. Note that for rrx, there's no need to fill SHIFT. |
| 602 | SHIFT: will be filled in with the shift operand to use, if any. */ | 602 | SHIFT: will be filled in with the shift operand to use, if any. */ |
| 603 | static uint32_t asm_parse_optional_shift(TCCState* s1, int* nb_shift, Operand* shift) | 603 | static uint32_t asm_parse_optional_shift(TCCState* S, int* nb_shift, Operand* shift) |
| 604 | { | 604 | { |
| 605 | uint32_t opcode = 0; | 605 | uint32_t opcode = 0; |
| 606 | *nb_shift = 0; | 606 | *nb_shift = 0; |
| 607 | switch (tok) { | 607 | switch (S->tccpp_tok) { |
| 608 | case TOK_ASM_asl: | 608 | case TOK_ASM_asl: |
| 609 | case TOK_ASM_lsl: | 609 | case TOK_ASM_lsl: |
| 610 | case TOK_ASM_asr: | 610 | case TOK_ASM_asr: |
| 611 | case TOK_ASM_lsr: | 611 | case TOK_ASM_lsr: |
| 612 | case TOK_ASM_ror: | 612 | case TOK_ASM_ror: |
| 613 | switch (tok) { | 613 | switch (S->tccpp_tok) { |
| 614 | case TOK_ASM_asl: | 614 | case TOK_ASM_asl: |
| 615 | /* fallthrough */ | 615 | /* fallthrough */ |
| 616 | case TOK_ASM_lsl: | 616 | case TOK_ASM_lsl: |
| @@ -626,26 +626,26 @@ static uint32_t asm_parse_optional_shift(TCCState* s1, int* nb_shift, Operand* s · 9 unmodified lines | |||
| 626 | opcode = ENCODE_BARREL_SHIFTER_MODE_ROR; | 626 | opcode = ENCODE_BARREL_SHIFTER_MODE_ROR; |
| 627 | break; | 627 | break; |
| 628 | } | 628 | } |
| 629 | next(); | 629 | next(S); |
| 630 | parse_operand(s1, shift); | 630 | parse_operand(S, shift); |
| 631 | *nb_shift = 1; | 631 | *nb_shift = 1; |
| 632 | break; | 632 | break; |
| 633 | case TOK_ASM_rrx: | 633 | case TOK_ASM_rrx: |
| 634 | next(); | 634 | next(S); |
| 635 | opcode = ENCODE_BARREL_SHIFTER_MODE_ROR; | 635 | opcode = ENCODE_BARREL_SHIFTER_MODE_ROR; |
| 636 | break; | 636 | break; |
| 637 | } | 637 | } |
| 638 | return opcode; | 638 | return opcode; |
| 639 | } | 639 | } |
| 640 | 640 | ||
| 641 | static uint32_t asm_encode_shift(Operand* shift) | 641 | static uint32_t asm_encode_shift(TCCState *S, Operand* shift) |
| 642 | { | 642 | { |
| 643 | uint64_t amount; | 643 | uint64_t amount; |
| 644 | uint32_t operands = 0; | 644 | uint32_t operands = 0; |
| 645 | switch (shift->type) { | 645 | switch (shift->type) { |
| 646 | case OP_REG32: | 646 | case OP_REG32: |
| 647 | if (shift->reg == 15) | 647 | if (shift->reg == 15) |
| 648 | tcc_error("r15 cannot be used as a shift count"); | 648 | tcc_error(S, "r15 cannot be used as a shift count"); |
| 649 | else { | 649 | else { |
| 650 | operands = ENCODE_BARREL_SHIFTER_SHIFT_BY_REGISTER; | 650 | operands = ENCODE_BARREL_SHIFTER_SHIFT_BY_REGISTER; |
| 651 | operands |= ENCODE_BARREL_SHIFTER_REGISTER(shift->reg); | 651 | operands |= ENCODE_BARREL_SHIFTER_REGISTER(shift->reg); |
| @@ -656,15 +656,15 @@ static uint32_t asm_encode_shift(Operand* shift) · 4 unmodified lines | |||
| 656 | if (amount > 0 && amount < 32) | 656 | if (amount > 0 && amount < 32) |
| 657 | operands = ENCODE_BARREL_SHIFTER_IMMEDIATE(amount); | 657 | operands = ENCODE_BARREL_SHIFTER_IMMEDIATE(amount); |
| 658 | else | 658 | else |
| 659 | tcc_error("shift count out of range"); | 659 | tcc_error(S, "shift count out of range"); |
| 660 | break; | 660 | break; |
| 661 | default: | 661 | default: |
| 662 | tcc_error("unknown shift amount"); | 662 | tcc_error(S, "unknown shift amount"); |
| 663 | } | 663 | } |
| 664 | return operands; | 664 | return operands; |
| 665 | } | 665 | } |
| 666 | 666 | ||
| 667 | static void asm_data_processing_opcode(TCCState *s1, int token) | 667 | static void asm_data_processing_opcode(TCCState *S, int token) |
| 668 | { | 668 | { |
| 669 | Operand ops[3]; | 669 | Operand ops[3]; |
| 670 | int nb_ops; | 670 | int nb_ops; |
| @@ -677,31 +677,31 @@ static void asm_data_processing_opcode(TCCState *s1, int token) · 6 unmodified lines | |||
| 677 | uint32_t opcode_nos = opcode_idx >> 1; // without "s"; "OpCode" in ARM docs | 677 | uint32_t opcode_nos = opcode_idx >> 1; // without "s"; "OpCode" in ARM docs |
| 678 | 678 | ||
| 679 | for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ) { | 679 | for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ) { |
| 680 | if (tok == TOK_ASM_asl || tok == TOK_ASM_lsl || tok == TOK_ASM_lsr || tok == TOK_ASM_asr || tok == TOK_ASM_ror || tok == TOK_ASM_rrx) | 680 | if (S->tccpp_tok == TOK_ASM_asl || S->tccpp_tok == TOK_ASM_lsl || S->tccpp_tok == TOK_ASM_lsr || S->tccpp_tok == TOK_ASM_asr || S->tccpp_tok == TOK_ASM_ror || S->tccpp_tok == TOK_ASM_rrx) |
| 681 | break; | 681 | break; |
| 682 | parse_operand(s1, &ops[nb_ops]); | 682 | parse_operand(S, &ops[nb_ops]); |
| 683 | ++nb_ops; | 683 | ++nb_ops; |
| 684 | if (tok != ',') | 684 | if (S->tccpp_tok != ',') |
| 685 | break; | 685 | break; |
| 686 | next(); // skip ',' | 686 | next(S); // skip ',' |
| 687 | } | 687 | } |
| 688 | if (tok == ',') | 688 | if (S->tccpp_tok == ',') |
| 689 | next(); | 689 | next(S); |
| 690 | operands |= asm_parse_optional_shift(s1, &nb_shift, &shift); | 690 | operands |= asm_parse_optional_shift(S, &nb_shift, &shift); |
| 691 | if (nb_ops < 2) | 691 | if (nb_ops < 2) |
| 692 | expect("at least two operands"); | 692 | expect(S, "at least two operands"); |
| 693 | else if (nb_ops == 2) { | 693 | else if (nb_ops == 2) { |
| 694 | memcpy(&ops[2], &ops[1], sizeof(ops[1])); // move ops[2] | 694 | memcpy(&ops[2], &ops[1], sizeof(ops[1])); // move ops[2] |
| 695 | memcpy(&ops[1], &ops[0], sizeof(ops[0])); // ops[1] was implicit | 695 | memcpy(&ops[1], &ops[0], sizeof(ops[0])); // ops[1] was implicit |
| 696 | nb_ops = 3; | 696 | nb_ops = 3; |
| 697 | } else if (nb_ops == 3) { | 697 | } else if (nb_ops == 3) { |
| 698 | if (opcode_nos == 0xd || opcode_nos == 0xf || opcode_nos == 0xa || opcode_nos == 0xb || opcode_nos == 0x8 || opcode_nos == 0x9) { // mov, mvn, cmp, cmn, tst, teq | 698 | if (opcode_nos == 0xd || opcode_nos == 0xf || opcode_nos == 0xa || opcode_nos == 0xb || opcode_nos == 0x8 || opcode_nos == 0x9) { // mov, mvn, cmp, cmn, tst, teq |
| 699 | tcc_error("'%s' cannot be used with three operands", get_tok_str(token, NULL)); | 699 | tcc_error(S, "'%s' cannot be used with three operands", get_tok_str(S, token, NULL)); |
| 700 | return; | 700 | return; |
| 701 | } | 701 | } |
| 702 | } | 702 | } |
| 703 | if (nb_ops != 3) { | 703 | if (nb_ops != 3) { |
| 704 | expect("two or three operands"); | 704 | expect(S, "two or three operands"); |
| 705 | return; | 705 | return; |
| 706 | } else { | 706 | } else { |
| 707 | uint32_t opcode = 0; | 707 | uint32_t opcode = 0; |
| @@ -710,7 +710,7 @@ static void asm_data_processing_opcode(TCCState *s1, int token) · 2 unmodified lines | |||
| 710 | if (nb_shift && shift.type == OP_REG32) { | 710 | if (nb_shift && shift.type == OP_REG32) { |
| 711 | if ((ops[0].type == OP_REG32 && ops[0].reg == 15) || | 711 | if ((ops[0].type == OP_REG32 && ops[0].reg == 15) || |
| 712 | (ops[1].type == OP_REG32 && ops[1].reg == 15)) { | 712 | (ops[1].type == OP_REG32 && ops[1].reg == 15)) { |
| 713 | tcc_error("Using the 'pc' register in data processing instructions that have a register-controlled shift is not implemented by ARM"); | 713 | tcc_error(S, "Using the 'pc' register in data processing instructions that have a register-controlled shift is not implemented by ARM"); |
| 714 | return; | 714 | return; |
| 715 | } | 715 | } |
| 716 | } | 716 | } |
| @@ -726,13 +726,13 @@ static void asm_data_processing_opcode(TCCState *s1, int token) · 9 unmodified lines | |||
| 726 | /* operations in the token list are ordered by opcode */ | 726 | /* operations in the token list are ordered by opcode */ |
| 727 | opcode = opcode_nos << 21; // drop "s" | 727 | opcode = opcode_nos << 21; // drop "s" |
| 728 | if (ops[0].type != OP_REG32) | 728 | if (ops[0].type != OP_REG32) |
| 729 | expect("(destination operand) register"); | 729 | expect(S, "(destination operand) register"); |
| 730 | else if (opcode_nos == 0xa || opcode_nos == 0xb || opcode_nos == 0x8 || opcode_nos == 0x9) // cmp, cmn, tst, teq | 730 | else if (opcode_nos == 0xa || opcode_nos == 0xb || opcode_nos == 0x8 || opcode_nos == 0x9) // cmp, cmn, tst, teq |
| 731 | operands |= ENCODE_SET_CONDITION_CODES; // force S set, otherwise it's a completely different instruction. | 731 | operands |= ENCODE_SET_CONDITION_CODES; // force S set, otherwise it's a completely different instruction. |
| 732 | else | 732 | else |
| 733 | operands |= ENCODE_RD(ops[0].reg); | 733 | operands |= ENCODE_RD(ops[0].reg); |
| 734 | if (ops[1].type != OP_REG32) | 734 | if (ops[1].type != OP_REG32) |
| 735 | expect("(first source operand) register"); | 735 | expect(S, "(first source operand) register"); |
| 736 | else if (!(opcode_nos == 0xd || opcode_nos == 0xf)) // not: mov, mvn (those have only one source operand) | 736 | else if (!(opcode_nos == 0xd || opcode_nos == 0xf)) // not: mov, mvn (those have only one source operand) |
| 737 | operands |= ENCODE_RN(ops[1].reg); | 737 | operands |= ENCODE_RN(ops[1].reg); |
| 738 | switch (ops[2].type) { | 738 | switch (ops[2].type) { |
| @@ -809,7 +809,7 @@ static void asm_data_processing_opcode(TCCState *s1, int token) · 70 unmodified lines | |||
| 809 | immediate_value = ~immediate_value; | 809 | immediate_value = ~immediate_value; |
| 810 | break; | 810 | break; |
| 811 | default: | 811 | default: |
| 812 | tcc_error("cannot use '%s' with a negative immediate value", get_tok_str(token, NULL)); | 812 | tcc_error(S, "cannot use '%s' with a negative immediate value", get_tok_str(S, token, NULL)); |
| 813 | } | 813 | } |
| 814 | for (half_immediate_rotation = 0; half_immediate_rotation < 16; ++half_immediate_rotation) { | 814 | for (half_immediate_rotation = 0; half_immediate_rotation < 16; ++half_immediate_rotation) { |
| 815 | if (immediate_value >= 0x00 && immediate_value < 0x100) | 815 | if (immediate_value >= 0x00 && immediate_value < 0x100) |
| @@ -819,30 +819,30 @@ static void asm_data_processing_opcode(TCCState *s1, int token) · 3 unmodified lines | |||
| 819 | } | 819 | } |
| 820 | if (half_immediate_rotation >= 16) { | 820 | if (half_immediate_rotation >= 16) { |
| 821 | immediate_value = ops[2].e.v; | 821 | immediate_value = ops[2].e.v; |
| 822 | tcc_error("immediate value 0x%X cannot be encoded into ARM immediate", (unsigned) immediate_value); | 822 | tcc_error(S, "immediate value 0x%X cannot be encoded into ARM immediate", (unsigned) immediate_value); |
| 823 | return; | 823 | return; |
| 824 | } | 824 | } |
| 825 | operands |= immediate_value; | 825 | operands |= immediate_value; |
| 826 | operands |= half_immediate_rotation << 8; | 826 | operands |= half_immediate_rotation << 8; |
| 827 | break; | 827 | break; |
| 828 | default: | 828 | default: |
| 829 | expect("(second source operand) register or immediate value"); | 829 | expect(S, "(second source operand) register or immediate value"); |
| 830 | } | 830 | } |
| 831 | 831 | ||
| 832 | if (nb_shift) { | 832 | if (nb_shift) { |
| 833 | if (operands & ENCODE_IMMEDIATE_FLAG) | 833 | if (operands & ENCODE_IMMEDIATE_FLAG) |
| 834 | tcc_error("immediate rotation not implemented"); | 834 | tcc_error(S, "immediate rotation not implemented"); |
| 835 | else | 835 | else |
| 836 | operands |= asm_encode_shift(&shift); | 836 | operands |= asm_encode_shift(S, &shift); |
| 837 | } | 837 | } |
| 838 | 838 | ||
| 839 | /* S=0 and S=1 entries alternate one after another, in that order */ | 839 | /* S=0 and S=1 entries alternate one after another, in that order */ |
| 840 | opcode |= (opcode_idx & 1) ? ENCODE_SET_CONDITION_CODES : 0; | 840 | opcode |= (opcode_idx & 1) ? ENCODE_SET_CONDITION_CODES : 0; |
| 841 | asm_emit_opcode(token, opcode | operands); | 841 | asm_emit_opcode(S, token, opcode | operands); |
| 842 | } | 842 | } |
| 843 | } | 843 | } |
| 844 | 844 | ||
| 845 | static void asm_shift_opcode(TCCState *s1, int token) | 845 | static void asm_shift_opcode(TCCState *S, int token) |
| 846 | { | 846 | { |
| 847 | Operand ops[3]; | 847 | Operand ops[3]; |
| 848 | int nb_ops; | 848 | int nb_ops; |
| @@ -851,20 +851,20 @@ static void asm_shift_opcode(TCCState *s1, int token) · 2 unmodified lines | |||
| 851 | uint32_t operands = 0; | 851 | uint32_t operands = 0; |
| 852 | 852 | ||
| 853 | for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) { | 853 | for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) { |
| 854 | parse_operand(s1, &ops[nb_ops]); | 854 | parse_operand(S, &ops[nb_ops]); |
| 855 | if (tok != ',') { | 855 | if (S->tccpp_tok != ',') { |
| 856 | ++nb_ops; | 856 | ++nb_ops; |
| 857 | break; | 857 | break; |
| 858 | } | 858 | } |
| 859 | next(); // skip ',' | 859 | next(S); // skip ',' |
| 860 | } | 860 | } |
| 861 | if (nb_ops < 2) { | 861 | if (nb_ops < 2) { |
| 862 | expect("at least two operands"); | 862 | expect(S, "at least two operands"); |
| 863 | return; | 863 | return; |
| 864 | } | 864 | } |
| 865 | 865 | ||
| 866 | if (ops[0].type != OP_REG32) { | 866 | if (ops[0].type != OP_REG32) { |
| 867 | expect("(destination operand) register"); | 867 | expect(S, "(destination operand) register"); |
| 868 | return; | 868 | return; |
| 869 | } else | 869 | } else |
| 870 | operands |= ENCODE_RD(ops[0].reg); | 870 | operands |= ENCODE_RD(ops[0].reg); |
| @@ -878,9 +878,9 @@ static void asm_shift_opcode(TCCState *s1, int token) · 7 unmodified lines | |||
| 878 | if (ops[1].type == OP_REG32) { | 878 | if (ops[1].type == OP_REG32) { |
| 879 | operands |= ops[1].reg; | 879 | operands |= ops[1].reg; |
| 880 | operands |= ENCODE_BARREL_SHIFTER_MODE_ROR; | 880 | operands |= ENCODE_BARREL_SHIFTER_MODE_ROR; |
| 881 | asm_emit_opcode(token, opcode | operands); | 881 | asm_emit_opcode(S, token, opcode | operands); |
| 882 | } else | 882 | } else |
| 883 | tcc_error("(first source operand) register"); | 883 | tcc_error(S, "(first source operand) register"); |
| 884 | return; | 884 | return; |
| 885 | default: | 885 | default: |
| 886 | memcpy(&ops[2], &ops[1], sizeof(ops[1])); // move ops[2] | 886 | memcpy(&ops[2], &ops[1], sizeof(ops[1])); // move ops[2] |
| @@ -889,7 +889,7 @@ static void asm_shift_opcode(TCCState *s1, int token) · 2 unmodified lines | |||
| 889 | } | 889 | } |
| 890 | } | 890 | } |
| 891 | if (nb_ops != 3) { | 891 | if (nb_ops != 3) { |
| 892 | expect("two or three operands"); | 892 | expect(S, "two or three operands"); |
| 893 | return; | 893 | return; |
| 894 | } | 894 | } |
| 895 | 895 | ||
| @@ -909,7 +909,7 @@ static void asm_shift_opcode(TCCState *s1, int token) · 13 unmodified lines | |||
| 909 | case OP_IM8: | 909 | case OP_IM8: |
| 910 | operands |= ENCODE_IMMEDIATE_FLAG; | 910 | operands |= ENCODE_IMMEDIATE_FLAG; |
| 911 | operands |= ops[1].e.v; | 911 | operands |= ops[1].e.v; |
| 912 | tcc_error("Using an immediate value as the source operand is not possible with '%s' instruction on ARM", get_tok_str(token, NULL)); | 912 | tcc_error(S, "Using an immediate value as the source operand is not possible with '%s' instruction on ARM", get_tok_str(S, token, NULL)); |
| 913 | return; | 913 | return; |
| 914 | } | 914 | } |
| 915 | 915 | ||
| @@ -917,13 +917,13 @@ static void asm_shift_opcode(TCCState *s1, int token) · 1 unmodified line | |||
| 917 | case OP_REG32: | 917 | case OP_REG32: |
| 918 | if ((ops[0].type == OP_REG32 && ops[0].reg == 15) || | 918 | if ((ops[0].type == OP_REG32 && ops[0].reg == 15) || |
| 919 | (ops[1].type == OP_REG32 && ops[1].reg == 15)) { | 919 | (ops[1].type == OP_REG32 && ops[1].reg == 15)) { |
| 920 | tcc_error("Using the 'pc' register in data processing instructions that have a register-controlled shift is not implemented by ARM"); | 920 | tcc_error(S, "Using the 'pc' register in data processing instructions that have a register-controlled shift is not implemented by ARM"); |
| 921 | } | 921 | } |
| 922 | operands |= asm_encode_shift(&ops[2]); | 922 | operands |= asm_encode_shift(S, &ops[2]); |
| 923 | break; | 923 | break; |
| 924 | case OP_IM8: | 924 | case OP_IM8: |
| 925 | if (ops[2].e.v) | 925 | if (ops[2].e.v) |
| 926 | operands |= asm_encode_shift(&ops[2]); | 926 | operands |= asm_encode_shift(S, &ops[2]); |
| 927 | else | 927 | else |
| 928 | definitely_neutral = 1; | 928 | definitely_neutral = 1; |
| 929 | break; | 929 | break; |
| @@ -947,28 +947,28 @@ static void asm_shift_opcode(TCCState *s1, int token) · 17 unmodified lines | |||
| 947 | operands |= ENCODE_BARREL_SHIFTER_MODE_ROR; | 947 | operands |= ENCODE_BARREL_SHIFTER_MODE_ROR; |
| 948 | break; | 948 | break; |
| 949 | default: | 949 | default: |
| 950 | expect("shift instruction"); | 950 | expect(S, "shift instruction"); |
| 951 | return; | 951 | return; |
| 952 | } | 952 | } |
| 953 | asm_emit_opcode(token, opcode | operands); | 953 | asm_emit_opcode(S, token, opcode | operands); |
| 954 | } | 954 | } |
| 955 | 955 | ||
| 956 | static void asm_multiplication_opcode(TCCState *s1, int token) | 956 | static void asm_multiplication_opcode(TCCState *S, int token) |
| 957 | { | 957 | { |
| 958 | Operand ops[4]; | 958 | Operand ops[4]; |
| 959 | int nb_ops = 0; | 959 | int nb_ops = 0; |
| 960 | uint32_t opcode = 0x90; | 960 | uint32_t opcode = 0x90; |
| 961 | 961 | ||
| 962 | for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) { | 962 | for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) { |
| 963 | parse_operand(s1, &ops[nb_ops]); | 963 | parse_operand(S, &ops[nb_ops]); |
| 964 | if (tok != ',') { | 964 | if (S->tccpp_tok != ',') { |
| 965 | ++nb_ops; | 965 | ++nb_ops; |
| 966 | break; | 966 | break; |
| 967 | } | 967 | } |
| 968 | next(); // skip ',' | 968 | next(S); // skip ',' |
| 969 | } | 969 | } |
| 970 | if (nb_ops < 2) | 970 | if (nb_ops < 2) |
| 971 | expect("at least two operands"); | 971 | expect(S, "at least two operands"); |
| 972 | else if (nb_ops == 2) { | 972 | else if (nb_ops == 2) { |
| 973 | switch (ARM_INSTRUCTION_GROUP(token)) { | 973 | switch (ARM_INSTRUCTION_GROUP(token)) { |
| 974 | case TOK_ASM_mulseq: | 974 | case TOK_ASM_mulseq: |
| @@ -976,7 +976,7 @@ static void asm_multiplication_opcode(TCCState *s1, int token) · 1 unmodified line | |||
| 976 | memcpy(&ops[2], &ops[0], sizeof(ops[1])); // ARM is actually like this! | 976 | memcpy(&ops[2], &ops[0], sizeof(ops[1])); // ARM is actually like this! |
| 977 | break; | 977 | break; |
| 978 | default: | 978 | default: |
| 979 | expect("at least three operands"); | 979 | expect(S, "at least three operands"); |
| 980 | return; | 980 | return; |
| 981 | } | 981 | } |
| 982 | nb_ops = 3; | 982 | nb_ops = 3; |
| @@ -992,20 +992,20 @@ static void asm_multiplication_opcode(TCCState *s1, int token) · 9 unmodified lines | |||
| 992 | if (ops[0].type == OP_REG32) | 992 | if (ops[0].type == OP_REG32) |
| 993 | opcode |= ops[0].reg << 16; | 993 | opcode |= ops[0].reg << 16; |
| 994 | else | 994 | else |
| 995 | expect("(destination operand) register"); | 995 | expect(S, "(destination operand) register"); |
| 996 | if (ops[1].type == OP_REG32) | 996 | if (ops[1].type == OP_REG32) |
| 997 | opcode |= ops[1].reg; | 997 | opcode |= ops[1].reg; |
| 998 | else | 998 | else |
| 999 | expect("(first source operand) register"); | 999 | expect(S, "(first source operand) register"); |
| 1000 | if (ops[2].type == OP_REG32) | 1000 | if (ops[2].type == OP_REG32) |
| 1001 | opcode |= ops[2].reg << 8; | 1001 | opcode |= ops[2].reg << 8; |
| 1002 | else | 1002 | else |
| 1003 | expect("(second source operand) register"); | 1003 | expect(S, "(second source operand) register"); |
| 1004 | if (nb_ops > 3) { | 1004 | if (nb_ops > 3) { |
| 1005 | if (ops[3].type == OP_REG32) | 1005 | if (ops[3].type == OP_REG32) |
| 1006 | opcode |= ops[3].reg << 12; | 1006 | opcode |= ops[3].reg << 12; |
| 1007 | else | 1007 | else |
| 1008 | expect("(third source operand) register"); | 1008 | expect(S, "(third source operand) register"); |
| 1009 | } | 1009 | } |
| 1010 | 1010 | ||
| 1011 | switch (ARM_INSTRUCTION_GROUP(token)) { | 1011 | switch (ARM_INSTRUCTION_GROUP(token)) { |
| @@ -1014,9 +1014,9 @@ static void asm_multiplication_opcode(TCCState *s1, int token) · 2 unmodified lines | |||
| 1014 | /* fallthrough */ | 1014 | /* fallthrough */ |
| 1015 | case TOK_ASM_muleq: | 1015 | case TOK_ASM_muleq: |
| 1016 | if (nb_ops != 3) | 1016 | if (nb_ops != 3) |
| 1017 | expect("three operands"); | 1017 | expect(S, "three operands"); |
| 1018 | else { | 1018 | else { |
| 1019 | asm_emit_opcode(token, opcode); | 1019 | asm_emit_opcode(S, token, opcode); |
| 1020 | } | 1020 | } |
| 1021 | break; | 1021 | break; |
| 1022 | case TOK_ASM_mlaseq: | 1022 | case TOK_ASM_mlaseq: |
| @@ -1024,33 +1024,33 @@ static void asm_multiplication_opcode(TCCState *s1, int token) · 1 unmodified line | |||
| 1024 | /* fallthrough */ | 1024 | /* fallthrough */ |
| 1025 | case TOK_ASM_mlaeq: | 1025 | case TOK_ASM_mlaeq: |
| 1026 | if (nb_ops != 4) | 1026 | if (nb_ops != 4) |
| 1027 | expect("four operands"); | 1027 | expect(S, "four operands"); |
| 1028 | else { | 1028 | else { |
| 1029 | opcode |= 1 << 21; // Accumulate | 1029 | opcode |= 1 << 21; // Accumulate |
| 1030 | asm_emit_opcode(token, opcode); | 1030 | asm_emit_opcode(S, token, opcode); |
| 1031 | } | 1031 | } |
| 1032 | break; | 1032 | break; |
| 1033 | default: | 1033 | default: |
| 1034 | expect("known multiplication instruction"); | 1034 | expect(S, "known multiplication instruction"); |
| 1035 | } | 1035 | } |
| 1036 | } | 1036 | } |
| 1037 | 1037 | ||
| 1038 | static void asm_long_multiplication_opcode(TCCState *s1, int token) | 1038 | static void asm_long_multiplication_opcode(TCCState *S, int token) |
| 1039 | { | 1039 | { |
| 1040 | Operand ops[4]; | 1040 | Operand ops[4]; |
| 1041 | int nb_ops = 0; | 1041 | int nb_ops = 0; |
| 1042 | uint32_t opcode = 0x90 | (1 << 23); | 1042 | uint32_t opcode = 0x90 | (1 << 23); |
| 1043 | 1043 | ||
| 1044 | for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) { | 1044 | for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) { |
| 1045 | parse_operand(s1, &ops[nb_ops]); | 1045 | parse_operand(S, &ops[nb_ops]); |
| 1046 | if (tok != ',') { | 1046 | if (S->tccpp_tok != ',') { |
| 1047 | ++nb_ops; | 1047 | ++nb_ops; |
| 1048 | break; | 1048 | break; |
| 1049 | } | 1049 | } |
| 1050 | next(); // skip ',' | 1050 | next(S); // skip ',' |
| 1051 | } | 1051 | } |
| 1052 | if (nb_ops != 4) { | 1052 | if (nb_ops != 4) { |
| 1053 | expect("four operands"); | 1053 | expect(S, "four operands"); |
| 1054 | return; | 1054 | return; |
| 1055 | } | 1055 | } |
| 1056 | 1056 | ||
| @@ -1064,19 +1064,19 @@ static void asm_long_multiplication_opcode(TCCState *s1, int token) · 7 unmodified lines | |||
| 1064 | if (ops[0].type == OP_REG32) | 1064 | if (ops[0].type == OP_REG32) |
| 1065 | opcode |= ops[0].reg << 12; | 1065 | opcode |= ops[0].reg << 12; |
| 1066 | else | 1066 | else |
| 1067 | expect("(destination lo accumulator) register"); | 1067 | expect(S, "(destination lo accumulator) register"); |
| 1068 | if (ops[1].type == OP_REG32) | 1068 | if (ops[1].type == OP_REG32) |
| 1069 | opcode |= ops[1].reg << 16; | 1069 | opcode |= ops[1].reg << 16; |
| 1070 | else | 1070 | else |
| 1071 | expect("(destination hi accumulator) register"); | 1071 | expect(S, "(destination hi accumulator) register"); |
| 1072 | if (ops[2].type == OP_REG32) | 1072 | if (ops[2].type == OP_REG32) |
| 1073 | opcode |= ops[2].reg; | 1073 | opcode |= ops[2].reg; |
| 1074 | else | 1074 | else |
| 1075 | expect("(first source operand) register"); | 1075 | expect(S, "(first source operand) register"); |
| 1076 | if (ops[3].type == OP_REG32) | 1076 | if (ops[3].type == OP_REG32) |
| 1077 | opcode |= ops[3].reg << 8; | 1077 | opcode |= ops[3].reg << 8; |
| 1078 | else | 1078 | else |
| 1079 | expect("(second source operand) register"); | 1079 | expect(S, "(second source operand) register"); |
| 1080 | 1080 | ||
| 1081 | switch (ARM_INSTRUCTION_GROUP(token)) { | 1081 | switch (ARM_INSTRUCTION_GROUP(token)) { |
| 1082 | case TOK_ASM_smullseq: | 1082 | case TOK_ASM_smullseq: |
| @@ -1084,13 +1084,13 @@ static void asm_long_multiplication_opcode(TCCState *s1, int token) · 1 unmodified line | |||
| 1084 | /* fallthrough */ | 1084 | /* fallthrough */ |
| 1085 | case TOK_ASM_smulleq: | 1085 | case TOK_ASM_smulleq: |
| 1086 | opcode |= 1 << 22; // signed | 1086 | opcode |= 1 << 22; // signed |
| 1087 | asm_emit_opcode(token, opcode); | 1087 | asm_emit_opcode(S, token, opcode); |
| 1088 | break; | 1088 | break; |
| 1089 | case TOK_ASM_umullseq: | 1089 | case TOK_ASM_umullseq: |
| 1090 | opcode |= 1 << 20; // Status | 1090 | opcode |= 1 << 20; // Status |
| 1091 | /* fallthrough */ | 1091 | /* fallthrough */ |
| 1092 | case TOK_ASM_umulleq: | 1092 | case TOK_ASM_umulleq: |
| 1093 | asm_emit_opcode(token, opcode); | 1093 | asm_emit_opcode(S, token, opcode); |
| 1094 | break; | 1094 | break; |
| 1095 | case TOK_ASM_smlalseq: | 1095 | case TOK_ASM_smlalseq: |
| 1096 | opcode |= 1 << 20; // Status | 1096 | opcode |= 1 << 20; // Status |
| @@ -1098,21 +1098,21 @@ static void asm_long_multiplication_opcode(TCCState *s1, int token) · 1 unmodified line | |||
| 1098 | case TOK_ASM_smlaleq: | 1098 | case TOK_ASM_smlaleq: |
| 1099 | opcode |= 1 << 22; // signed | 1099 | opcode |= 1 << 22; // signed |
| 1100 | opcode |= 1 << 21; // Accumulate | 1100 | opcode |= 1 << 21; // Accumulate |
| 1101 | asm_emit_opcode(token, opcode); | 1101 | asm_emit_opcode(S, token, opcode); |
| 1102 | break; | 1102 | break; |
| 1103 | case TOK_ASM_umlalseq: | 1103 | case TOK_ASM_umlalseq: |
| 1104 | opcode |= 1 << 20; // Status | 1104 | opcode |= 1 << 20; // Status |
| 1105 | /* fallthrough */ | 1105 | /* fallthrough */ |
| 1106 | case TOK_ASM_umlaleq: | 1106 | case TOK_ASM_umlaleq: |
| 1107 | opcode |= 1 << 21; // Accumulate | 1107 | opcode |= 1 << 21; // Accumulate |
| 1108 | asm_emit_opcode(token, opcode); | 1108 | asm_emit_opcode(S, token, opcode); |
| 1109 | break; | 1109 | break; |
| 1110 | default: | 1110 | default: |
| 1111 | expect("known long multiplication instruction"); | 1111 | expect(S, "known long multiplication instruction"); |
| 1112 | } | 1112 | } |
| 1113 | } | 1113 | } |
| 1114 | 1114 | ||
| 1115 | static void asm_single_data_transfer_opcode(TCCState *s1, int token) | 1115 | static void asm_single_data_transfer_opcode(TCCState *S, int token) |
| 1116 | { | 1116 | { |
| 1117 | Operand ops[3]; | 1117 | Operand ops[3]; |
| 1118 | Operand strex_operand; | 1118 | Operand strex_operand; |
| @@ -1126,67 +1126,67 @@ static void asm_single_data_transfer_opcode(TCCState *s1, int token) · 7 unmodified lines | |||
| 1126 | // Note: ldr r0, [r4, #4]! ; pre-indexed: r0 = *(int*)(r4+4); r4 = r4+4 | 1126 | // Note: ldr r0, [r4, #4]! ; pre-indexed: r0 = *(int*)(r4+4); r4 = r4+4 |
| 1127 | // Note: ldr r0, [r4], #4 ; post-indexed: r0 = *(int*)(r4+0); r4 = r4+4 | 1127 | // Note: ldr r0, [r4], #4 ; post-indexed: r0 = *(int*)(r4+0); r4 = r4+4 |
| 1128 | 1128 | ||
| 1129 | parse_operand(s1, &ops[0]); | 1129 | parse_operand(S, &ops[0]); |
| 1130 | if (ops[0].type == OP_REG32) | 1130 | if (ops[0].type == OP_REG32) |
| 1131 | opcode |= ENCODE_RD(ops[0].reg); | 1131 | opcode |= ENCODE_RD(ops[0].reg); |
| 1132 | else { | 1132 | else { |
| 1133 | expect("(destination operand) register"); | 1133 | expect(S, "(destination operand) register"); |
| 1134 | return; | 1134 | return; |
| 1135 | } | 1135 | } |
| 1136 | if (tok != ',') | 1136 | if (S->tccpp_tok != ',') |
| 1137 | expect("at least two arguments"); | 1137 | expect(S, "at least two arguments"); |
| 1138 | else | 1138 | else |
| 1139 | next(); // skip ',' | 1139 | next(S); // skip ',' |
| 1140 | 1140 | ||
| 1141 | switch (ARM_INSTRUCTION_GROUP(token)) { | 1141 | switch (ARM_INSTRUCTION_GROUP(token)) { |
| 1142 | case TOK_ASM_strexbeq: | 1142 | case TOK_ASM_strexbeq: |
| 1143 | case TOK_ASM_strexeq: | 1143 | case TOK_ASM_strexeq: |
| 1144 | parse_operand(s1, &strex_operand); | 1144 | parse_operand(S, &strex_operand); |
| 1145 | if (strex_operand.type != OP_REG32) { | 1145 | if (strex_operand.type != OP_REG32) { |
| 1146 | expect("register"); | 1146 | expect(S, "register"); |
| 1147 | return; | 1147 | return; |
| 1148 | } | 1148 | } |
| 1149 | if (tok != ',') | 1149 | if (S->tccpp_tok != ',') |
| 1150 | expect("at least three arguments"); | 1150 | expect(S, "at least three arguments"); |
| 1151 | else | 1151 | else |
| 1152 | next(); // skip ',' | 1152 | next(S); // skip ',' |
| 1153 | break; | 1153 | break; |
| 1154 | } | 1154 | } |
| 1155 | 1155 | ||
| 1156 | if (tok != '[') | 1156 | if (S->tccpp_tok != '[') |
| 1157 | expect("'['"); | 1157 | expect(S, "'['"); |
| 1158 | else | 1158 | else |
| 1159 | next(); // skip '[' | 1159 | next(S); // skip '[' |
| 1160 | 1160 | ||
| 1161 | parse_operand(s1, &ops[1]); | 1161 | parse_operand(S, &ops[1]); |
| 1162 | if (ops[1].type == OP_REG32) | 1162 | if (ops[1].type == OP_REG32) |
| 1163 | opcode |= ENCODE_RN(ops[1].reg); | 1163 | opcode |= ENCODE_RN(ops[1].reg); |
| 1164 | else { | 1164 | else { |
| 1165 | expect("(first source operand) register"); | 1165 | expect(S, "(first source operand) register"); |
| 1166 | return; | 1166 | return; |
| 1167 | } | 1167 | } |
| 1168 | if (tok == ']') { | 1168 | if (S->tccpp_tok == ']') { |
| 1169 | next(); | 1169 | next(S); |
| 1170 | closed_bracket = 1; | 1170 | closed_bracket = 1; |
| 1171 | // exclam = 1; // implicit in hardware; don't do it in software | 1171 | // exclam = 1; // implicit in hardware; don't do it in software |
| 1172 | } | 1172 | } |
| 1173 | if (tok == ',') { | 1173 | if (S->tccpp_tok == ',') { |
| 1174 | next(); // skip ',' | 1174 | next(S); // skip ',' |
| 1175 | if (tok == '-') { | 1175 | if (S->tccpp_tok == '-') { |
| 1176 | op2_minus = 1; | 1176 | op2_minus = 1; |
| 1177 | next(); | 1177 | next(S); |
| 1178 | } | 1178 | } |
| 1179 | parse_operand(s1, &ops[2]); | 1179 | parse_operand(S, &ops[2]); |
| 1180 | if (ops[2].type == OP_REG32) { | 1180 | if (ops[2].type == OP_REG32) { |
| 1181 | if (ops[2].reg == 15) { | 1181 | if (ops[2].reg == 15) { |
| 1182 | tcc_error("Using 'pc' for register offset in '%s' is not implemented by ARM", get_tok_str(token, NULL)); | 1182 | tcc_error(S, "Using 'pc' for register offset in '%s' is not implemented by ARM", get_tok_str(S, token, NULL)); |
| 1183 | return; | 1183 | return; |
| 1184 | } | 1184 | } |
| 1185 | if (tok == ',') { | 1185 | if (S->tccpp_tok == ',') { |
| 1186 | next(); | 1186 | next(S); |
| 1187 | opcode |= asm_parse_optional_shift(s1, &nb_shift, &shift); | 1187 | opcode |= asm_parse_optional_shift(S, &nb_shift, &shift); |
| 1188 | if (opcode == 0) | 1188 | if (opcode == 0) |
| 1189 | expect("shift directive, or no comma"); | 1189 | expect(S, "shift directive, or no comma"); |
| 1190 | } | 1190 | } |
| 1191 | } | 1191 | } |
| 1192 | } else { | 1192 | } else { |
| @@ -1196,14 +1196,14 @@ static void asm_single_data_transfer_opcode(TCCState *s1, int token) · 3 unmodified lines | |||
| 1196 | opcode |= 1 << 24; // add offset before transfer | 1196 | opcode |= 1 << 24; // add offset before transfer |
| 1197 | } | 1197 | } |
| 1198 | if (!closed_bracket) { | 1198 | if (!closed_bracket) { |
| 1199 | if (tok != ']') | 1199 | if (S->tccpp_tok != ']') |
| 1200 | expect("']'"); | 1200 | expect(S, "']'"); |
| 1201 | else | 1201 | else |
| 1202 | next(); // skip ']' | 1202 | next(S); // skip ']' |
| 1203 | opcode |= 1 << 24; // add offset before transfer | 1203 | opcode |= 1 << 24; // add offset before transfer |
| 1204 | if (tok == '!') { | 1204 | if (S->tccpp_tok == '!') { |
| 1205 | exclam = 1; | 1205 | exclam = 1; |
| 1206 | next(); // skip '!' | 1206 | next(S); // skip '!' |
| 1207 | } | 1207 | } |
| 1208 | } | 1208 | } |
| 1209 | 1209 | ||
| @@ -1224,16 +1224,16 @@ static void asm_single_data_transfer_opcode(TCCState *s1, int token) · 14 unmodified lines | |||
| 1224 | if (ops[2].type == OP_IM32 || ops[2].type == OP_IM8 || ops[2].type == OP_IM8N) { | 1224 | if (ops[2].type == OP_IM32 || ops[2].type == OP_IM8 || ops[2].type == OP_IM8N) { |
| 1225 | int v = ops[2].e.v; | 1225 | int v = ops[2].e.v; |
| 1226 | if (op2_minus) | 1226 | if (op2_minus) |
| 1227 | tcc_error("minus before '#' not supported for immediate values"); | 1227 | tcc_error(S, "minus before '#' not supported for immediate values"); |
| 1228 | if (v >= 0) { | 1228 | if (v >= 0) { |
| 1229 | opcode |= 1 << 23; // up | 1229 | opcode |= 1 << 23; // up |
| 1230 | if (v >= 0x1000) | 1230 | if (v >= 0x1000) |
| 1231 | tcc_error("offset out of range for '%s'", get_tok_str(token, NULL)); | 1231 | tcc_error(S, "offset out of range for '%s'", get_tok_str(S, token, NULL)); |
| 1232 | else | 1232 | else |
| 1233 | opcode |= v; | 1233 | opcode |= v; |
| 1234 | } else { // down | 1234 | } else { // down |
| 1235 | if (v <= -0x1000) | 1235 | if (v <= -0x1000) |
| 1236 | tcc_error("offset out of range for '%s'", get_tok_str(token, NULL)); | 1236 | tcc_error(S, "offset out of range for '%s'", get_tok_str(S, token, NULL)); |
| 1237 | else | 1237 | else |
| 1238 | opcode |= -v; | 1238 | opcode |= -v; |
| 1239 | } | 1239 | } |
| @@ -1243,7 +1243,7 @@ static void asm_single_data_transfer_opcode(TCCState *s1, int token) · 3 unmodified lines | |||
| 1243 | opcode |= ENCODE_IMMEDIATE_FLAG; /* if set, it means it's NOT immediate */ | 1243 | opcode |= ENCODE_IMMEDIATE_FLAG; /* if set, it means it's NOT immediate */ |
| 1244 | opcode |= ops[2].reg; | 1244 | opcode |= ops[2].reg; |
| 1245 | } else | 1245 | } else |
| 1246 | expect("register"); | 1246 | expect(S, "register"); |
| 1247 | 1247 | ||
| 1248 | switch (ARM_INSTRUCTION_GROUP(token)) { | 1248 | switch (ARM_INSTRUCTION_GROUP(token)) { |
| 1249 | case TOK_ASM_strbeq: | 1249 | case TOK_ASM_strbeq: |
| @@ -1252,8 +1252,8 @@ static void asm_single_data_transfer_opcode(TCCState *s1, int token) · 2 unmodified lines | |||
| 1252 | case TOK_ASM_streq: | 1252 | case TOK_ASM_streq: |
| 1253 | opcode |= 1 << 26; // Load/Store | 1253 | opcode |= 1 << 26; // Load/Store |
| 1254 | if (nb_shift) | 1254 | if (nb_shift) |
| 1255 | opcode |= asm_encode_shift(&shift); | 1255 | opcode |= asm_encode_shift(S, &shift); |
| 1256 | asm_emit_opcode(token, opcode); | 1256 | asm_emit_opcode(S, token, opcode); |
| 1257 | break; | 1257 | break; |
| 1258 | case TOK_ASM_ldrbeq: | 1258 | case TOK_ASM_ldrbeq: |
| 1259 | opcode |= 1 << 22; // B | 1259 | opcode |= 1 << 22; // B |
| @@ -1262,56 +1262,56 @@ static void asm_single_data_transfer_opcode(TCCState *s1, int token) · 2 unmodified lines | |||
| 1262 | opcode |= 1 << 20; // L | 1262 | opcode |= 1 << 20; // L |
| 1263 | opcode |= 1 << 26; // Load/Store | 1263 | opcode |= 1 << 26; // Load/Store |
| 1264 | if (nb_shift) | 1264 | if (nb_shift) |
| 1265 | opcode |= asm_encode_shift(&shift); | 1265 | opcode |= asm_encode_shift(S, &shift); |
| 1266 | asm_emit_opcode(token, opcode); | 1266 | asm_emit_opcode(S, token, opcode); |
| 1267 | break; | 1267 | break; |
| 1268 | case TOK_ASM_strexbeq: | 1268 | case TOK_ASM_strexbeq: |
| 1269 | opcode |= 1 << 22; // B | 1269 | opcode |= 1 << 22; // B |
| 1270 | /* fallthrough */ | 1270 | /* fallthrough */ |
| 1271 | case TOK_ASM_strexeq: | 1271 | case TOK_ASM_strexeq: |
| 1272 | if ((opcode & 0xFFF) || nb_shift) { | 1272 | if ((opcode & 0xFFF) || nb_shift) { |
| 1273 | tcc_error("neither offset nor shift allowed with 'strex'"); | 1273 | tcc_error(S, "neither offset nor shift allowed with 'strex'"); |
| 1274 | return; | 1274 | return; |
| 1275 | } else if (opcode & ENCODE_IMMEDIATE_FLAG) { // if set, it means it's NOT immediate | 1275 | } else if (opcode & ENCODE_IMMEDIATE_FLAG) { // if set, it means it's NOT immediate |
| 1276 | tcc_error("offset not allowed with 'strex'"); | 1276 | tcc_error(S, "offset not allowed with 'strex'"); |
| 1277 | return; | 1277 | return; |
| 1278 | } | 1278 | } |
| 1279 | if ((opcode & (1 << 24)) == 0) { // add offset after transfer | 1279 | if ((opcode & (1 << 24)) == 0) { // add offset after transfer |
| 1280 | tcc_error("adding offset after transfer not allowed with 'strex'"); | 1280 | tcc_error(S, "adding offset after transfer not allowed with 'strex'"); |
| 1281 | return; | 1281 | return; |
| 1282 | } | 1282 | } |
| 1283 | 1283 | ||
| 1284 | opcode |= 0xf90; // Used to mean: barrel shifter is enabled, barrel shift register is r15, mode is LSL | 1284 | opcode |= 0xf90; // Used to mean: barrel shifter is enabled, barrel shift register is r15, mode is LSL |
| 1285 | opcode |= strex_operand.reg; | 1285 | opcode |= strex_operand.reg; |
| 1286 | asm_emit_opcode(token, opcode); | 1286 | asm_emit_opcode(S, token, opcode); |
| 1287 | break; | 1287 | break; |
| 1288 | case TOK_ASM_ldrexbeq: | 1288 | case TOK_ASM_ldrexbeq: |
| 1289 | opcode |= 1 << 22; // B | 1289 | opcode |= 1 << 22; // B |
| 1290 | /* fallthrough */ | 1290 | /* fallthrough */ |
| 1291 | case TOK_ASM_ldrexeq: | 1291 | case TOK_ASM_ldrexeq: |
| 1292 | if ((opcode & 0xFFF) || nb_shift) { | 1292 | if ((opcode & 0xFFF) || nb_shift) { |
| 1293 | tcc_error("neither offset nor shift allowed with 'ldrex'"); | 1293 | tcc_error(S, "neither offset nor shift allowed with 'ldrex'"); |
| 1294 | return; | 1294 | return; |
| 1295 | } else if (opcode & ENCODE_IMMEDIATE_FLAG) { // if set, it means it's NOT immediate | 1295 | } else if (opcode & ENCODE_IMMEDIATE_FLAG) { // if set, it means it's NOT immediate |
| 1296 | tcc_error("offset not allowed with 'ldrex'"); | 1296 | tcc_error(S, "offset not allowed with 'ldrex'"); |
| 1297 | return; | 1297 | return; |
| 1298 | } | 1298 | } |
| 1299 | if ((opcode & (1 << 24)) == 0) { // add offset after transfer | 1299 | if ((opcode & (1 << 24)) == 0) { // add offset after transfer |
| 1300 | tcc_error("adding offset after transfer not allowed with 'ldrex'"); | 1300 | tcc_error(S, "adding offset after transfer not allowed with 'ldrex'"); |
| 1301 | return; | 1301 | return; |
| 1302 | } | 1302 | } |
| 1303 | opcode |= 1 << 20; // L | 1303 | opcode |= 1 << 20; // L |
| 1304 | opcode |= 0x00f; | 1304 | opcode |= 0x00f; |
| 1305 | opcode |= 0xf90; // Used to mean: barrel shifter is enabled, barrel shift register is r15, mode is LSL | 1305 | opcode |= 0xf90; // Used to mean: barrel shifter is enabled, barrel shift register is r15, mode is LSL |
| 1306 | asm_emit_opcode(token, opcode); | 1306 | asm_emit_opcode(S, token, opcode); |
| 1307 | break; | 1307 | break; |
| 1308 | default: | 1308 | default: |
| 1309 | expect("data transfer instruction"); | 1309 | expect(S, "data transfer instruction"); |
| 1310 | } | 1310 | } |
| 1311 | } | 1311 | } |
| 1312 | 1312 | ||
| 1313 | // Note: Only call this using a VFP register if you know exactly what you are doing (i.e. cp_number is 10 or 11 and you are doing a vmov) | 1313 | // Note: Only call this using a VFP register if you know exactly what you are doing (i.e. cp_number is 10 or 11 and you are doing a vmov) |
| 1314 | static void asm_emit_coprocessor_data_transfer(uint32_t high_nibble, uint8_t cp_number, uint8_t CRd, const Operand* Rn, const Operand* offset, int offset_minus, int preincrement, int writeback, int long_transfer, int load) { | 1314 | static void asm_emit_coprocessor_data_transfer(TCCState *S, uint32_t high_nibble, uint8_t cp_number, uint8_t CRd, const Operand* Rn, const Operand* offset, int offset_minus, int preincrement, int writeback, int long_transfer, int load) { |
| 1315 | uint32_t opcode = 0x0; | 1315 | uint32_t opcode = 0x0; |
| 1316 | opcode |= 1 << 26; // Load/Store | 1316 | opcode |= 1 << 26; // Load/Store |
| 1317 | opcode |= 1 << 27; // coprocessor | 1317 | opcode |= 1 << 27; // coprocessor |
| @@ -1328,7 +1328,7 @@ static void asm_emit_coprocessor_data_transfer(uint32_t high_nibble, uint8_t cp_ · 10 unmodified lines | |||
| 1328 | opcode |= ENCODE_RD(CRd); | 1328 | opcode |= ENCODE_RD(CRd); |
| 1329 | 1329 | ||
| 1330 | if (Rn->type != OP_REG32) { | 1330 | if (Rn->type != OP_REG32) { |
| 1331 | expect("register"); | 1331 | expect(S, "register"); |
| 1332 | return; | 1332 | return; |
| 1333 | } | 1333 | } |
| 1334 | //assert(Rn->reg < 16); | 1334 | //assert(Rn->reg < 16); |
| @@ -1342,18 +1342,18 @@ static void asm_emit_coprocessor_data_transfer(uint32_t high_nibble, uint8_t cp_ · 7 unmodified lines | |||
| 1342 | if (offset->type == OP_IM8 || offset->type == OP_IM8N || offset->type == OP_IM32) { | 1342 | if (offset->type == OP_IM8 || offset->type == OP_IM8N || offset->type == OP_IM32) { |
| 1343 | int v = offset->e.v; | 1343 | int v = offset->e.v; |
| 1344 | if (offset_minus) | 1344 | if (offset_minus) |
| 1345 | tcc_error("minus before '#' not supported for immediate values"); | 1345 | tcc_error(S, "minus before '#' not supported for immediate values"); |
| 1346 | if (offset->type == OP_IM8N || v < 0) | 1346 | if (offset->type == OP_IM8N || v < 0) |
| 1347 | v = -v; | 1347 | v = -v; |
| 1348 | else | 1348 | else |
| 1349 | opcode |= 1 << 23; // up | 1349 | opcode |= 1 << 23; // up |
| 1350 | if (v & 3) { | 1350 | if (v & 3) { |
| 1351 | tcc_error("immediate offset must be a multiple of 4"); | 1351 | tcc_error(S, "immediate offset must be a multiple of 4"); |
| 1352 | return; | 1352 | return; |
| 1353 | } | 1353 | } |
| 1354 | v >>= 2; | 1354 | v >>= 2; |
| 1355 | if (v > 255) { | 1355 | if (v > 255) { |
| 1356 | tcc_error("immediate offset must be between -1020 and 1020"); | 1356 | tcc_error(S, "immediate offset must be between -1020 and 1020"); |
| 1357 | return; | 1357 | return; |
| 1358 | } | 1358 | } |
| 1359 | opcode |= v; | 1359 | opcode |= v; |
| @@ -1362,20 +1362,20 @@ static void asm_emit_coprocessor_data_transfer(uint32_t high_nibble, uint8_t cp_ · 2 unmodified lines | |||
| 1362 | opcode |= 1 << 23; // up | 1362 | opcode |= 1 << 23; // up |
| 1363 | opcode |= ENCODE_IMMEDIATE_FLAG; /* if set, it means it's NOT immediate */ | 1363 | opcode |= ENCODE_IMMEDIATE_FLAG; /* if set, it means it's NOT immediate */ |
| 1364 | opcode |= offset->reg; | 1364 | opcode |= offset->reg; |
| 1365 | tcc_error("Using register offset to register address is not possible here"); | 1365 | tcc_error(S, "Using register offset to register address is not possible here"); |
| 1366 | return; | 1366 | return; |
| 1367 | } else if (offset->type == OP_VREG64) { | 1367 | } else if (offset->type == OP_VREG64) { |
| 1368 | opcode |= 16; | 1368 | opcode |= 16; |
| 1369 | opcode |= offset->reg; | 1369 | opcode |= offset->reg; |
| 1370 | } else | 1370 | } else |
| 1371 | expect("immediate or register"); | 1371 | expect(S, "immediate or register"); |
| 1372 | 1372 | ||
| 1373 | asm_emit_unconditional_opcode((high_nibble << 28) | opcode); | 1373 | asm_emit_unconditional_opcode(S, (high_nibble << 28) | opcode); |
| 1374 | } | 1374 | } |
| 1375 | 1375 | ||
| 1376 | // Almost exactly the same as asm_single_data_transfer_opcode. | 1376 | // Almost exactly the same as asm_single_data_transfer_opcode. |
| 1377 | // Difference: Offsets are smaller and multiples of 4; no shifts, no STREX, ENCODE_IMMEDIATE_FLAG is inverted again. | 1377 | // Difference: Offsets are smaller and multiples of 4; no shifts, no STREX, ENCODE_IMMEDIATE_FLAG is inverted again. |
| 1378 | static void asm_coprocessor_data_transfer_opcode(TCCState *s1, int token) | 1378 | static void asm_coprocessor_data_transfer_opcode(TCCState *S, int token) |
| 1379 | { | 1379 | { |
| 1380 | Operand ops[3]; | 1380 | Operand ops[3]; |
| 1381 | uint8_t coprocessor; | 1381 | uint8_t coprocessor; |
| @@ -1389,61 +1389,61 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *s1, int token) · 7 unmodified lines | |||
| 1389 | // Note: ldc p2, c0, [r4, #4]! ; pre-indexed: r0 = *(int*)(r4+4); r4 = r4+4 | 1389 | // Note: ldc p2, c0, [r4, #4]! ; pre-indexed: r0 = *(int*)(r4+4); r4 = r4+4 |
| 1390 | // Note: ldc p3, c0, [r4], #4 ; post-indexed: r0 = *(int*)(r4+0); r4 = r4+4 | 1390 | // Note: ldc p3, c0, [r4], #4 ; post-indexed: r0 = *(int*)(r4+0); r4 = r4+4 |
| 1391 | 1391 | ||
| 1392 | if (tok >= TOK_ASM_p0 && tok <= TOK_ASM_p15) { | 1392 | if (S->tccpp_tok >= TOK_ASM_p0 && S->tccpp_tok <= TOK_ASM_p15) { |
| 1393 | coprocessor = tok - TOK_ASM_p0; | 1393 | coprocessor = S->tccpp_tok - TOK_ASM_p0; |
| 1394 | next(); | 1394 | next(S); |
| 1395 | } else { | 1395 | } else { |
| 1396 | expect("'c<number>'"); | 1396 | expect(S, "'c<number>'"); |
| 1397 | return; | 1397 | return; |
| 1398 | } | 1398 | } |
| 1399 | 1399 | ||
| 1400 | if (tok == ',') | 1400 | if (S->tccpp_tok == ',') |
| 1401 | next(); | 1401 | next(S); |
| 1402 | else | 1402 | else |
| 1403 | expect("','"); | 1403 | expect(S, "','"); |
| 1404 | 1404 | ||
| 1405 | if (tok >= TOK_ASM_c0 && tok <= TOK_ASM_c15) { | 1405 | if (S->tccpp_tok >= TOK_ASM_c0 && S->tccpp_tok <= TOK_ASM_c15) { |
| 1406 | coprocessor_destination_register = tok - TOK_ASM_c0; | 1406 | coprocessor_destination_register = S->tccpp_tok - TOK_ASM_c0; |
| 1407 | next(); | 1407 | next(S); |
| 1408 | } else { | 1408 | } else { |
| 1409 | expect("'c<number>'"); | 1409 | expect(S, "'c<number>'"); |
| 1410 | return; | 1410 | return; |
| 1411 | } | 1411 | } |
| 1412 | 1412 | ||
| 1413 | if (tok == ',') | 1413 | if (S->tccpp_tok == ',') |
| 1414 | next(); | 1414 | next(S); |
| 1415 | else | 1415 | else |
| 1416 | expect("','"); | 1416 | expect(S, "','"); |
| 1417 | 1417 | ||
| 1418 | if (tok != '[') | 1418 | if (S->tccpp_tok != '[') |
| 1419 | expect("'['"); | 1419 | expect(S, "'['"); |
| 1420 | else | 1420 | else |
| 1421 | next(); // skip '[' | 1421 | next(S); // skip '[' |
| 1422 | 1422 | ||
| 1423 | parse_operand(s1, &ops[1]); | 1423 | parse_operand(S, &ops[1]); |
| 1424 | if (ops[1].type != OP_REG32) { | 1424 | if (ops[1].type != OP_REG32) { |
| 1425 | expect("(first source operand) register"); | 1425 | expect(S, "(first source operand) register"); |
| 1426 | return; | 1426 | return; |
| 1427 | } | 1427 | } |
| 1428 | if (tok == ']') { | 1428 | if (S->tccpp_tok == ']') { |
| 1429 | next(); | 1429 | next(S); |
| 1430 | closed_bracket = 1; | 1430 | closed_bracket = 1; |
| 1431 | // exclam = 1; // implicit in hardware; don't do it in software | 1431 | // exclam = 1; // implicit in hardware; don't do it in software |
| 1432 | } | 1432 | } |
| 1433 | if (tok == ',') { | 1433 | if (S->tccpp_tok == ',') { |
| 1434 | next(); // skip ',' | 1434 | next(S); // skip ',' |
| 1435 | if (tok == '-') { | 1435 | if (S->tccpp_tok == '-') { |
| 1436 | op2_minus = 1; | 1436 | op2_minus = 1; |
| 1437 | next(); | 1437 | next(S); |
| 1438 | } | 1438 | } |
| 1439 | parse_operand(s1, &ops[2]); | 1439 | parse_operand(S, &ops[2]); |
| 1440 | if (ops[2].type == OP_REG32) { | 1440 | if (ops[2].type == OP_REG32) { |
| 1441 | if (ops[2].reg == 15) { | 1441 | if (ops[2].reg == 15) { |
| 1442 | tcc_error("Using 'pc' for register offset in '%s' is not implemented by ARM", get_tok_str(token, NULL)); | 1442 | tcc_error(S, "Using 'pc' for register offset in '%s' is not implemented by ARM", get_tok_str(S, token, NULL)); |
| 1443 | return; | 1443 | return; |
| 1444 | } | 1444 | } |
| 1445 | } else if (ops[2].type == OP_VREG64) { | 1445 | } else if (ops[2].type == OP_VREG64) { |
| 1446 | tcc_error("'%s' does not support VFP register operand", get_tok_str(token, NULL)); | 1446 | tcc_error(S, "'%s' does not support VFP register operand", get_tok_str(S, token, NULL)); |
| 1447 | return; | 1447 | return; |
| 1448 | } | 1448 | } |
| 1449 | } else { | 1449 | } else { |
| @@ -1453,14 +1453,14 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *s1, int token) · 3 unmodified lines | |||
| 1453 | preincrement = 1; // add offset before transfer | 1453 | preincrement = 1; // add offset before transfer |
| 1454 | } | 1454 | } |
| 1455 | if (!closed_bracket) { | 1455 | if (!closed_bracket) { |
| 1456 | if (tok != ']') | 1456 | if (S->tccpp_tok != ']') |
| 1457 | expect("']'"); | 1457 | expect(S, "']'"); |
| 1458 | else | 1458 | else |
| 1459 | next(); // skip ']' | 1459 | next(S); // skip ']' |
| 1460 | preincrement = 1; // add offset before transfer | 1460 | preincrement = 1; // add offset before transfer |
| 1461 | if (tok == '!') { | 1461 | if (S->tccpp_tok == '!') { |
| 1462 | exclam = 1; | 1462 | exclam = 1; |
| 1463 | next(); // skip '!' | 1463 | next(S); // skip '!' |
| 1464 | } | 1464 | } |
| 1465 | } | 1465 | } |
| 1466 | 1466 | ||
| @@ -1472,13 +1472,13 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *s1, int token) · 5 unmodified lines | |||
| 1472 | long_transfer = 1; // long transfer | 1472 | long_transfer = 1; // long transfer |
| 1473 | /* fallthrough */ | 1473 | /* fallthrough */ |
| 1474 | case TOK_ASM_ldc2: | 1474 | case TOK_ASM_ldc2: |
| 1475 | asm_emit_coprocessor_data_transfer(0xF, coprocessor, coprocessor_destination_register, &ops[1], &ops[2], op2_minus, preincrement, exclam, long_transfer, 1); | 1475 | asm_emit_coprocessor_data_transfer(S, 0xF, coprocessor, coprocessor_destination_register, &ops[1], &ops[2], op2_minus, preincrement, exclam, long_transfer, 1); |
| 1476 | break; | 1476 | break; |
| 1477 | case TOK_ASM_stc2l: | 1477 | case TOK_ASM_stc2l: |
| 1478 | long_transfer = 1; // long transfer | 1478 | long_transfer = 1; // long transfer |
| 1479 | /* fallthrough */ | 1479 | /* fallthrough */ |
| 1480 | case TOK_ASM_stc2: | 1480 | case TOK_ASM_stc2: |
| 1481 | asm_emit_coprocessor_data_transfer(0xF, coprocessor, coprocessor_destination_register, &ops[1], &ops[2], op2_minus, preincrement, exclam, long_transfer, 0); | 1481 | asm_emit_coprocessor_data_transfer(S, 0xF, coprocessor, coprocessor_destination_register, &ops[1], &ops[2], op2_minus, preincrement, exclam, long_transfer, 0); |
| 1482 | break; | 1482 | break; |
| 1483 | } | 1483 | } |
| 1484 | } else switch (ARM_INSTRUCTION_GROUP(token)) { | 1484 | } else switch (ARM_INSTRUCTION_GROUP(token)) { |
| @@ -1486,16 +1486,16 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *s1, int token) · 1 unmodified line | |||
| 1486 | long_transfer = 1; | 1486 | long_transfer = 1; |
| 1487 | /* fallthrough */ | 1487 | /* fallthrough */ |
| 1488 | case TOK_ASM_stceq: | 1488 | case TOK_ASM_stceq: |
| 1489 | asm_emit_coprocessor_data_transfer(condition_code_of_token(token), coprocessor, coprocessor_destination_register, &ops[1], &ops[2], op2_minus, preincrement, exclam, long_transfer, 0); | 1489 | asm_emit_coprocessor_data_transfer(S, condition_code_of_token(S, token), coprocessor, coprocessor_destination_register, &ops[1], &ops[2], op2_minus, preincrement, exclam, long_transfer, 0); |
| 1490 | break; | 1490 | break; |
| 1491 | case TOK_ASM_ldcleq: | 1491 | case TOK_ASM_ldcleq: |
| 1492 | long_transfer = 1; | 1492 | long_transfer = 1; |
| 1493 | /* fallthrough */ | 1493 | /* fallthrough */ |
| 1494 | case TOK_ASM_ldceq: | 1494 | case TOK_ASM_ldceq: |
| 1495 | asm_emit_coprocessor_data_transfer(condition_code_of_token(token), coprocessor, coprocessor_destination_register, &ops[1], &ops[2], op2_minus, preincrement, exclam, long_transfer, 1); | 1495 | asm_emit_coprocessor_data_transfer(S, condition_code_of_token(S, token), coprocessor, coprocessor_destination_register, &ops[1], &ops[2], op2_minus, preincrement, exclam, long_transfer, 1); |
| 1496 | break; | 1496 | break; |
| 1497 | default: | 1497 | default: |
| 1498 | expect("coprocessor data transfer instruction"); | 1498 | expect(S, "coprocessor data transfer instruction"); |
| 1499 | } | 1499 | } |
| 1500 | } | 1500 | } |
| 1501 | 1501 | ||
| @@ -1503,7 +1503,7 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *s1, int token) · 1 unmodified line | |||
| 1503 | #define CP_SINGLE_PRECISION_FLOAT 10 | 1503 | #define CP_SINGLE_PRECISION_FLOAT 10 |
| 1504 | #define CP_DOUBLE_PRECISION_FLOAT 11 | 1504 | #define CP_DOUBLE_PRECISION_FLOAT 11 |
| 1505 | 1505 | ||
| 1506 | static void asm_floating_point_single_data_transfer_opcode(TCCState *s1, int token) | 1506 | static void asm_floating_point_single_data_transfer_opcode(TCCState *S, int token) |
| 1507 | { | 1507 | { |
| 1508 | Operand ops[3]; | 1508 | Operand ops[3]; |
| 1509 | uint8_t coprocessor = 0; | 1509 | uint8_t coprocessor = 0; |
| @@ -1513,7 +1513,7 @@ static void asm_floating_point_single_data_transfer_opcode(TCCState *s1, int tok · 3 unmodified lines | |||
| 1513 | // Note: Not allowed: vldr p2, c0, [r4, #4]! ; pre-indexed: r0 = *(int*)(r4+4); r4 = r4+4 | 1513 | // Note: Not allowed: vldr p2, c0, [r4, #4]! ; pre-indexed: r0 = *(int*)(r4+4); r4 = r4+4 |
| 1514 | // Note: Not allowed: vldr p3, c0, [r4], #4 ; post-indexed: r0 = *(int*)(r4+0); r4 = r4+4 | 1514 | // Note: Not allowed: vldr p3, c0, [r4], #4 ; post-indexed: r0 = *(int*)(r4+0); r4 = r4+4 |
| 1515 | 1515 | ||
| 1516 | parse_operand(s1, &ops[0]); | 1516 | parse_operand(S, &ops[0]); |
| 1517 | if (ops[0].type == OP_VREG32) { | 1517 | if (ops[0].type == OP_VREG32) { |
| 1518 | coprocessor = CP_SINGLE_PRECISION_FLOAT; | 1518 | coprocessor = CP_SINGLE_PRECISION_FLOAT; |
| 1519 | coprocessor_destination_register = ops[0].reg; | 1519 | coprocessor_destination_register = ops[0].reg; |
| @@ -1522,32 +1522,32 @@ static void asm_floating_point_single_data_transfer_opcode(TCCState *s1, int tok · 2 unmodified lines | |||
| 1522 | } else if (ops[0].type == OP_VREG64) { | 1522 | } else if (ops[0].type == OP_VREG64) { |
| 1523 | coprocessor = CP_DOUBLE_PRECISION_FLOAT; | 1523 | coprocessor = CP_DOUBLE_PRECISION_FLOAT; |
| 1524 | coprocessor_destination_register = ops[0].reg; | 1524 | coprocessor_destination_register = ops[0].reg; |
| 1525 | next(); | 1525 | next(S); |
| 1526 | } else { | 1526 | } else { |
| 1527 | expect("floating point register"); | 1527 | expect(S, "floating point register"); |
| 1528 | return; | 1528 | return; |
| 1529 | } | 1529 | } |
| 1530 | 1530 | ||
| 1531 | if (tok == ',') | 1531 | if (S->tccpp_tok == ',') |
| 1532 | next(); | 1532 | next(S); |
| 1533 | else | 1533 | else |
| 1534 | expect("','"); | 1534 | expect(S, "','"); |
| 1535 | 1535 | ||
| 1536 | if (tok != '[') | 1536 | if (S->tccpp_tok != '[') |
| 1537 | expect("'['"); | 1537 | expect(S, "'['"); |
| 1538 | else | 1538 | else |
| 1539 | next(); // skip '[' | 1539 | next(S); // skip '[' |
| 1540 | 1540 | ||
| 1541 | parse_operand(s1, &ops[1]); | 1541 | parse_operand(S, &ops[1]); |
| 1542 | if (ops[1].type != OP_REG32) { | 1542 | if (ops[1].type != OP_REG32) { |
| 1543 | expect("(first source operand) register"); | 1543 | expect(S, "(first source operand) register"); |
| 1544 | return; | 1544 | return; |
| 1545 | } | 1545 | } |
| 1546 | if (tok == ',') { | 1546 | if (S->tccpp_tok == ',') { |
| 1547 | next(); // skip ',' | 1547 | next(S); // skip ',' |
| 1548 | parse_operand(s1, &ops[2]); | 1548 | parse_operand(S, &ops[2]); |
| 1549 | if (ops[2].type != OP_IM8 && ops[2].type != OP_IM8N) { | 1549 | if (ops[2].type != OP_IM8 && ops[2].type != OP_IM8N) { |
| 1550 | expect("immediate offset"); | 1550 | expect(S, "immediate offset"); |
| 1551 | return; | 1551 | return; |
| 1552 | } | 1552 | } |
| 1553 | } else { | 1553 | } else { |
| @@ -1555,24 +1555,24 @@ static void asm_floating_point_single_data_transfer_opcode(TCCState *s1, int tok · 1 unmodified line | |||
| 1555 | ops[2].type = OP_IM8; | 1555 | ops[2].type = OP_IM8; |
| 1556 | ops[2].e.v = 0; | 1556 | ops[2].e.v = 0; |
| 1557 | } | 1557 | } |
| 1558 | if (tok != ']') | 1558 | if (S->tccpp_tok != ']') |
| 1559 | expect("']'"); | 1559 | expect(S, "']'"); |
| 1560 | else | 1560 | else |
| 1561 | next(); // skip ']' | 1561 | next(S); // skip ']' |
| 1562 | 1562 | ||
| 1563 | switch (ARM_INSTRUCTION_GROUP(token)) { | 1563 | switch (ARM_INSTRUCTION_GROUP(token)) { |
| 1564 | case TOK_ASM_vldreq: | 1564 | case TOK_ASM_vldreq: |
| 1565 | asm_emit_coprocessor_data_transfer(condition_code_of_token(token), coprocessor, coprocessor_destination_register, &ops[1], &ops[2], 0, 1, 0, long_transfer, 1); | 1565 | asm_emit_coprocessor_data_transfer(S, condition_code_of_token(S, token), coprocessor, coprocessor_destination_register, &ops[1], &ops[2], 0, 1, 0, long_transfer, 1); |
| 1566 | break; | 1566 | break; |
| 1567 | case TOK_ASM_vstreq: | 1567 | case TOK_ASM_vstreq: |
| 1568 | asm_emit_coprocessor_data_transfer(condition_code_of_token(token), coprocessor, coprocessor_destination_register, &ops[1], &ops[2], 0, 1, 0, long_transfer, 0); | 1568 | asm_emit_coprocessor_data_transfer(S, condition_code_of_token(S, token), coprocessor, coprocessor_destination_register, &ops[1], &ops[2], 0, 1, 0, long_transfer, 0); |
| 1569 | break; | 1569 | break; |
| 1570 | default: | 1570 | default: |
| 1571 | expect("floating point data transfer instruction"); | 1571 | expect(S, "floating point data transfer instruction"); |
| 1572 | } | 1572 | } |
| 1573 | } | 1573 | } |
| 1574 | 1574 | ||
| 1575 | static void asm_floating_point_block_data_transfer_opcode(TCCState *s1, int token) | 1575 | static void asm_floating_point_block_data_transfer_opcode(TCCState *S, int token) |
| 1576 | { | 1576 | { |
| 1577 | uint8_t coprocessor = 0; | 1577 | uint8_t coprocessor = 0; |
| 1578 | int first_regset_register; | 1578 | int first_regset_register; |
| @@ -1592,56 +1592,56 @@ static void asm_floating_point_block_data_transfer_opcode(TCCState *s1, int toke · 13 unmodified lines | |||
| 1592 | op0_exclam = 1; | 1592 | op0_exclam = 1; |
| 1593 | break; | 1593 | break; |
| 1594 | default: | 1594 | default: |
| 1595 | parse_operand(s1, &ops[0]); | 1595 | parse_operand(S, &ops[0]); |
| 1596 | if (tok == '!') { | 1596 | if (S->tccpp_tok == '!') { |
| 1597 | op0_exclam = 1; | 1597 | op0_exclam = 1; |
| 1598 | next(); // skip '!' | 1598 | next(S); // skip '!' |
| 1599 | } | 1599 | } |
| 1600 | if (tok == ',') | 1600 | if (S->tccpp_tok == ',') |
| 1601 | next(); // skip comma | 1601 | next(S); // skip comma |
| 1602 | else { | 1602 | else { |
| 1603 | expect("','"); | 1603 | expect(S, "','"); |
| 1604 | return; | 1604 | return; |
| 1605 | } | 1605 | } |
| 1606 | } | 1606 | } |
| 1607 | 1607 | ||
| 1608 | if (tok != '{') { | 1608 | if (S->tccpp_tok != '{') { |
| 1609 | expect("'{'"); | 1609 | expect(S, "'{'"); |
| 1610 | return; | 1610 | return; |
| 1611 | } | 1611 | } |
| 1612 | next(); // skip '{' | 1612 | next(S); // skip '{' |
| 1613 | first_regset_register = asm_parse_vfp_regvar(tok, 1); | 1613 | first_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, 1); |
| 1614 | if ((first_regset_register = asm_parse_vfp_regvar(tok, 1)) != -1) { | 1614 | if ((first_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, 1)) != -1) { |
| 1615 | coprocessor = CP_DOUBLE_PRECISION_FLOAT; | 1615 | coprocessor = CP_DOUBLE_PRECISION_FLOAT; |
| 1616 | next(); | 1616 | next(S); |
| 1617 | } else if ((first_regset_register = asm_parse_vfp_regvar(tok, 0)) != -1) { | 1617 | } else if ((first_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, 0)) != -1) { |
| 1618 | coprocessor = CP_SINGLE_PRECISION_FLOAT; | 1618 | coprocessor = CP_SINGLE_PRECISION_FLOAT; |
| 1619 | next(); | 1619 | next(S); |
| 1620 | } else { | 1620 | } else { |
| 1621 | expect("floating-point register"); | 1621 | expect(S, "floating-point register"); |
| 1622 | return; | 1622 | return; |
| 1623 | } | 1623 | } |
| 1624 | 1624 | ||
| 1625 | if (tok == '-') { | 1625 | if (S->tccpp_tok == '-') { |
| 1626 | next(); | 1626 | next(S); |
| 1627 | if ((last_regset_register = asm_parse_vfp_regvar(tok, coprocessor == CP_DOUBLE_PRECISION_FLOAT)) != -1) | 1627 | if ((last_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, coprocessor == CP_DOUBLE_PRECISION_FLOAT)) != -1) |
| 1628 | next(); | 1628 | next(S); |
| 1629 | else { | 1629 | else { |
| 1630 | expect("floating-point register"); | 1630 | expect(S, "floating-point register"); |
| 1631 | return; | 1631 | return; |
| 1632 | } | 1632 | } |
| 1633 | } else | 1633 | } else |
| 1634 | last_regset_register = first_regset_register; | 1634 | last_regset_register = first_regset_register; |
| 1635 | 1635 | ||
| 1636 | if (last_regset_register < first_regset_register) { | 1636 | if (last_regset_register < first_regset_register) { |
| 1637 | tcc_error("registers will be processed in ascending order by hardware--but are not specified in ascending order here"); | 1637 | tcc_error(S, "registers will be processed in ascending order by hardware--but are not specified in ascending order here"); |
| 1638 | return; | 1638 | return; |
| 1639 | } | 1639 | } |
| 1640 | if (tok != '}') { | 1640 | if (S->tccpp_tok != '}') { |
| 1641 | expect("'}'"); | 1641 | expect(S, "'}'"); |
| 1642 | return; | 1642 | return; |
| 1643 | } | 1643 | } |
| 1644 | next(); // skip '}' | 1644 | next(S); // skip '}' |
| 1645 | 1645 | ||
| 1646 | // Note: 0 (one down) is not implemented by us regardless. | 1646 | // Note: 0 (one down) is not implemented by us regardless. |
| 1647 | regset_item_count = last_regset_register - first_regset_register + 1; | 1647 | regset_item_count = last_regset_register - first_regset_register + 1; |
| @@ -1672,23 +1672,23 @@ static void asm_floating_point_block_data_transfer_opcode(TCCState *s1, int toke · 24 unmodified lines | |||
| 1672 | preincrement = 1; | 1672 | preincrement = 1; |
| 1673 | break; | 1673 | break; |
| 1674 | default: | 1674 | default: |
| 1675 | expect("floating point block data transfer instruction"); | 1675 | expect(S, "floating point block data transfer instruction"); |
| 1676 | return; | 1676 | return; |
| 1677 | } | 1677 | } |
| 1678 | if (ops[0].type != OP_REG32) | 1678 | if (ops[0].type != OP_REG32) |
| 1679 | expect("(first operand) register"); | 1679 | expect(S, "(first operand) register"); |
| 1680 | else if (ops[0].reg == 15) | 1680 | else if (ops[0].reg == 15) |
| 1681 | tcc_error("'%s' does not support 'pc' as operand", get_tok_str(token, NULL)); | 1681 | tcc_error(S, "'%s' does not support 'pc' as operand", get_tok_str(S, token, NULL)); |
| 1682 | else if (!op0_exclam && ARM_INSTRUCTION_GROUP(token) != TOK_ASM_vldmeq && ARM_INSTRUCTION_GROUP(token) != TOK_ASM_vldmiaeq && ARM_INSTRUCTION_GROUP(token) != TOK_ASM_vstmeq && ARM_INSTRUCTION_GROUP(token) != TOK_ASM_vstmiaeq) | 1682 | else if (!op0_exclam && ARM_INSTRUCTION_GROUP(token) != TOK_ASM_vldmeq && ARM_INSTRUCTION_GROUP(token) != TOK_ASM_vldmiaeq && ARM_INSTRUCTION_GROUP(token) != TOK_ASM_vstmeq && ARM_INSTRUCTION_GROUP(token) != TOK_ASM_vstmiaeq) |
| 1683 | tcc_error("first operand of '%s' should have an exclamation mark", get_tok_str(token, NULL)); | 1683 | tcc_error(S, "first operand of '%s' should have an exclamation mark", get_tok_str(S, token, NULL)); |
| 1684 | else | 1684 | else |
| 1685 | asm_emit_coprocessor_data_transfer(condition_code_of_token(token), coprocessor, first_regset_register, &ops[0], &offset, 0, preincrement, op0_exclam, extra_register_bit, load); | 1685 | asm_emit_coprocessor_data_transfer(S, condition_code_of_token(S, token), coprocessor, first_regset_register, &ops[0], &offset, 0, preincrement, op0_exclam, extra_register_bit, load); |
| 1686 | } | 1686 | } |
| 1687 | 1687 | ||
| 1688 | #define VMOV_FRACTIONAL_DIGITS 7 | 1688 | #define VMOV_FRACTIONAL_DIGITS 7 |
| 1689 | #define VMOV_ONE 10000000 /* pow(10, VMOV_FRACTIONAL_DIGITS) */ | 1689 | #define VMOV_ONE 10000000 /* pow(10, VMOV_FRACTIONAL_DIGITS) */ |
| 1690 | 1690 | ||
| 1691 | static uint32_t vmov_parse_fractional_part(const char* s) | 1691 | static uint32_t vmov_parse_fractional_part(TCCState* S, const char* s) |
| 1692 | { | 1692 | { |
| 1693 | uint32_t result = 0; | 1693 | uint32_t result = 0; |
| 1694 | int i; | 1694 | int i; |
| @@ -1701,7 +1701,7 @@ static uint32_t vmov_parse_fractional_part(const char* s) · 6 unmodified lines | |||
| 1701 | } | 1701 | } |
| 1702 | } | 1702 | } |
| 1703 | if (*s) | 1703 | if (*s) |
| 1704 | expect("decimal numeral"); | 1704 | expect(S, "decimal numeral"); |
| 1705 | return result; | 1705 | return result; |
| 1706 | } | 1706 | } |
| 1707 | 1707 | ||
| @@ -1720,34 +1720,34 @@ static int vmov_linear_approx_index(uint32_t beginning, uint32_t end, uint32_t v · 12 unmodified lines | |||
| 1720 | return -1; | 1720 | return -1; |
| 1721 | } | 1721 | } |
| 1722 | 1722 | ||
| 1723 | static uint32_t vmov_parse_immediate_value() { | 1723 | static uint32_t vmov_parse_immediate_value(TCCState* S) { |
| 1724 | uint32_t value; | 1724 | uint32_t value; |
| 1725 | unsigned long integral_value; | 1725 | unsigned long integral_value; |
| 1726 | const char *p; | 1726 | const char *p; |
| 1727 | 1727 | ||
| 1728 | if (tok != TOK_PPNUM) { | 1728 | if (S->tccpp_tok != TOK_PPNUM) { |
| 1729 | expect("immediate value"); | 1729 | expect(S, "immediate value"); |
| 1730 | return 0; | 1730 | return 0; |
| 1731 | } | 1731 | } |
| 1732 | p = tokc.str.data; | 1732 | p = S->tccpp_tokc.str.data; |
| 1733 | errno = 0; | 1733 | errno = 0; |
| 1734 | integral_value = strtoul(p, (char **)&p, 0); | 1734 | integral_value = strtoul(p, (char **)&p, 0); |
| 1735 | 1735 | ||
| 1736 | if (errno || integral_value >= 32) { | 1736 | if (errno || integral_value >= 32) { |
| 1737 | tcc_error("invalid floating-point immediate value"); | 1737 | tcc_error(S, "invalid floating-point immediate value"); |
| 1738 | return 0; | 1738 | return 0; |
| 1739 | } | 1739 | } |
| 1740 | 1740 | ||
| 1741 | value = (uint32_t) integral_value * VMOV_ONE; | 1741 | value = (uint32_t) integral_value * VMOV_ONE; |
| 1742 | if (*p == '.') { | 1742 | if (*p == '.') { |
| 1743 | ++p; | 1743 | ++p; |
| 1744 | value += vmov_parse_fractional_part(p); | 1744 | value += vmov_parse_fractional_part(S, p); |
| 1745 | } | 1745 | } |
| 1746 | next(); | 1746 | next(S); |
| 1747 | return value; | 1747 | return value; |
| 1748 | } | 1748 | } |
| 1749 | 1749 | ||
| 1750 | static uint8_t vmov_encode_immediate_value(uint32_t value) | 1750 | static uint8_t vmov_encode_immediate_value(TCCState* S, uint32_t value) |
| 1751 | { | 1751 | { |
| 1752 | uint32_t limit; | 1752 | uint32_t limit; |
| 1753 | uint32_t end = 0; | 1753 | uint32_t end = 0; |
| @@ -1767,7 +1767,7 @@ static uint8_t vmov_encode_immediate_value(uint32_t value) · 13 unmodified lines | |||
| 1767 | limit >>= 1; | 1767 | limit >>= 1; |
| 1768 | } | 1768 | } |
| 1769 | if (r == -1 || value < beginning || value > end) { | 1769 | if (r == -1 || value < beginning || value > end) { |
| 1770 | tcc_error("invalid decimal number for vmov: %d", value); | 1770 | tcc_error(S, "invalid decimal number for vmov: %d", value); |
| 1771 | return 0; | 1771 | return 0; |
| 1772 | } | 1772 | } |
| 1773 | n = vmov_linear_approx_index(beginning, end, value); | 1773 | n = vmov_linear_approx_index(beginning, end, value); |
| @@ -1775,7 +1775,7 @@ static uint8_t vmov_encode_immediate_value(uint32_t value) · 1 unmodified line | |||
| 1775 | } | 1775 | } |
| 1776 | 1776 | ||
| 1777 | // Not standalone. | 1777 | // Not standalone. |
| 1778 | static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *s1, int token, uint8_t coprocessor, uint8_t CRd) { | 1778 | static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *S, int token, uint8_t coprocessor, uint8_t CRd) { |
| 1779 | uint8_t opcode1 = 0; | 1779 | uint8_t opcode1 = 0; |
| 1780 | uint8_t opcode2 = 0; | 1780 | uint8_t opcode2 = 0; |
| 1781 | uint8_t operands[3] = {0, 0, 0}; | 1781 | uint8_t operands[3] = {0, 0, 0}; |
| @@ -1785,14 +1785,14 @@ static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *s · 3 unmodified lines | |||
| 1785 | 1785 | ||
| 1786 | operands[0] = CRd; | 1786 | operands[0] = CRd; |
| 1787 | 1787 | ||
| 1788 | if (tok == '#' || tok == '$') { | 1788 | if (S->tccpp_tok == '#' || S->tccpp_tok == '$') { |
| 1789 | next(); | 1789 | next(S); |
| 1790 | } | 1790 | } |
| 1791 | if (tok == '-') { | 1791 | if (S->tccpp_tok == '-') { |
| 1792 | op_minus = 1; | 1792 | op_minus = 1; |
| 1793 | next(); | 1793 | next(S); |
| 1794 | } | 1794 | } |
| 1795 | immediate_value = vmov_parse_immediate_value(); | 1795 | immediate_value = vmov_parse_immediate_value(S); |
| 1796 | 1796 | ||
| 1797 | opcode1 = 11; // "Other" instruction | 1797 | opcode1 = 11; // "Other" instruction |
| 1798 | switch (ARM_INSTRUCTION_GROUP(token)) { | 1798 | switch (ARM_INSTRUCTION_GROUP(token)) { |
| @@ -1801,7 +1801,7 @@ static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *s · 2 unmodified lines | |||
| 1801 | opcode2 = 2; | 1801 | opcode2 = 2; |
| 1802 | operands[1] = 5; | 1802 | operands[1] = 5; |
| 1803 | if (immediate_value) { | 1803 | if (immediate_value) { |
| 1804 | expect("Immediate value 0"); | 1804 | expect(S, "Immediate value 0"); |
| 1805 | return; | 1805 | return; |
| 1806 | } | 1806 | } |
| 1807 | break; | 1807 | break; |
| @@ -1810,7 +1810,7 @@ static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *s · 2 unmodified lines | |||
| 1810 | opcode2 = 6; | 1810 | opcode2 = 6; |
| 1811 | operands[1] = 5; | 1811 | operands[1] = 5; |
| 1812 | if (immediate_value) { | 1812 | if (immediate_value) { |
| 1813 | expect("Immediate value 0"); | 1813 | expect(S, "Immediate value 0"); |
| 1814 | return; | 1814 | return; |
| 1815 | } | 1815 | } |
| 1816 | break; | 1816 | break; |
| @@ -1821,12 +1821,12 @@ static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *s · 4 unmodified lines | |||
| 1821 | operands[1] = 0x8; | 1821 | operands[1] = 0x8; |
| 1822 | else | 1822 | else |
| 1823 | operands[1] = 0x0; | 1823 | operands[1] = 0x0; |
| 1824 | code = vmov_encode_immediate_value(immediate_value); | 1824 | code = vmov_encode_immediate_value(S, immediate_value); |
| 1825 | operands[1] |= code >> 4; | 1825 | operands[1] |= code >> 4; |
| 1826 | operands[2] = code & 0xF; | 1826 | operands[2] = code & 0xF; |
| 1827 | break; | 1827 | break; |
| 1828 | default: | 1828 | default: |
| 1829 | expect("known floating point with immediate instruction"); | 1829 | expect(S, "known floating point with immediate instruction"); |
| 1830 | return; | 1830 | return; |
| 1831 | } | 1831 | } |
| 1832 | 1832 | ||
| @@ -1836,17 +1836,17 @@ static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *s · 3 unmodified lines | |||
| 1836 | operands[0] >>= 1; | 1836 | operands[0] >>= 1; |
| 1837 | } | 1837 | } |
| 1838 | 1838 | ||
| 1839 | asm_emit_coprocessor_opcode(condition_code_of_token(token), coprocessor, opcode1, operands[0], operands[1], operands[2], opcode2, 0); | 1839 | asm_emit_coprocessor_opcode(S, condition_code_of_token(S, token), coprocessor, opcode1, operands[0], operands[1], operands[2], opcode2, 0); |
| 1840 | } | 1840 | } |
| 1841 | 1841 | ||
| 1842 | static void asm_floating_point_reg_arm_reg_transfer_opcode_tail(TCCState *s1, int token, int coprocessor, int nb_arm_regs, int nb_ops, Operand ops[3]) { | 1842 | static void asm_floating_point_reg_arm_reg_transfer_opcode_tail(TCCState *S, int token, int coprocessor, int nb_arm_regs, int nb_ops, Operand ops[3]) { |
| 1843 | uint8_t opcode1 = 0; | 1843 | uint8_t opcode1 = 0; |
| 1844 | uint8_t opcode2 = 0; | 1844 | uint8_t opcode2 = 0; |
| 1845 | switch (coprocessor) { | 1845 | switch (coprocessor) { |
| 1846 | case CP_SINGLE_PRECISION_FLOAT: | 1846 | case CP_SINGLE_PRECISION_FLOAT: |
| 1847 | // "vmov.f32 r2, s3" or "vmov.f32 s3, r2" | 1847 | // "vmov.f32 r2, s3" or "vmov.f32 s3, r2" |
| 1848 | if (nb_ops != 2 || nb_arm_regs != 1) { | 1848 | if (nb_ops != 2 || nb_arm_regs != 1) { |
| 1849 | tcc_error("vmov.f32 only implemented for one VFP register operand and one ARM register operands"); | 1849 | tcc_error(S, "vmov.f32 only implemented for one VFP register operand and one ARM register operands"); |
| 1850 | return; | 1850 | return; |
| 1851 | } | 1851 | } |
| 1852 | if (ops[0].type != OP_REG32) { // determine mode: load or store | 1852 | if (ops[0].type != OP_REG32) { // determine mode: load or store |
| @@ -1869,11 +1869,11 @@ static void asm_floating_point_reg_arm_reg_transfer_opcode_tail(TCCState *s1, in · 16 unmodified lines | |||
| 1869 | ops[0].reg >>= 1; | 1869 | ops[0].reg >>= 1; |
| 1870 | } | 1870 | } |
| 1871 | 1871 | ||
| 1872 | asm_emit_coprocessor_opcode(condition_code_of_token(token), coprocessor, opcode1, ops[0].reg, (ops[1].type == OP_IM8) ? ops[1].e.v : ops[1].reg, 0x10, opcode2, 0); | 1872 | asm_emit_coprocessor_opcode(S, condition_code_of_token(S, token), coprocessor, opcode1, ops[0].reg, (ops[1].type == OP_IM8) ? ops[1].e.v : ops[1].reg, 0x10, opcode2, 0); |
| 1873 | break; | 1873 | break; |
| 1874 | case CP_DOUBLE_PRECISION_FLOAT: | 1874 | case CP_DOUBLE_PRECISION_FLOAT: |
| 1875 | if (nb_ops != 3 || nb_arm_regs != 2) { | 1875 | if (nb_ops != 3 || nb_arm_regs != 2) { |
| 1876 | tcc_error("vmov.f32 only implemented for one VFP register operand and two ARM register operands"); | 1876 | tcc_error(S, "vmov.f32 only implemented for one VFP register operand and two ARM register operands"); |
| 1877 | return; | 1877 | return; |
| 1878 | } | 1878 | } |
| 1879 | // Determine whether it's a store into a VFP register (vmov "d1, r2, r3") rather than "vmov r2, r3, d1" | 1879 | // Determine whether it's a store into a VFP register (vmov "d1, r2, r3") rather than "vmov r2, r3, d1" |
| @@ -1886,23 +1886,23 @@ static void asm_floating_point_reg_arm_reg_transfer_opcode_tail(TCCState *s1, in · 6 unmodified lines | |||
| 1886 | memcpy(&ops[1], &ops[2], sizeof(ops[1])); | 1886 | memcpy(&ops[1], &ops[2], sizeof(ops[1])); |
| 1887 | memcpy(&ops[2], &temp, sizeof(ops[2])); | 1887 | memcpy(&ops[2], &temp, sizeof(ops[2])); |
| 1888 | } else { | 1888 | } else { |
| 1889 | tcc_error("vmov.f64 only implemented for one VFP register operand and two ARM register operands"); | 1889 | tcc_error(S, "vmov.f64 only implemented for one VFP register operand and two ARM register operands"); |
| 1890 | return; | 1890 | return; |
| 1891 | } | 1891 | } |
| 1892 | } else if (ops[0].type != OP_REG32 || ops[1].type != OP_REG32 || ops[2].type != OP_VREG64) { | 1892 | } else if (ops[0].type != OP_REG32 || ops[1].type != OP_REG32 || ops[2].type != OP_VREG64) { |
| 1893 | tcc_error("vmov.f64 only implemented for one VFP register operand and two ARM register operands"); | 1893 | tcc_error(S, "vmov.f64 only implemented for one VFP register operand and two ARM register operands"); |
| 1894 | return; | 1894 | return; |
| 1895 | } else { | 1895 | } else { |
| 1896 | opcode1 |= 1; | 1896 | opcode1 |= 1; |
| 1897 | } | 1897 | } |
| 1898 | asm_emit_coprocessor_data_transfer(condition_code_of_token(token), coprocessor, ops[0].reg, &ops[1], &ops[2], 0, 0, 0, 1, opcode1); | 1898 | asm_emit_coprocessor_data_transfer(S, condition_code_of_token(S, token), coprocessor, ops[0].reg, &ops[1], &ops[2], 0, 0, 0, 1, opcode1); |
| 1899 | break; | 1899 | break; |
| 1900 | default: | 1900 | default: |
| 1901 | tcc_internal_error("unknown coprocessor"); | 1901 | tcc_internal_error(S, "unknown coprocessor"); |
| 1902 | } | 1902 | } |
| 1903 | } | 1903 | } |
| 1904 | 1904 | ||
| 1905 | static void asm_floating_point_vcvt_data_processing_opcode(TCCState *s1, int token) { | 1905 | static void asm_floating_point_vcvt_data_processing_opcode(TCCState *S, int token) { |
| 1906 | uint8_t coprocessor = 0; | 1906 | uint8_t coprocessor = 0; |
| 1907 | Operand ops[3]; | 1907 | Operand ops[3]; |
| 1908 | uint8_t opcode1 = 11; | 1908 | uint8_t opcode1 = 11; |
| @@ -1928,11 +1928,11 @@ static void asm_floating_point_vcvt_data_processing_opcode(TCCState *s1, int tok · 19 unmodified lines | |||
| 1928 | coprocessor = CP_SINGLE_PRECISION_FLOAT; | 1928 | coprocessor = CP_SINGLE_PRECISION_FLOAT; |
| 1929 | break; | 1929 | break; |
| 1930 | default: | 1930 | default: |
| 1931 | tcc_error("Unknown coprocessor for instruction '%s'", get_tok_str(token, NULL)); | 1931 | tcc_error(S, "Unknown coprocessor for instruction '%s'", get_tok_str(S, token, NULL)); |
| 1932 | return; | 1932 | return; |
| 1933 | } | 1933 | } |
| 1934 | 1934 | ||
| 1935 | parse_operand(s1, &ops[0]); | 1935 | parse_operand(S, &ops[0]); |
| 1936 | ops[1].type = OP_IM8; | 1936 | ops[1].type = OP_IM8; |
| 1937 | ops[1].e.v = 8; | 1937 | ops[1].e.v = 8; |
| 1938 | /* floating-point -> integer */ | 1938 | /* floating-point -> integer */ |
| @@ -1956,11 +1956,11 @@ static void asm_floating_point_vcvt_data_processing_opcode(TCCState *s1, int tok · 17 unmodified lines | |||
| 1956 | break; | 1956 | break; |
| 1957 | } | 1957 | } |
| 1958 | 1958 | ||
| 1959 | if (tok == ',') | 1959 | if (S->tccpp_tok == ',') |
| 1960 | next(); | 1960 | next(S); |
| 1961 | else | 1961 | else |
| 1962 | expect("','"); | 1962 | expect(S, "','"); |
| 1963 | parse_operand(s1, &ops[2]); | 1963 | parse_operand(S, &ops[2]); |
| 1964 | 1964 | ||
| 1965 | switch (ARM_INSTRUCTION_GROUP(token)) { | 1965 | switch (ARM_INSTRUCTION_GROUP(token)) { |
| 1966 | /* floating-point -> integer */ | 1966 | /* floating-point -> integer */ |
| @@ -1990,7 +1990,7 @@ static void asm_floating_point_vcvt_data_processing_opcode(TCCState *s1, int tok · 23 unmodified lines | |||
| 1990 | case TOK_ASM_vcvteq_f64_f32: | 1990 | case TOK_ASM_vcvteq_f64_f32: |
| 1991 | if (ops[0].type == OP_VREG64 && ops[2].type == OP_VREG32) { | 1991 | if (ops[0].type == OP_VREG64 && ops[2].type == OP_VREG32) { |
| 1992 | } else { | 1992 | } else { |
| 1993 | expect("d<number>, s<number>"); | 1993 | expect(S, "d<number>, s<number>"); |
| 1994 | return; | 1994 | return; |
| 1995 | } | 1995 | } |
| 1996 | break; | 1996 | break; |
| @@ -1998,13 +1998,13 @@ static void asm_floating_point_vcvt_data_processing_opcode(TCCState *s1, int tok · 1 unmodified line | |||
| 1998 | if (coprocessor == CP_SINGLE_PRECISION_FLOAT) { | 1998 | if (coprocessor == CP_SINGLE_PRECISION_FLOAT) { |
| 1999 | if (ops[0].type == OP_VREG32 && ops[2].type == OP_VREG32) { | 1999 | if (ops[0].type == OP_VREG32 && ops[2].type == OP_VREG32) { |
| 2000 | } else { | 2000 | } else { |
| 2001 | expect("s<number>, s<number>"); | 2001 | expect(S, "s<number>, s<number>"); |
| 2002 | return; | 2002 | return; |
| 2003 | } | 2003 | } |
| 2004 | } else if (coprocessor == CP_DOUBLE_PRECISION_FLOAT) { | 2004 | } else if (coprocessor == CP_DOUBLE_PRECISION_FLOAT) { |
| 2005 | if (ops[0].type == OP_VREG32 && ops[2].type == OP_VREG64) { | 2005 | if (ops[0].type == OP_VREG32 && ops[2].type == OP_VREG64) { |
| 2006 | } else { | 2006 | } else { |
| 2007 | expect("s<number>, d<number>"); | 2007 | expect(S, "s<number>, d<number>"); |
| 2008 | return; | 2008 | return; |
| 2009 | } | 2009 | } |
| 2010 | } | 2010 | } |
| @@ -2020,10 +2020,10 @@ static void asm_floating_point_vcvt_data_processing_opcode(TCCState *s1, int tok · 9 unmodified lines | |||
| 2020 | opcode1 |= 4; | 2020 | opcode1 |= 4; |
| 2021 | ops[0].reg >>= 1; | 2021 | ops[0].reg >>= 1; |
| 2022 | } | 2022 | } |
| 2023 | asm_emit_coprocessor_opcode(condition_code_of_token(token), coprocessor, opcode1, ops[0].reg, (ops[1].type == OP_IM8) ? ops[1].e.v : ops[1].reg, (ops[2].type == OP_IM8) ? ops[2].e.v : ops[2].reg, opcode2, 0); | 2023 | asm_emit_coprocessor_opcode(S, condition_code_of_token(S, token), coprocessor, opcode1, ops[0].reg, (ops[1].type == OP_IM8) ? ops[1].e.v : ops[1].reg, (ops[2].type == OP_IM8) ? ops[2].e.v : ops[2].reg, opcode2, 0); |
| 2024 | } | 2024 | } |
| 2025 | 2025 | ||
| 2026 | static void asm_floating_point_data_processing_opcode(TCCState *s1, int token) { | 2026 | static void asm_floating_point_data_processing_opcode(TCCState *S, int token) { |
| 2027 | uint8_t coprocessor = CP_SINGLE_PRECISION_FLOAT; | 2027 | uint8_t coprocessor = CP_SINGLE_PRECISION_FLOAT; |
| 2028 | uint8_t opcode1 = 0; | 2028 | uint8_t opcode1 = 0; |
| 2029 | uint8_t opcode2 = 0; // (0 || 2) | register selection | 2029 | uint8_t opcode2 = 0; // (0 || 2) | register selection |
| @@ -2078,30 +2078,30 @@ static void asm_floating_point_data_processing_opcode(TCCState *s1, int token) { · 48 unmodified lines | |||
| 2078 | 2078 | ||
| 2079 | for (nb_ops = 0; nb_ops < 3; ) { | 2079 | for (nb_ops = 0; nb_ops < 3; ) { |
| 2080 | // Note: Necessary because parse_operand can't parse decimal numerals. | 2080 | // Note: Necessary because parse_operand can't parse decimal numerals. |
| 2081 | if (nb_ops == 1 && (tok == '#' || tok == '$' || tok == TOK_PPNUM || tok == '-')) { | 2081 | if (nb_ops == 1 && (S->tccpp_tok == '#' || S->tccpp_tok == '$' || S->tccpp_tok == TOK_PPNUM || S->tccpp_tok == '-')) { |
| 2082 | asm_floating_point_immediate_data_processing_opcode_tail(s1, token, coprocessor, ops[0].reg); | 2082 | asm_floating_point_immediate_data_processing_opcode_tail(S, token, coprocessor, ops[0].reg); |
| 2083 | return; | 2083 | return; |
| 2084 | } | 2084 | } |
| 2085 | parse_operand(s1, &ops[nb_ops]); | 2085 | parse_operand(S, &ops[nb_ops]); |
| 2086 | if (vmov && ops[nb_ops].type == OP_REG32) { | 2086 | if (vmov && ops[nb_ops].type == OP_REG32) { |
| 2087 | ++nb_arm_regs; | 2087 | ++nb_arm_regs; |
| 2088 | } else if (ops[nb_ops].type == OP_VREG32) { | 2088 | } else if (ops[nb_ops].type == OP_VREG32) { |
| 2089 | if (coprocessor != CP_SINGLE_PRECISION_FLOAT) { | 2089 | if (coprocessor != CP_SINGLE_PRECISION_FLOAT) { |
| 2090 | expect("'s<number>'"); | 2090 | expect(S, "'s<number>'"); |
| 2091 | return; | 2091 | return; |
| 2092 | } | 2092 | } |
| 2093 | } else if (ops[nb_ops].type == OP_VREG64) { | 2093 | } else if (ops[nb_ops].type == OP_VREG64) { |
| 2094 | if (coprocessor != CP_DOUBLE_PRECISION_FLOAT) { | 2094 | if (coprocessor != CP_DOUBLE_PRECISION_FLOAT) { |
| 2095 | expect("'d<number>'"); | 2095 | expect(S, "'d<number>'"); |
| 2096 | return; | 2096 | return; |
| 2097 | } | 2097 | } |
| 2098 | } else { | 2098 | } else { |
| 2099 | expect("floating point register"); | 2099 | expect(S, "floating point register"); |
| 2100 | return; | 2100 | return; |
| 2101 | } | 2101 | } |
| 2102 | ++nb_ops; | 2102 | ++nb_ops; |
| 2103 | if (tok == ',') | 2103 | if (S->tccpp_tok == ',') |
| 2104 | next(); | 2104 | next(S); |
| 2105 | else | 2105 | else |
| 2106 | break; | 2106 | break; |
| 2107 | } | 2107 | } |
| @@ -2113,7 +2113,7 @@ static void asm_floating_point_data_processing_opcode(TCCState *s1, int token) { · 5 unmodified lines | |||
| 2113 | nb_ops = 3; | 2113 | nb_ops = 3; |
| 2114 | } | 2114 | } |
| 2115 | if (nb_ops < 3) { | 2115 | if (nb_ops < 3) { |
| 2116 | tcc_error("Not enough operands for '%s' (%u)", get_tok_str(token, NULL), nb_ops); | 2116 | tcc_error(S, "Not enough operands for '%s' (%u)", get_tok_str(S, token, NULL), nb_ops); |
| 2117 | return; | 2117 | return; |
| 2118 | } | 2118 | } |
| 2119 | } | 2119 | } |
| @@ -2202,7 +2202,7 @@ static void asm_floating_point_data_processing_opcode(TCCState *s1, int token) { · 82 unmodified lines | |||
| 2202 | case TOK_ASM_vmoveq_f32: | 2202 | case TOK_ASM_vmoveq_f32: |
| 2203 | case TOK_ASM_vmoveq_f64: | 2203 | case TOK_ASM_vmoveq_f64: |
| 2204 | if (nb_arm_regs > 0) { // vmov.f32 r2, s3 or similar | 2204 | if (nb_arm_regs > 0) { // vmov.f32 r2, s3 or similar |
| 2205 | asm_floating_point_reg_arm_reg_transfer_opcode_tail(s1, token, coprocessor, nb_arm_regs, nb_ops, ops); | 2205 | asm_floating_point_reg_arm_reg_transfer_opcode_tail(S, token, coprocessor, nb_arm_regs, nb_ops, ops); |
| 2206 | return; | 2206 | return; |
| 2207 | } else { | 2207 | } else { |
| 2208 | opcode1 = 11; // "Other" instruction | 2208 | opcode1 = 11; // "Other" instruction |
| @@ -2212,7 +2212,7 @@ static void asm_floating_point_data_processing_opcode(TCCState *s1, int token) { · 3 unmodified lines | |||
| 2212 | } | 2212 | } |
| 2213 | break; | 2213 | break; |
| 2214 | default: | 2214 | default: |
| 2215 | expect("known floating point instruction"); | 2215 | expect(S, "known floating point instruction"); |
| 2216 | return; | 2216 | return; |
| 2217 | } | 2217 | } |
| 2218 | 2218 | ||
| @@ -2236,10 +2236,10 @@ static void asm_floating_point_data_processing_opcode(TCCState *s1, int token) { · 17 unmodified lines | |||
| 2236 | } | 2236 | } |
| 2237 | } | 2237 | } |
| 2238 | 2238 | ||
| 2239 | asm_emit_coprocessor_opcode(condition_code_of_token(token), coprocessor, opcode1, ops[0].reg, (ops[1].type == OP_IM8) ? ops[1].e.v : ops[1].reg, (ops[2].type == OP_IM8) ? ops[2].e.v : ops[2].reg, opcode2, 0); | 2239 | asm_emit_coprocessor_opcode(S, condition_code_of_token(S, token), coprocessor, opcode1, ops[0].reg, (ops[1].type == OP_IM8) ? ops[1].e.v : ops[1].reg, (ops[2].type == OP_IM8) ? ops[2].e.v : ops[2].reg, opcode2, 0); |
| 2240 | } | 2240 | } |
| 2241 | 2241 | ||
| 2242 | static void asm_floating_point_status_register_opcode(TCCState* s1, int token) | 2242 | static void asm_floating_point_status_register_opcode(TCCState* S, int token) |
| 2243 | { | 2243 | { |
| 2244 | uint8_t coprocessor = CP_SINGLE_PRECISION_FLOAT; | 2244 | uint8_t coprocessor = CP_SINGLE_PRECISION_FLOAT; |
| 2245 | uint8_t opcode; | 2245 | uint8_t opcode; |
| @@ -2248,61 +2248,61 @@ static void asm_floating_point_status_register_opcode(TCCState* s1, int token) · 2 unmodified lines | |||
| 2248 | switch (ARM_INSTRUCTION_GROUP(token)) { | 2248 | switch (ARM_INSTRUCTION_GROUP(token)) { |
| 2249 | case TOK_ASM_vmrseq: | 2249 | case TOK_ASM_vmrseq: |
| 2250 | opcode = 0xf; | 2250 | opcode = 0xf; |
| 2251 | if (tok == TOK_ASM_apsr_nzcv) { | 2251 | if (S->tccpp_tok == TOK_ASM_apsr_nzcv) { |
| 2252 | arm_operand.type = OP_REG32; | 2252 | arm_operand.type = OP_REG32; |
| 2253 | arm_operand.reg = 15; // not PC | 2253 | arm_operand.reg = 15; // not PC |
| 2254 | next(); // skip apsr_nzcv | 2254 | next(S); // skip apsr_nzcv |
| 2255 | } else { | 2255 | } else { |
| 2256 | parse_operand(s1, &arm_operand); | 2256 | parse_operand(S, &arm_operand); |
| 2257 | if (arm_operand.type == OP_REG32 && arm_operand.reg == 15) { | 2257 | if (arm_operand.type == OP_REG32 && arm_operand.reg == 15) { |
| 2258 | tcc_error("'%s' does not support 'pc' as operand", get_tok_str(token, NULL)); | 2258 | tcc_error(S, "'%s' does not support 'pc' as operand", get_tok_str(S, token, NULL)); |
| 2259 | return; | 2259 | return; |
| 2260 | } | 2260 | } |
| 2261 | } | 2261 | } |
| 2262 | 2262 | ||
| 2263 | if (tok != ',') | 2263 | if (S->tccpp_tok != ',') |
| 2264 | expect("','"); | 2264 | expect(S, "','"); |
| 2265 | else | 2265 | else |
| 2266 | next(); // skip ',' | 2266 | next(S); // skip ',' |
| 2267 | vfp_sys_reg = asm_parse_vfp_status_regvar(tok); | 2267 | vfp_sys_reg = asm_parse_vfp_status_regvar(S->tccpp_tok); |
| 2268 | next(); // skip vfp sys reg | 2268 | next(S); // skip vfp sys reg |
| 2269 | if (arm_operand.type == OP_REG32 && arm_operand.reg == 15 && vfp_sys_reg != 1) { | 2269 | if (arm_operand.type == OP_REG32 && arm_operand.reg == 15 && vfp_sys_reg != 1) { |
| 2270 | tcc_error("'%s' only supports the variant 'vmrs apsr_nzcv, fpscr' here", get_tok_str(token, NULL)); | 2270 | tcc_error(S, "'%s' only supports the variant 'vmrs apsr_nzcv, fpscr' here", get_tok_str(S, token, NULL)); |
| 2271 | return; | 2271 | return; |
| 2272 | } | 2272 | } |
| 2273 | break; | 2273 | break; |
| 2274 | case TOK_ASM_vmsreq: | 2274 | case TOK_ASM_vmsreq: |
| 2275 | opcode = 0xe; | 2275 | opcode = 0xe; |
| 2276 | vfp_sys_reg = asm_parse_vfp_status_regvar(tok); | 2276 | vfp_sys_reg = asm_parse_vfp_status_regvar(S->tccpp_tok); |
| 2277 | next(); // skip vfp sys reg | 2277 | next(S); // skip vfp sys reg |
| 2278 | if (tok != ',') | 2278 | if (S->tccpp_tok != ',') |
| 2279 | expect("','"); | 2279 | expect(S, "','"); |
| 2280 | else | 2280 | else |
| 2281 | next(); // skip ',' | 2281 | next(S); // skip ',' |
| 2282 | parse_operand(s1, &arm_operand); | 2282 | parse_operand(S, &arm_operand); |
| 2283 | if (arm_operand.type == OP_REG32 && arm_operand.reg == 15) { | 2283 | if (arm_operand.type == OP_REG32 && arm_operand.reg == 15) { |
| 2284 | tcc_error("'%s' does not support 'pc' as operand", get_tok_str(token, NULL)); | 2284 | tcc_error(S, "'%s' does not support 'pc' as operand", get_tok_str(S, token, NULL)); |
| 2285 | return; | 2285 | return; |
| 2286 | } | 2286 | } |
| 2287 | break; | 2287 | break; |
| 2288 | default: | 2288 | default: |
| 2289 | expect("floating point status register instruction"); | 2289 | expect(S, "floating point status register instruction"); |
| 2290 | return; | 2290 | return; |
| 2291 | } | 2291 | } |
| 2292 | if (vfp_sys_reg == -1) { | 2292 | if (vfp_sys_reg == -1) { |
| 2293 | expect("VFP system register"); | 2293 | expect(S, "VFP system register"); |
| 2294 | return; | 2294 | return; |
| 2295 | } | 2295 | } |
| 2296 | if (arm_operand.type != OP_REG32) { | 2296 | if (arm_operand.type != OP_REG32) { |
| 2297 | expect("ARM register"); | 2297 | expect(S, "ARM register"); |
| 2298 | return; | 2298 | return; |
| 2299 | } | 2299 | } |
| 2300 | asm_emit_coprocessor_opcode(condition_code_of_token(token), coprocessor, opcode, arm_operand.reg, vfp_sys_reg, 0x10, 0, 0); | 2300 | asm_emit_coprocessor_opcode(S, condition_code_of_token(S, token), coprocessor, opcode, arm_operand.reg, vfp_sys_reg, 0x10, 0, 0); |
| 2301 | } | 2301 | } |
| 2302 | 2302 | ||
| 2303 | #endif | 2303 | #endif |
| 2304 | 2304 | ||
| 2305 | static void asm_misc_single_data_transfer_opcode(TCCState *s1, int token) | 2305 | static void asm_misc_single_data_transfer_opcode(TCCState *S, int token) |
| 2306 | { | 2306 | { |
| 2307 | Operand ops[3]; | 2307 | Operand ops[3]; |
| 2308 | int exclam = 0; | 2308 | int exclam = 0; |
| @@ -2322,42 +2322,42 @@ static void asm_misc_single_data_transfer_opcode(TCCState *s1, int token) · 13 unmodified lines | |||
| 2322 | // Here: 0 0 0 P U I W L << 20 | 2322 | // Here: 0 0 0 P U I W L << 20 |
| 2323 | // [compare single data transfer: 0 1 I P U B W L << 20] | 2323 | // [compare single data transfer: 0 1 I P U B W L << 20] |
| 2324 | 2324 | ||
| 2325 | parse_operand(s1, &ops[0]); | 2325 | parse_operand(S, &ops[0]); |
| 2326 | if (ops[0].type == OP_REG32) | 2326 | if (ops[0].type == OP_REG32) |
| 2327 | opcode |= ENCODE_RD(ops[0].reg); | 2327 | opcode |= ENCODE_RD(ops[0].reg); |
| 2328 | else { | 2328 | else { |
| 2329 | expect("(destination operand) register"); | 2329 | expect(S, "(destination operand) register"); |
| 2330 | return; | 2330 | return; |
| 2331 | } | 2331 | } |
| 2332 | if (tok != ',') | 2332 | if (S->tccpp_tok != ',') |
| 2333 | expect("at least two arguments"); | 2333 | expect(S, "at least two arguments"); |
| 2334 | else | 2334 | else |
| 2335 | next(); // skip ',' | 2335 | next(S); // skip ',' |
| 2336 | 2336 | ||
| 2337 | if (tok != '[') | 2337 | if (S->tccpp_tok != '[') |
| 2338 | expect("'['"); | 2338 | expect(S, "'['"); |
| 2339 | else | 2339 | else |
| 2340 | next(); // skip '[' | 2340 | next(S); // skip '[' |
| 2341 | 2341 | ||
| 2342 | parse_operand(s1, &ops[1]); | 2342 | parse_operand(S, &ops[1]); |
| 2343 | if (ops[1].type == OP_REG32) | 2343 | if (ops[1].type == OP_REG32) |
| 2344 | opcode |= ENCODE_RN(ops[1].reg); | 2344 | opcode |= ENCODE_RN(ops[1].reg); |
| 2345 | else { | 2345 | else { |
| 2346 | expect("(first source operand) register"); | 2346 | expect(S, "(first source operand) register"); |
| 2347 | return; | 2347 | return; |
| 2348 | } | 2348 | } |
| 2349 | if (tok == ']') { | 2349 | if (S->tccpp_tok == ']') { |
| 2350 | next(); | 2350 | next(S); |
| 2351 | closed_bracket = 1; | 2351 | closed_bracket = 1; |
| 2352 | // exclam = 1; // implicit in hardware; don't do it in software | 2352 | // exclam = 1; // implicit in hardware; don't do it in software |
| 2353 | } | 2353 | } |
| 2354 | if (tok == ',') { | 2354 | if (S->tccpp_tok == ',') { |
| 2355 | next(); // skip ',' | 2355 | next(S); // skip ',' |
| 2356 | if (tok == '-') { | 2356 | if (S->tccpp_tok == '-') { |
| 2357 | op2_minus = 1; | 2357 | op2_minus = 1; |
| 2358 | next(); | 2358 | next(S); |
| 2359 | } | 2359 | } |
| 2360 | parse_operand(s1, &ops[2]); | 2360 | parse_operand(S, &ops[2]); |
| 2361 | } else { | 2361 | } else { |
| 2362 | // end of input expression in brackets--assume 0 offset | 2362 | // end of input expression in brackets--assume 0 offset |
| 2363 | ops[2].type = OP_IM8; | 2363 | ops[2].type = OP_IM8; |
| @@ -2365,20 +2365,20 @@ static void asm_misc_single_data_transfer_opcode(TCCState *s1, int token) · 1 unmodified line | |||
| 2365 | opcode |= 1 << 24; // add offset before transfer | 2365 | opcode |= 1 << 24; // add offset before transfer |
| 2366 | } | 2366 | } |
| 2367 | if (!closed_bracket) { | 2367 | if (!closed_bracket) { |
| 2368 | if (tok != ']') | 2368 | if (S->tccpp_tok != ']') |
| 2369 | expect("']'"); | 2369 | expect(S, "']'"); |
| 2370 | else | 2370 | else |
| 2371 | next(); // skip ']' | 2371 | next(S); // skip ']' |
| 2372 | opcode |= 1 << 24; // add offset before transfer | 2372 | opcode |= 1 << 24; // add offset before transfer |
| 2373 | if (tok == '!') { | 2373 | if (S->tccpp_tok == '!') { |
| 2374 | exclam = 1; | 2374 | exclam = 1; |
| 2375 | next(); // skip '!' | 2375 | next(S); // skip '!' |
| 2376 | } | 2376 | } |
| 2377 | } | 2377 | } |
| 2378 | 2378 | ||
| 2379 | if (exclam) { | 2379 | if (exclam) { |
| 2380 | if ((opcode & (1 << 24)) == 0) { | 2380 | if ((opcode & (1 << 24)) == 0) { |
| 2381 | tcc_error("result of '%s' would be unpredictable here", get_tok_str(token, NULL)); | 2381 | tcc_error(S, "result of '%s' would be unpredictable here", get_tok_str(S, token, NULL)); |
| 2382 | return; | 2382 | return; |
| 2383 | } | 2383 | } |
| 2384 | opcode |= 1 << 21; // write offset back into register | 2384 | opcode |= 1 << 21; // write offset back into register |
| @@ -2387,11 +2387,11 @@ static void asm_misc_single_data_transfer_opcode(TCCState *s1, int token) · 2 unmodified lines | |||
| 2387 | if (ops[2].type == OP_IM32 || ops[2].type == OP_IM8 || ops[2].type == OP_IM8N) { | 2387 | if (ops[2].type == OP_IM32 || ops[2].type == OP_IM8 || ops[2].type == OP_IM8N) { |
| 2388 | int v = ops[2].e.v; | 2388 | int v = ops[2].e.v; |
| 2389 | if (op2_minus) | 2389 | if (op2_minus) |
| 2390 | tcc_error("minus before '#' not supported for immediate values"); | 2390 | tcc_error(S, "minus before '#' not supported for immediate values"); |
| 2391 | if (v >= 0) { | 2391 | if (v >= 0) { |
| 2392 | opcode |= 1 << 23; // up | 2392 | opcode |= 1 << 23; // up |
| 2393 | if (v >= 0x100) | 2393 | if (v >= 0x100) |
| 2394 | tcc_error("offset out of range for '%s'", get_tok_str(token, NULL)); | 2394 | tcc_error(S, "offset out of range for '%s'", get_tok_str(S, token, NULL)); |
| 2395 | else { | 2395 | else { |
| 2396 | // bits 11...8: immediate hi nibble | 2396 | // bits 11...8: immediate hi nibble |
| 2397 | // bits 3...0: immediate lo nibble | 2397 | // bits 3...0: immediate lo nibble |
| @@ -2400,7 +2400,7 @@ static void asm_misc_single_data_transfer_opcode(TCCState *s1, int token) · 2 unmodified lines | |||
| 2400 | } | 2400 | } |
| 2401 | } else { // down | 2401 | } else { // down |
| 2402 | if (v <= -0x100) | 2402 | if (v <= -0x100) |
| 2403 | tcc_error("offset out of range for '%s'", get_tok_str(token, NULL)); | 2403 | tcc_error(S, "offset out of range for '%s'", get_tok_str(S, token, NULL)); |
| 2404 | else { | 2404 | else { |
| 2405 | v = -v; | 2405 | v = -v; |
| 2406 | // bits 11...8: immediate hi nibble | 2406 | // bits 11...8: immediate hi nibble |
| @@ -2415,7 +2415,7 @@ static void asm_misc_single_data_transfer_opcode(TCCState *s1, int token) · 8 unmodified lines | |||
| 2415 | opcode |= 1 << 23; // up | 2415 | opcode |= 1 << 23; // up |
| 2416 | opcode |= ops[2].reg; | 2416 | opcode |= ops[2].reg; |
| 2417 | } else | 2417 | } else |
| 2418 | expect("register"); | 2418 | expect(S, "register"); |
| 2419 | 2419 | ||
| 2420 | switch (ARM_INSTRUCTION_GROUP(token)) { | 2420 | switch (ARM_INSTRUCTION_GROUP(token)) { |
| 2421 | case TOK_ASM_ldrsheq: | 2421 | case TOK_ASM_ldrsheq: |
| @@ -2424,34 +2424,34 @@ static void asm_misc_single_data_transfer_opcode(TCCState *s1, int token) · 2 unmodified lines | |||
| 2424 | case TOK_ASM_ldrsbeq: | 2424 | case TOK_ASM_ldrsbeq: |
| 2425 | opcode |= 1 << 6; // sign extend | 2425 | opcode |= 1 << 6; // sign extend |
| 2426 | opcode |= 1 << 20; // L | 2426 | opcode |= 1 << 20; // L |
| 2427 | asm_emit_opcode(token, opcode); | 2427 | asm_emit_opcode(S, token, opcode); |
| 2428 | break; | 2428 | break; |
| 2429 | case TOK_ASM_ldrheq: | 2429 | case TOK_ASM_ldrheq: |
| 2430 | opcode |= 1 << 5; // halfword, not byte | 2430 | opcode |= 1 << 5; // halfword, not byte |
| 2431 | opcode |= 1 << 20; // L | 2431 | opcode |= 1 << 20; // L |
| 2432 | asm_emit_opcode(token, opcode); | 2432 | asm_emit_opcode(S, token, opcode); |
| 2433 | break; | 2433 | break; |
| 2434 | case TOK_ASM_strheq: | 2434 | case TOK_ASM_strheq: |
| 2435 | opcode |= 1 << 5; // halfword, not byte | 2435 | opcode |= 1 << 5; // halfword, not byte |
| 2436 | asm_emit_opcode(token, opcode); | 2436 | asm_emit_opcode(S, token, opcode); |
| 2437 | break; | 2437 | break; |
| 2438 | } | 2438 | } |
| 2439 | } | 2439 | } |
| 2440 | 2440 | ||
| 2441 | /* Note: almost dupe of encbranch in arm-gen.c */ | 2441 | /* Note: almost dupe of encbranch in arm-gen.c */ |
| 2442 | static uint32_t encbranchoffset(int pos, int addr, int fail) | 2442 | static uint32_t encbranchoffset(TCCState* S, int pos, int addr, int fail) |
| 2443 | { | 2443 | { |
| 2444 | addr-=pos+8; | 2444 | addr-=pos+8; |
| 2445 | addr/=4; | 2445 | addr/=4; |
| 2446 | if(addr>=0x7fffff || addr<-0x800000) { | 2446 | if(addr>=0x7fffff || addr<-0x800000) { |
| 2447 | if(fail) | 2447 | if(fail) |
| 2448 | tcc_error("branch offset is too far"); | 2448 | tcc_error(S, "branch offset is too far"); |
| 2449 | return 0; | 2449 | return 0; |
| 2450 | } | 2450 | } |
| 2451 | return /*not 0x0A000000|*/(addr&0xffffff); | 2451 | return /*not 0x0A000000|*/(addr&0xffffff); |
| 2452 | } | 2452 | } |
| 2453 | 2453 | ||
| 2454 | static void asm_branch_opcode(TCCState *s1, int token) | 2454 | static void asm_branch_opcode(TCCState *S, int token) |
| 2455 | { | 2455 | { |
| 2456 | int jmp_disp = 0; | 2456 | int jmp_disp = 0; |
| 2457 | Operand op; | 2457 | Operand op; |
| @@ -2461,63 +2461,63 @@ static void asm_branch_opcode(TCCState *s1, int token) · 3 unmodified lines | |||
| 2461 | switch (ARM_INSTRUCTION_GROUP(token)) { | 2461 | switch (ARM_INSTRUCTION_GROUP(token)) { |
| 2462 | case TOK_ASM_beq: | 2462 | case TOK_ASM_beq: |
| 2463 | case TOK_ASM_bleq: | 2463 | case TOK_ASM_bleq: |
| 2464 | asm_expr(s1, &e); | 2464 | asm_expr(S, &e); |
| 2465 | esym = elfsym(e.sym); | 2465 | esym = elfsym(S, e.sym); |
| 2466 | if (!esym || esym->st_shndx != cur_text_section->sh_num) { | 2466 | if (!esym || esym->st_shndx != cur_text_section->sh_num) { |
| 2467 | tcc_error("invalid branch target"); | 2467 | tcc_error(S, "invalid branch target"); |
| 2468 | return; | 2468 | return; |
| 2469 | } | 2469 | } |
| 2470 | jmp_disp = encbranchoffset(ind, e.v + esym->st_value, 1); | 2470 | jmp_disp = encbranchoffset(S, S->tccgen_ind, e.v + esym->st_value, 1); |
| 2471 | break; | 2471 | break; |
| 2472 | default: | 2472 | default: |
| 2473 | parse_operand(s1, &op); | 2473 | parse_operand(S, &op); |
| 2474 | break; | 2474 | break; |
| 2475 | } | 2475 | } |
| 2476 | switch (ARM_INSTRUCTION_GROUP(token)) { | 2476 | switch (ARM_INSTRUCTION_GROUP(token)) { |
| 2477 | case TOK_ASM_beq: | 2477 | case TOK_ASM_beq: |
| 2478 | asm_emit_opcode(token, (0xa << 24) | (jmp_disp & 0xffffff)); | 2478 | asm_emit_opcode(S, token, (0xa << 24) | (jmp_disp & 0xffffff)); |
| 2479 | break; | 2479 | break; |
| 2480 | case TOK_ASM_bleq: | 2480 | case TOK_ASM_bleq: |
| 2481 | asm_emit_opcode(token, (0xb << 24) | (jmp_disp & 0xffffff)); | 2481 | asm_emit_opcode(S, token, (0xb << 24) | (jmp_disp & 0xffffff)); |
| 2482 | break; | 2482 | break; |
| 2483 | case TOK_ASM_bxeq: | 2483 | case TOK_ASM_bxeq: |
| 2484 | if (op.type != OP_REG32) | 2484 | if (op.type != OP_REG32) |
| 2485 | expect("register"); | 2485 | expect(S, "register"); |
| 2486 | else | 2486 | else |
| 2487 | asm_emit_opcode(token, (0x12fff1 << 4) | op.reg); | 2487 | asm_emit_opcode(S, token, (0x12fff1 << 4) | op.reg); |
| 2488 | break; | 2488 | break; |
| 2489 | case TOK_ASM_blxeq: | 2489 | case TOK_ASM_blxeq: |
| 2490 | if (op.type != OP_REG32) | 2490 | if (op.type != OP_REG32) |
| 2491 | expect("register"); | 2491 | expect(S, "register"); |
| 2492 | else | 2492 | else |
| 2493 | asm_emit_opcode(token, (0x12fff3 << 4) | op.reg); | 2493 | asm_emit_opcode(S, token, (0x12fff3 << 4) | op.reg); |
| 2494 | break; | 2494 | break; |
| 2495 | default: | 2495 | default: |
| 2496 | expect("branch instruction"); | 2496 | expect(S, "branch instruction"); |
| 2497 | } | 2497 | } |
| 2498 | } | 2498 | } |
| 2499 | 2499 | ||
| 2500 | ST_FUNC void asm_opcode(TCCState *s1, int token) | 2500 | ST_FUNC void asm_opcode(TCCState *S, int token) |
| 2501 | { | 2501 | { |
| 2502 | while (token == TOK_LINEFEED) { | 2502 | while (token == TOK_LINEFEED) { |
| 2503 | next(); | 2503 | next(S); |
| 2504 | token = tok; | 2504 | token = S->tccpp_tok; |
| 2505 | } | 2505 | } |
| 2506 | if (token == TOK_EOF) | 2506 | if (token == TOK_EOF) |
| 2507 | return; | 2507 | return; |
| 2508 | if (token < TOK_ASM_nopeq) { // no condition code | 2508 | if (token < TOK_ASM_nopeq) { // no condition code |
| 2509 | switch (token) { | 2509 | switch (token) { |
| 2510 | case TOK_ASM_cdp2: | 2510 | case TOK_ASM_cdp2: |
| 2511 | asm_coprocessor_opcode(s1, token); | 2511 | asm_coprocessor_opcode(S, token); |
| 2512 | return; | 2512 | return; |
| 2513 | case TOK_ASM_ldc2: | 2513 | case TOK_ASM_ldc2: |
| 2514 | case TOK_ASM_ldc2l: | 2514 | case TOK_ASM_ldc2l: |
| 2515 | case TOK_ASM_stc2: | 2515 | case TOK_ASM_stc2: |
| 2516 | case TOK_ASM_stc2l: | 2516 | case TOK_ASM_stc2l: |
| 2517 | asm_coprocessor_data_transfer_opcode(s1, token); | 2517 | asm_coprocessor_data_transfer_opcode(S, token); |
| 2518 | return; | 2518 | return; |
| 2519 | default: | 2519 | default: |
| 2520 | expect("instruction"); | 2520 | expect(S, "instruction"); |
| 2521 | return; | 2521 | return; |
| 2522 | } | 2522 | } |
| 2523 | } | 2523 | } |
| @@ -2535,22 +2535,22 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 11 unmodified lines | |||
| 2535 | case TOK_ASM_ldmdbeq: | 2535 | case TOK_ASM_ldmdbeq: |
| 2536 | case TOK_ASM_stmibeq: | 2536 | case TOK_ASM_stmibeq: |
| 2537 | case TOK_ASM_ldmibeq: | 2537 | case TOK_ASM_ldmibeq: |
| 2538 | asm_block_data_transfer_opcode(s1, token); | 2538 | asm_block_data_transfer_opcode(S, token); |
| 2539 | return; | 2539 | return; |
| 2540 | case TOK_ASM_nopeq: | 2540 | case TOK_ASM_nopeq: |
| 2541 | case TOK_ASM_wfeeq: | 2541 | case TOK_ASM_wfeeq: |
| 2542 | case TOK_ASM_wfieq: | 2542 | case TOK_ASM_wfieq: |
| 2543 | asm_nullary_opcode(token); | 2543 | asm_nullary_opcode(S, token); |
| 2544 | return; | 2544 | return; |
| 2545 | case TOK_ASM_swieq: | 2545 | case TOK_ASM_swieq: |
| 2546 | case TOK_ASM_svceq: | 2546 | case TOK_ASM_svceq: |
| 2547 | asm_unary_opcode(s1, token); | 2547 | asm_unary_opcode(S, token); |
| 2548 | return; | 2548 | return; |
| 2549 | case TOK_ASM_beq: | 2549 | case TOK_ASM_beq: |
| 2550 | case TOK_ASM_bleq: | 2550 | case TOK_ASM_bleq: |
| 2551 | case TOK_ASM_bxeq: | 2551 | case TOK_ASM_bxeq: |
| 2552 | case TOK_ASM_blxeq: | 2552 | case TOK_ASM_blxeq: |
| 2553 | asm_branch_opcode(s1, token); | 2553 | asm_branch_opcode(S, token); |
| 2554 | return; | 2554 | return; |
| 2555 | case TOK_ASM_clzeq: | 2555 | case TOK_ASM_clzeq: |
| 2556 | case TOK_ASM_sxtbeq: | 2556 | case TOK_ASM_sxtbeq: |
| @@ -2559,7 +2559,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 2 unmodified lines | |||
| 2559 | case TOK_ASM_uxtheq: | 2559 | case TOK_ASM_uxtheq: |
| 2560 | case TOK_ASM_movteq: | 2560 | case TOK_ASM_movteq: |
| 2561 | case TOK_ASM_movweq: | 2561 | case TOK_ASM_movweq: |
| 2562 | asm_binary_opcode(s1, token); | 2562 | asm_binary_opcode(S, token); |
| 2563 | return; | 2563 | return; |
| 2564 | 2564 | ||
| 2565 | case TOK_ASM_ldreq: | 2565 | case TOK_ASM_ldreq: |
| @@ -2570,14 +2570,14 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 4 unmodified lines | |||
| 2570 | case TOK_ASM_ldrexbeq: | 2570 | case TOK_ASM_ldrexbeq: |
| 2571 | case TOK_ASM_strexeq: | 2571 | case TOK_ASM_strexeq: |
| 2572 | case TOK_ASM_strexbeq: | 2572 | case TOK_ASM_strexbeq: |
| 2573 | asm_single_data_transfer_opcode(s1, token); | 2573 | asm_single_data_transfer_opcode(S, token); |
| 2574 | return; | 2574 | return; |
| 2575 | 2575 | ||
| 2576 | case TOK_ASM_ldrheq: | 2576 | case TOK_ASM_ldrheq: |
| 2577 | case TOK_ASM_ldrsheq: | 2577 | case TOK_ASM_ldrsheq: |
| 2578 | case TOK_ASM_ldrsbeq: | 2578 | case TOK_ASM_ldrsbeq: |
| 2579 | case TOK_ASM_strheq: | 2579 | case TOK_ASM_strheq: |
| 2580 | asm_misc_single_data_transfer_opcode(s1, token); | 2580 | asm_misc_single_data_transfer_opcode(S, token); |
| 2581 | return; | 2581 | return; |
| 2582 | 2582 | ||
| 2583 | case TOK_ASM_andeq: | 2583 | case TOK_ASM_andeq: |
| @@ -2612,7 +2612,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 28 unmodified lines | |||
| 2612 | case TOK_ASM_movseq: | 2612 | case TOK_ASM_movseq: |
| 2613 | case TOK_ASM_bicseq: | 2613 | case TOK_ASM_bicseq: |
| 2614 | case TOK_ASM_mvnseq: | 2614 | case TOK_ASM_mvnseq: |
| 2615 | asm_data_processing_opcode(s1, token); | 2615 | asm_data_processing_opcode(S, token); |
| 2616 | return; | 2616 | return; |
| 2617 | 2617 | ||
| 2618 | case TOK_ASM_lsleq: | 2618 | case TOK_ASM_lsleq: |
| @@ -2625,14 +2625,14 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 6 unmodified lines | |||
| 2625 | case TOK_ASM_rorseq: | 2625 | case TOK_ASM_rorseq: |
| 2626 | case TOK_ASM_rrxseq: | 2626 | case TOK_ASM_rrxseq: |
| 2627 | case TOK_ASM_rrxeq: | 2627 | case TOK_ASM_rrxeq: |
| 2628 | asm_shift_opcode(s1, token); | 2628 | asm_shift_opcode(S, token); |
| 2629 | return; | 2629 | return; |
| 2630 | 2630 | ||
| 2631 | case TOK_ASM_muleq: | 2631 | case TOK_ASM_muleq: |
| 2632 | case TOK_ASM_mulseq: | 2632 | case TOK_ASM_mulseq: |
| 2633 | case TOK_ASM_mlaeq: | 2633 | case TOK_ASM_mlaeq: |
| 2634 | case TOK_ASM_mlaseq: | 2634 | case TOK_ASM_mlaseq: |
| 2635 | asm_multiplication_opcode(s1, token); | 2635 | asm_multiplication_opcode(S, token); |
| 2636 | return; | 2636 | return; |
| 2637 | 2637 | ||
| 2638 | case TOK_ASM_smulleq: | 2638 | case TOK_ASM_smulleq: |
| @@ -2643,26 +2643,26 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 4 unmodified lines | |||
| 2643 | case TOK_ASM_smlalseq: | 2643 | case TOK_ASM_smlalseq: |
| 2644 | case TOK_ASM_umlaleq: | 2644 | case TOK_ASM_umlaleq: |
| 2645 | case TOK_ASM_umlalseq: | 2645 | case TOK_ASM_umlalseq: |
| 2646 | asm_long_multiplication_opcode(s1, token); | 2646 | asm_long_multiplication_opcode(S, token); |
| 2647 | return; | 2647 | return; |
| 2648 | 2648 | ||
| 2649 | case TOK_ASM_cdpeq: | 2649 | case TOK_ASM_cdpeq: |
| 2650 | case TOK_ASM_mcreq: | 2650 | case TOK_ASM_mcreq: |
| 2651 | case TOK_ASM_mrceq: | 2651 | case TOK_ASM_mrceq: |
| 2652 | asm_coprocessor_opcode(s1, token); | 2652 | asm_coprocessor_opcode(S, token); |
| 2653 | return; | 2653 | return; |
| 2654 | 2654 | ||
| 2655 | case TOK_ASM_ldceq: | 2655 | case TOK_ASM_ldceq: |
| 2656 | case TOK_ASM_ldcleq: | 2656 | case TOK_ASM_ldcleq: |
| 2657 | case TOK_ASM_stceq: | 2657 | case TOK_ASM_stceq: |
| 2658 | case TOK_ASM_stcleq: | 2658 | case TOK_ASM_stcleq: |
| 2659 | asm_coprocessor_data_transfer_opcode(s1, token); | 2659 | asm_coprocessor_data_transfer_opcode(S, token); |
| 2660 | return; | 2660 | return; |
| 2661 | 2661 | ||
| 2662 | #if defined(TCC_ARM_VFP) | 2662 | #if defined(TCC_ARM_VFP) |
| 2663 | case TOK_ASM_vldreq: | 2663 | case TOK_ASM_vldreq: |
| 2664 | case TOK_ASM_vstreq: | 2664 | case TOK_ASM_vstreq: |
| 2665 | asm_floating_point_single_data_transfer_opcode(s1, token); | 2665 | asm_floating_point_single_data_transfer_opcode(S, token); |
| 2666 | return; | 2666 | return; |
| 2667 | 2667 | ||
| 2668 | case TOK_ASM_vmlaeq_f32: | 2668 | case TOK_ASM_vmlaeq_f32: |
| @@ -2695,7 +2695,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 26 unmodified lines | |||
| 2695 | case TOK_ASM_vcmpeq_f64: | 2695 | case TOK_ASM_vcmpeq_f64: |
| 2696 | case TOK_ASM_vcmpeeq_f64: | 2696 | case TOK_ASM_vcmpeeq_f64: |
| 2697 | case TOK_ASM_vmoveq_f64: | 2697 | case TOK_ASM_vmoveq_f64: |
| 2698 | asm_floating_point_data_processing_opcode(s1, token); | 2698 | asm_floating_point_data_processing_opcode(S, token); |
| 2699 | return; | 2699 | return; |
| 2700 | 2700 | ||
| 2701 | case TOK_ASM_vcvtreq_s32_f32: | 2701 | case TOK_ASM_vcvtreq_s32_f32: |
| @@ -2712,7 +2712,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 10 unmodified lines | |||
| 2712 | case TOK_ASM_vcvteq_f32_u32: | 2712 | case TOK_ASM_vcvteq_f32_u32: |
| 2713 | case TOK_ASM_vcvteq_f64_f32: | 2713 | case TOK_ASM_vcvteq_f64_f32: |
| 2714 | case TOK_ASM_vcvteq_f32_f64: | 2714 | case TOK_ASM_vcvteq_f32_f64: |
| 2715 | asm_floating_point_vcvt_data_processing_opcode(s1, token); | 2715 | asm_floating_point_vcvt_data_processing_opcode(S, token); |
| 2716 | return; | 2716 | return; |
| 2717 | 2717 | ||
| 2718 | case TOK_ASM_vpusheq: | 2718 | case TOK_ASM_vpusheq: |
| @@ -2723,21 +2723,21 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 4 unmodified lines | |||
| 2723 | case TOK_ASM_vstmeq: | 2723 | case TOK_ASM_vstmeq: |
| 2724 | case TOK_ASM_vstmiaeq: | 2724 | case TOK_ASM_vstmiaeq: |
| 2725 | case TOK_ASM_vstmdbeq: | 2725 | case TOK_ASM_vstmdbeq: |
| 2726 | asm_floating_point_block_data_transfer_opcode(s1, token); | 2726 | asm_floating_point_block_data_transfer_opcode(S, token); |
| 2727 | return; | 2727 | return; |
| 2728 | 2728 | ||
| 2729 | case TOK_ASM_vmsreq: | 2729 | case TOK_ASM_vmsreq: |
| 2730 | case TOK_ASM_vmrseq: | 2730 | case TOK_ASM_vmrseq: |
| 2731 | asm_floating_point_status_register_opcode(s1, token); | 2731 | asm_floating_point_status_register_opcode(S, token); |
| 2732 | return; | 2732 | return; |
| 2733 | #endif | 2733 | #endif |
| 2734 | 2734 | ||
| 2735 | default: | 2735 | default: |
| 2736 | expect("known instruction"); | 2736 | expect(S, "known instruction"); |
| 2737 | } | 2737 | } |
| 2738 | } | 2738 | } |
| 2739 | 2739 | ||
| 2740 | ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier) | 2740 | ST_FUNC void subst_asm_operand(TCCState* S, CString *add_str, SValue *sv, int modifier) |
| 2741 | { | 2741 | { |
| 2742 | int r, reg, size, val; | 2742 | int r, reg, size, val; |
| 2743 | char buf[64]; | 2743 | char buf[64]; |
| @@ -2746,45 +2746,45 @@ ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier) · 2 unmodified lines | |||
| 2746 | if ((r & VT_VALMASK) == VT_CONST) { | 2746 | if ((r & VT_VALMASK) == VT_CONST) { |
| 2747 | if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n' && | 2747 | if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n' && |
| 2748 | modifier != 'P') | 2748 | modifier != 'P') |
| 2749 | cstr_ccat(add_str, '#'); | 2749 | cstr_ccat(S, add_str, '#'); |
| 2750 | if (r & VT_SYM) { | 2750 | if (r & VT_SYM) { |
| 2751 | const char *name = get_tok_str(sv->sym->v, NULL); | 2751 | const char *name = get_tok_str(S, sv->sym->v, NULL); |
| 2752 | if (sv->sym->v >= SYM_FIRST_ANOM) { | 2752 | if (sv->sym->v >= SYM_FIRST_ANOM) { |
| 2753 | /* In case of anonymous symbols ("L.42", used | 2753 | /* In case of anonymous symbols ("L.42", used |
| 2754 | for static data labels) we can't find them | 2754 | for static data labels) we can't find them |
| 2755 | in the C symbol table when later looking up | 2755 | in the C symbol table when later looking up |
| 2756 | this name. So enter them now into the asm label | 2756 | this name. So enter them now into the asm label |
| 2757 | list when we still know the symbol. */ | 2757 | list when we still know the symbol. */ |
| 2758 | get_asm_sym(tok_alloc(name, strlen(name))->tok, sv->sym); | 2758 | get_asm_sym(S, tok_alloc(S, name, strlen(name))->tok, sv->sym); |
| 2759 | } | 2759 | } |
| 2760 | if (tcc_state->leading_underscore) | 2760 | if (S->leading_underscore) |
| 2761 | cstr_ccat(add_str, '_'); | 2761 | cstr_ccat(S, add_str, '_'); |
| 2762 | cstr_cat(add_str, name, -1); | 2762 | cstr_cat(S, add_str, name, -1); |
| 2763 | if ((uint32_t) sv->c.i == 0) | 2763 | if ((uint32_t) sv->c.i == 0) |
| 2764 | goto no_offset; | 2764 | goto no_offset; |
| 2765 | cstr_ccat(add_str, '+'); | 2765 | cstr_ccat(S, add_str, '+'); |
| 2766 | } | 2766 | } |
| 2767 | val = sv->c.i; | 2767 | val = sv->c.i; |
| 2768 | if (modifier == 'n') | 2768 | if (modifier == 'n') |
| 2769 | val = -val; | 2769 | val = -val; |
| 2770 | snprintf(buf, sizeof(buf), "%d", (int) sv->c.i); | 2770 | snprintf(buf, sizeof(buf), "%d", (int) sv->c.i); |
| 2771 | cstr_cat(add_str, buf, -1); | 2771 | cstr_cat(S, add_str, buf, -1); |
| 2772 | no_offset:; | 2772 | no_offset:; |
| 2773 | } else if ((r & VT_VALMASK) == VT_LOCAL) { | 2773 | } else if ((r & VT_VALMASK) == VT_LOCAL) { |
| 2774 | snprintf(buf, sizeof(buf), "[fp,#%d]", (int) sv->c.i); | 2774 | snprintf(buf, sizeof(buf), "[fp,#%d]", (int) sv->c.i); |
| 2775 | cstr_cat(add_str, buf, -1); | 2775 | cstr_cat(S, add_str, buf, -1); |
| 2776 | } else if (r & VT_LVAL) { | 2776 | } else if (r & VT_LVAL) { |
| 2777 | reg = r & VT_VALMASK; | 2777 | reg = r & VT_VALMASK; |
| 2778 | if (reg >= VT_CONST) | 2778 | if (reg >= VT_CONST) |
| 2779 | tcc_internal_error(""); | 2779 | tcc_internal_error(S, ""); |
| 2780 | snprintf(buf, sizeof(buf), "[%s]", | 2780 | snprintf(buf, sizeof(buf), "[%s]", |
| 2781 | get_tok_str(TOK_ASM_r0 + reg, NULL)); | 2781 | get_tok_str(S, TOK_ASM_r0 + reg, NULL)); |
| 2782 | cstr_cat(add_str, buf, -1); | 2782 | cstr_cat(S, add_str, buf, -1); |
| 2783 | } else { | 2783 | } else { |
| 2784 | /* register case */ | 2784 | /* register case */ |
| 2785 | reg = r & VT_VALMASK; | 2785 | reg = r & VT_VALMASK; |
| 2786 | if (reg >= VT_CONST) | 2786 | if (reg >= VT_CONST) |
| 2787 | tcc_internal_error(""); | 2787 | tcc_internal_error(S, ""); |
| 2788 | 2788 | ||
| 2789 | /* choose register operand size */ | 2789 | /* choose register operand size */ |
| 2790 | if ((sv->type.t & VT_BTYPE) == VT_BYTE || | 2790 | if ((sv->type.t & VT_BTYPE) == VT_BYTE || |
| @@ -2808,13 +2808,13 @@ ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier) · 17 unmodified lines | |||
| 2808 | reg = TOK_ASM_r0 + reg; | 2808 | reg = TOK_ASM_r0 + reg; |
| 2809 | break; | 2809 | break; |
| 2810 | } | 2810 | } |
| 2811 | snprintf(buf, sizeof(buf), "%s", get_tok_str(reg, NULL)); | 2811 | snprintf(buf, sizeof(buf), "%s", get_tok_str(S, reg, NULL)); |
| 2812 | cstr_cat(add_str, buf, -1); | 2812 | cstr_cat(S, add_str, buf, -1); |
| 2813 | } | 2813 | } |
| 2814 | } | 2814 | } |
| 2815 | 2815 | ||
| 2816 | /* generate prolog and epilog code for asm statement */ | 2816 | /* generate prolog and epilog code for asm statement */ |
| 2817 | ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, | 2817 | ST_FUNC void asm_gen_code(TCCState* S, ASMOperand *operands, int nb_operands, |
| 2818 | int nb_outputs, int is_output, | 2818 | int nb_outputs, int is_output, |
| 2819 | uint8_t *clobber_regs, | 2819 | uint8_t *clobber_regs, |
| 2820 | int out_reg) | 2820 | int out_reg) |
| @@ -2844,7 +2844,7 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, · 23 unmodified lines | |||
| 2844 | if (!is_output) { // prolog | 2844 | if (!is_output) { // prolog |
| 2845 | /* generate reg save code */ | 2845 | /* generate reg save code */ |
| 2846 | if (saved_regset) | 2846 | if (saved_regset) |
| 2847 | gen_le32(0xe92d0000 | saved_regset); // push {...} | 2847 | gen_le32(S, 0xe92d0000 | saved_regset); // push {...} |
| 2848 | 2848 | ||
| 2849 | /* generate load code */ | 2849 | /* generate load code */ |
| 2850 | for(i = 0; i < nb_operands; i++) { | 2850 | for(i = 0; i < nb_operands; i++) { |
| @@ -2858,12 +2858,12 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, · 7 unmodified lines | |||
| 2858 | sv = *op->vt; | 2858 | sv = *op->vt; |
| 2859 | sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL | VT_LVAL; | 2859 | sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL | VT_LVAL; |
| 2860 | sv.type.t = VT_PTR; | 2860 | sv.type.t = VT_PTR; |
| 2861 | load(op->reg, &sv); | 2861 | load(S, op->reg, &sv); |
| 2862 | } else if (i >= nb_outputs || op->is_rw) { // not write-only | 2862 | } else if (i >= nb_outputs || op->is_rw) { // not write-only |
| 2863 | /* load value in register */ | 2863 | /* load value in register */ |
| 2864 | load(op->reg, op->vt); | 2864 | load(S, op->reg, op->vt); |
| 2865 | if (op->is_llong) | 2865 | if (op->is_llong) |
| 2866 | tcc_error("long long not implemented"); | 2866 | tcc_error(S, "long long not implemented"); |
| 2867 | } | 2867 | } |
| 2868 | } | 2868 | } |
| 2869 | } | 2869 | } |
| @@ -2878,29 +2878,29 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, · 8 unmodified lines | |||
| 2878 | sv = *op->vt; | 2878 | sv = *op->vt; |
| 2879 | sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL; | 2879 | sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL; |
| 2880 | sv.type.t = VT_PTR; | 2880 | sv.type.t = VT_PTR; |
| 2881 | load(out_reg, &sv); | 2881 | load(S, out_reg, &sv); |
| 2882 | 2882 | ||
| 2883 | sv = *op->vt; | 2883 | sv = *op->vt; |
| 2884 | sv.r = (sv.r & ~VT_VALMASK) | out_reg; | 2884 | sv.r = (sv.r & ~VT_VALMASK) | out_reg; |
| 2885 | store(op->reg, &sv); | 2885 | store(S, op->reg, &sv); |
| 2886 | } | 2886 | } |
| 2887 | } else { | 2887 | } else { |
| 2888 | store(op->reg, op->vt); | 2888 | store(S, op->reg, op->vt); |
| 2889 | if (op->is_llong) | 2889 | if (op->is_llong) |
| 2890 | tcc_error("long long not implemented"); | 2890 | tcc_error(S, "long long not implemented"); |
| 2891 | } | 2891 | } |
| 2892 | } | 2892 | } |
| 2893 | } | 2893 | } |
| 2894 | 2894 | ||
| 2895 | /* generate reg restore code */ | 2895 | /* generate reg restore code */ |
| 2896 | if (saved_regset) | 2896 | if (saved_regset) |
| 2897 | gen_le32(0xe8bd0000 | saved_regset); // pop {...} | 2897 | gen_le32(S, 0xe8bd0000 | saved_regset); // pop {...} |
| 2898 | } | 2898 | } |
| 2899 | } | 2899 | } |
| 2900 | 2900 | ||
| 2901 | /* return the constraint priority (we allocate first the lowest | 2901 | /* return the constraint priority (we allocate first the lowest |
| 2902 | numbered constraints) */ | 2902 | numbered constraints) */ |
| 2903 | static inline int constraint_priority(const char *str) | 2903 | static inline int constraint_priority(TCCState* S, const char *str) |
| 2904 | { | 2904 | { |
| 2905 | int priority, c, pr; | 2905 | int priority, c, pr; |
| 2906 | 2906 | ||
| @@ -2927,7 +2927,7 @@ static inline int constraint_priority(const char *str) · 20 unmodified lines | |||
| 2927 | pr = 4; | 2927 | pr = 4; |
| 2928 | break; | 2928 | break; |
| 2929 | default: | 2929 | default: |
| 2930 | tcc_error("unknown constraint '%c'", c); | 2930 | tcc_error(S, "unknown constraint '%c'", c); |
| 2931 | pr = 0; | 2931 | pr = 0; |
| 2932 | } | 2932 | } |
| 2933 | if (pr > priority) | 2933 | if (pr > priority) |
| @@ -2956,7 +2956,7 @@ static const char *skip_constraint_modifiers(const char *p) · 22 unmodified lines | |||
| 2956 | 2956 | ||
| 2957 | #define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask) | 2957 | #define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask) |
| 2958 | 2958 | ||
| 2959 | ST_FUNC void asm_compute_constraints(ASMOperand *operands, | 2959 | ST_FUNC void asm_compute_constraints(TCCState* S, ASMOperand *operands, |
| 2960 | int nb_operands, int nb_outputs, | 2960 | int nb_operands, int nb_outputs, |
| 2961 | const uint8_t *clobber_regs, | 2961 | const uint8_t *clobber_regs, |
| 2962 | int *pout_reg) | 2962 | int *pout_reg) |
| @@ -3009,13 +3009,13 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 46 unmodified lines | |||
| 3009 | str = skip_constraint_modifiers(str); | 3009 | str = skip_constraint_modifiers(str); |
| 3010 | if (isnum(*str) || *str == '[') { | 3010 | if (isnum(*str) || *str == '[') { |
| 3011 | /* this is a reference to another constraint */ | 3011 | /* this is a reference to another constraint */ |
| 3012 | k = find_constraint(operands, nb_operands, str, NULL); | 3012 | k = find_constraint(S, operands, nb_operands, str, NULL); |
| 3013 | if ((unsigned) k >= i || i < nb_outputs) | 3013 | if ((unsigned) k >= i || i < nb_outputs) |
| 3014 | tcc_error("invalid reference in constraint %d ('%s')", | 3014 | tcc_error(S, "invalid reference in constraint %d ('%s')", |
| 3015 | i, str); | 3015 | i, str); |
| 3016 | op->ref_index = k; | 3016 | op->ref_index = k; |
| 3017 | if (operands[k].input_index >= 0) | 3017 | if (operands[k].input_index >= 0) |
| 3018 | tcc_error("cannot reference twice the same operand"); | 3018 | tcc_error(S, "cannot reference twice the same operand"); |
| 3019 | operands[k].input_index = i; | 3019 | operands[k].input_index = i; |
| 3020 | op->priority = 5; | 3020 | op->priority = 5; |
| 3021 | } else if ((op->vt->r & VT_VALMASK) == VT_LOCAL | 3021 | } else if ((op->vt->r & VT_VALMASK) == VT_LOCAL |
| @@ -3024,7 +3024,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 2 unmodified lines | |||
| 3024 | op->priority = 1; | 3024 | op->priority = 1; |
| 3025 | op->reg = reg; | 3025 | op->reg = reg; |
| 3026 | } else { | 3026 | } else { |
| 3027 | op->priority = constraint_priority(str); | 3027 | op->priority = constraint_priority(S, str); |
| 3028 | } | 3028 | } |
| 3029 | } | 3029 | } |
| 3030 | 3030 | ||
| @@ -3073,7 +3073,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 42 unmodified lines | |||
| 3073 | if (op->reg >= 0) { | 3073 | if (op->reg >= 0) { |
| 3074 | if (is_reg_allocated(op->reg)) | 3074 | if (is_reg_allocated(op->reg)) |
| 3075 | tcc_error | 3075 | tcc_error |
| 3076 | ("asm regvar requests register that's taken already"); | 3076 | (S, "asm regvar requests register that's taken already"); |
| 3077 | reg = op->reg; | 3077 | reg = op->reg; |
| 3078 | goto reg_found; | 3078 | goto reg_found; |
| 3079 | } | 3079 | } |
| @@ -3087,7 +3087,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 7 unmodified lines | |||
| 3087 | /* FALL THRU */ | 3087 | /* FALL THRU */ |
| 3088 | case '&': // Operand is clobbered before the instruction is done using the input operands | 3088 | case '&': // Operand is clobbered before the instruction is done using the input operands |
| 3089 | if (j >= nb_outputs) | 3089 | if (j >= nb_outputs) |
| 3090 | tcc_error("'%c' modifier can only be applied to outputs", | 3090 | tcc_error(S, "'%c' modifier can only be applied to outputs", |
| 3091 | c); | 3091 | c); |
| 3092 | reg_mask = REG_IN_MASK | REG_OUT_MASK; | 3092 | reg_mask = REG_IN_MASK | REG_OUT_MASK; |
| 3093 | goto try_next; | 3093 | goto try_next; |
| @@ -3147,7 +3147,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 53 unmodified lines | |||
| 3147 | } | 3147 | } |
| 3148 | break; | 3148 | break; |
| 3149 | default: | 3149 | default: |
| 3150 | tcc_error("asm constraint %d ('%s') could not be satisfied", | 3150 | tcc_error(S, "asm constraint %d ('%s') could not be satisfied", |
| 3151 | j, op->constraint); | 3151 | j, op->constraint); |
| 3152 | break; | 3152 | break; |
| 3153 | } | 3153 | } |
| @@ -3169,7 +3169,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 15 unmodified lines | |||
| 3169 | if (!(regs_allocated[reg] & REG_OUT_MASK)) | 3169 | if (!(regs_allocated[reg] & REG_OUT_MASK)) |
| 3170 | goto reg_found2; | 3170 | goto reg_found2; |
| 3171 | } | 3171 | } |
| 3172 | tcc_error("could not find free output register for reloading"); | 3172 | tcc_error(S, "could not find free output register for reloading"); |
| 3173 | reg_found2: | 3173 | reg_found2: |
| 3174 | *pout_reg = reg; | 3174 | *pout_reg = reg; |
| 3175 | break; | 3175 | break; |
| @@ -3183,7 +3183,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 7 unmodified lines | |||
| 3183 | op = &operands[j]; | 3183 | op = &operands[j]; |
| 3184 | printf("%%%d [%s]: \"%s\" r=0x%04x reg=%d\n", | 3184 | printf("%%%d [%s]: \"%s\" r=0x%04x reg=%d\n", |
| 3185 | j, | 3185 | j, |
| 3186 | op->id ? get_tok_str(op->id, NULL) : "", | 3186 | op->id ? get_tok_str(S, op->id, NULL) : "", |
| 3187 | op->constraint, op->vt->r, op->reg); | 3187 | op->constraint, op->vt->r, op->reg); |
| 3188 | } | 3188 | } |
| 3189 | if (*pout_reg >= 0) | 3189 | if (*pout_reg >= 0) |
| @@ -3191,7 +3191,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 1 unmodified line | |||
| 3191 | #endif | 3191 | #endif |
| 3192 | } | 3192 | } |
| 3193 | 3193 | ||
| 3194 | ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str) | 3194 | ST_FUNC void asm_clobber(TCCState* S, uint8_t *clobber_regs, const char *str) |
| 3195 | { | 3195 | { |
| 3196 | int reg; | 3196 | int reg; |
| 3197 | TokenSym *ts; | 3197 | TokenSym *ts; |
| @@ -3200,17 +3200,17 @@ ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str) · 2 unmodified lines | |||
| 3200 | !strcmp(str, "cc") || | 3200 | !strcmp(str, "cc") || |
| 3201 | !strcmp(str, "flags")) | 3201 | !strcmp(str, "flags")) |
| 3202 | return; | 3202 | return; |
| 3203 | ts = tok_alloc(str, strlen(str)); | 3203 | ts = tok_alloc(S, str, strlen(str)); |
| 3204 | reg = asm_parse_regvar(ts->tok); | 3204 | reg = asm_parse_regvar(S, ts->tok); |
| 3205 | if (reg == -1) { | 3205 | if (reg == -1) { |
| 3206 | tcc_error("invalid clobber register '%s'", str); | 3206 | tcc_error(S, "invalid clobber register '%s'", str); |
| 3207 | } | 3207 | } |
| 3208 | clobber_regs[reg] = 1; | 3208 | clobber_regs[reg] = 1; |
| 3209 | } | 3209 | } |
| 3210 | 3210 | ||
| 3211 | /* If T refers to a register then return the register number and type. | 3211 | /* If T refers to a register then return the register number and type. |
| 3212 | Otherwise return -1. */ | 3212 | Otherwise return -1. */ |
| 3213 | ST_FUNC int asm_parse_regvar (int t) | 3213 | ST_FUNC int asm_parse_regvar (TCCState *S, int t) |
| 3214 | { | 3214 | { |
| 3215 | if (t >= TOK_ASM_r0 && t <= TOK_ASM_pc) { /* register name */ | 3215 | if (t >= TOK_ASM_r0 && t <= TOK_ASM_pc) { /* register name */ |
| 3216 | switch (t) { | 3216 | switch (t) { |
| @@ -179,24 +179,17 @@ ST_DATA const int reg_classes[NB_REGS] = { · 178 unmodified lines | |||
| 179 | static int func_sub_sp_offset, last_itod_magic; | 179 | static int func_sub_sp_offset, last_itod_magic; |
| 180 | static int leaffunc; | 180 | static int leaffunc; |
| 181 | 181 | ||
| 182 | #if defined(CONFIG_TCC_BCHECK) | ||
| 183 | static addr_t func_bound_offset; | ||
| 184 | static unsigned long func_bound_ind; | ||
| 185 | ST_DATA int func_bound_add_epilog; | ||
| 186 | #endif | ||
| 187 | |||
| 188 | #if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP) | 182 | #if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP) |
| 189 | static CType float_type, double_type, func_float_type, func_double_type; | 183 | ST_FUNC void arm_init(TCCState *S) |
| 190 | ST_FUNC void arm_init(struct TCCState *s) | ||
| 191 | { | 184 | { |
| 192 | float_type.t = VT_FLOAT; | 185 | S->armgen_float_type.t = VT_FLOAT; |
| 193 | double_type.t = VT_DOUBLE; | 186 | S->armgen_double_type.t = VT_DOUBLE; |
| 194 | func_float_type.t = VT_FUNC; | 187 | S->armgen_func_float_type.t = VT_FUNC; |
| 195 | func_float_type.ref = sym_push(SYM_FIELD, &float_type, FUNC_CDECL, FUNC_OLD); | 188 | S->armgen_func_float_type.ref = sym_push(S, SYM_FIELD, &S->armgen_float_type, FUNC_CDECL, FUNC_OLD); |
| 196 | func_double_type.t = VT_FUNC; | 189 | S->armgen_func_double_type.t = VT_FUNC; |
| 197 | func_double_type.ref = sym_push(SYM_FIELD, &double_type, FUNC_CDECL, FUNC_OLD); | 190 | S->armgen_func_double_type.ref = sym_push(S, SYM_FIELD, &S->armgen_double_type, FUNC_CDECL, FUNC_OLD); |
| 198 | 191 | ||
| 199 | float_abi = s->float_abi; | 192 | float_abi = S->float_abi; |
| 200 | #ifndef TCC_ARM_HARDFLOAT | 193 | #ifndef TCC_ARM_HARDFLOAT |
| 201 | // XXX: Works on OpenBSD | 194 | // XXX: Works on OpenBSD |
| 202 | // # warning "soft float ABI currently not supported: default to softfp" | 195 | // # warning "soft float ABI currently not supported: default to softfp" |
| @@ -223,15 +216,15 @@ ST_FUNC void arm_init(struct TCCState *s) · 20 unmodified lines | |||
| 223 | 216 | ||
| 224 | #define CHECK_R(r) ((r) >= TREG_R0 && (r) <= TREG_LR) | 217 | #define CHECK_R(r) ((r) >= TREG_R0 && (r) <= TREG_LR) |
| 225 | 218 | ||
| 226 | static int two2mask(int a,int b) { | 219 | static int two2mask(TCCState* S, int a,int b) { |
| 227 | if (!CHECK_R(a) || !CHECK_R(b)) | 220 | if (!CHECK_R(a) || !CHECK_R(b)) |
| 228 | tcc_error("compiler error! registers %i,%i is not valid",a,b); | 221 | tcc_error(S, "compiler error! registers %i,%i is not valid",a,b); |
| 229 | return (reg_classes[a]|reg_classes[b])&~(RC_INT|RC_FLOAT); | 222 | return (reg_classes[a]|reg_classes[b])&~(RC_INT|RC_FLOAT); |
| 230 | } | 223 | } |
| 231 | 224 | ||
| 232 | static int regmask(int r) { | 225 | static int regmask(TCCState* S, int r) { |
| 233 | if (!CHECK_R(r)) | 226 | if (!CHECK_R(r)) |
| 234 | tcc_error("compiler error! register %i is not valid",r); | 227 | tcc_error(S, "compiler error! register %i is not valid",r); |
| 235 | return reg_classes[r]&~(RC_INT|RC_FLOAT); | 228 | return reg_classes[r]&~(RC_INT|RC_FLOAT); |
| 236 | } | 229 | } |
| 237 | 230 | ||
| @@ -247,25 +240,25 @@ const char *default_elfinterp(struct TCCState *s) · 9 unmodified lines | |||
| 247 | } | 240 | } |
| 248 | #endif | 241 | #endif |
| 249 | 242 | ||
| 250 | void o(uint32_t i) | 243 | void o(TCCState* S, uint32_t i) |
| 251 | { | 244 | { |
| 252 | /* this is a good place to start adding big-endian support*/ | 245 | /* this is a good place to start adding big-endian support*/ |
| 253 | int ind1; | 246 | int ind1; |
| 254 | if (nocode_wanted) | 247 | if (S->tccgen_nocode_wanted) |
| 255 | return; | 248 | return; |
| 256 | ind1 = ind + 4; | 249 | ind1 = S->tccgen_ind + 4; |
| 257 | if (!cur_text_section) | 250 | if (!cur_text_section) |
| 258 | tcc_error("compiler error! This happens f.ex. if the compiler\n" | 251 | tcc_error(S, "compiler error! This happens f.ex. if the compiler\n" |
| 259 | "can't evaluate constant expressions outside of a function."); | 252 | "can't evaluate constant expressions outside of a function."); |
| 260 | if (ind1 > cur_text_section->data_allocated) | 253 | if (ind1 > cur_text_section->data_allocated) |
| 261 | section_realloc(cur_text_section, ind1); | 254 | section_realloc(S, cur_text_section, ind1); |
| 262 | cur_text_section->data[ind++] = i&255; | 255 | cur_text_section->data[S->tccgen_ind++] = i&255; |
| 263 | i>>=8; | 256 | i>>=8; |
| 264 | cur_text_section->data[ind++] = i&255; | 257 | cur_text_section->data[S->tccgen_ind++] = i&255; |
| 265 | i>>=8; | 258 | i>>=8; |
| 266 | cur_text_section->data[ind++] = i&255; | 259 | cur_text_section->data[S->tccgen_ind++] = i&255; |
| 267 | i>>=8; | 260 | i>>=8; |
| 268 | cur_text_section->data[ind++] = i; | 261 | cur_text_section->data[S->tccgen_ind++] = i; |
| 269 | } | 262 | } |
| 270 | 263 | ||
| 271 | static uint32_t stuff_const(uint32_t op, uint32_t c) | 264 | static uint32_t stuff_const(uint32_t op, uint32_t c) |
| @@ -322,11 +315,11 @@ static uint32_t stuff_const(uint32_t op, uint32_t c) · 50 unmodified lines | |||
| 322 | 315 | ||
| 323 | 316 | ||
| 324 | //only add,sub | 317 | //only add,sub |
| 325 | void stuff_const_harder(uint32_t op, uint32_t v) { | 318 | void stuff_const_harder(TCCState* S, uint32_t op, uint32_t v) { |
| 326 | uint32_t x; | 319 | uint32_t x; |
| 327 | x=stuff_const(op,v); | 320 | x=stuff_const(op,v); |
| 328 | if(x) | 321 | if(x) |
| 329 | o(x); | 322 | o(S, x); |
| 330 | else { | 323 | else { |
| 331 | uint32_t a[16], nv, no, o2, n2; | 324 | uint32_t a[16], nv, no, o2, n2; |
| 332 | int i,j,k; | 325 | int i,j,k; |
| @@ -337,8 +330,8 @@ void stuff_const_harder(uint32_t op, uint32_t v) { · 4 unmodified lines | |||
| 337 | for(i=0;i<12;i++) | 330 | for(i=0;i<12;i++) |
| 338 | for(j=i<4?i+12:15;j>=i+4;j--) | 331 | for(j=i<4?i+12:15;j>=i+4;j--) |
| 339 | if((v&(a[i]|a[j]))==v) { | 332 | if((v&(a[i]|a[j]))==v) { |
| 340 | o(stuff_const(op,v&a[i])); | 333 | o(S, stuff_const(op,v&a[i])); |
| 341 | o(stuff_const(o2,v&a[j])); | 334 | o(S, stuff_const(o2,v&a[j])); |
| 342 | return; | 335 | return; |
| 343 | } | 336 | } |
| 344 | no=op^0xC00000; | 337 | no=op^0xC00000; |
| @@ -347,17 +340,17 @@ void stuff_const_harder(uint32_t op, uint32_t v) { · 2 unmodified lines | |||
| 347 | for(i=0;i<12;i++) | 340 | for(i=0;i<12;i++) |
| 348 | for(j=i<4?i+12:15;j>=i+4;j--) | 341 | for(j=i<4?i+12:15;j>=i+4;j--) |
| 349 | if((nv&(a[i]|a[j]))==nv) { | 342 | if((nv&(a[i]|a[j]))==nv) { |
| 350 | o(stuff_const(no,nv&a[i])); | 343 | o(S, stuff_const(no,nv&a[i])); |
| 351 | o(stuff_const(n2,nv&a[j])); | 344 | o(S, stuff_const(n2,nv&a[j])); |
| 352 | return; | 345 | return; |
| 353 | } | 346 | } |
| 354 | for(i=0;i<8;i++) | 347 | for(i=0;i<8;i++) |
| 355 | for(j=i+4;j<12;j++) | 348 | for(j=i+4;j<12;j++) |
| 356 | for(k=i<4?i+12:15;k>=j+4;k--) | 349 | for(k=i<4?i+12:15;k>=j+4;k--) |
| 357 | if((v&(a[i]|a[j]|a[k]))==v) { | 350 | if((v&(a[i]|a[j]|a[k]))==v) { |
| 358 | o(stuff_const(op,v&a[i])); | 351 | o(S, stuff_const(op,v&a[i])); |
| 359 | o(stuff_const(o2,v&a[j])); | 352 | o(S, stuff_const(o2,v&a[j])); |
| 360 | o(stuff_const(o2,v&a[k])); | 353 | o(S, stuff_const(o2,v&a[k])); |
| 361 | return; | 354 | return; |
| 362 | } | 355 | } |
| 363 | no=op^0xC00000; | 356 | no=op^0xC00000; |
| @@ -366,31 +359,31 @@ void stuff_const_harder(uint32_t op, uint32_t v) { · 2 unmodified lines | |||
| 366 | for(j=i+4;j<12;j++) | 359 | for(j=i+4;j<12;j++) |
| 367 | for(k=i<4?i+12:15;k>=j+4;k--) | 360 | for(k=i<4?i+12:15;k>=j+4;k--) |
| 368 | if((nv&(a[i]|a[j]|a[k]))==nv) { | 361 | if((nv&(a[i]|a[j]|a[k]))==nv) { |
| 369 | o(stuff_const(no,nv&a[i])); | 362 | o(S, stuff_const(no,nv&a[i])); |
| 370 | o(stuff_const(n2,nv&a[j])); | 363 | o(S, stuff_const(n2,nv&a[j])); |
| 371 | o(stuff_const(n2,nv&a[k])); | 364 | o(S, stuff_const(n2,nv&a[k])); |
| 372 | return; | 365 | return; |
| 373 | } | 366 | } |
| 374 | o(stuff_const(op,v&a[0])); | 367 | o(S, stuff_const(op,v&a[0])); |
| 375 | o(stuff_const(o2,v&a[4])); | 368 | o(S, stuff_const(o2,v&a[4])); |
| 376 | o(stuff_const(o2,v&a[8])); | 369 | o(S, stuff_const(o2,v&a[8])); |
| 377 | o(stuff_const(o2,v&a[12])); | 370 | o(S, stuff_const(o2,v&a[12])); |
| 378 | } | 371 | } |
| 379 | } | 372 | } |
| 380 | 373 | ||
| 381 | uint32_t encbranch(int pos, int addr, int fail) | 374 | uint32_t encbranch(TCCState* S, int pos, int addr, int fail) |
| 382 | { | 375 | { |
| 383 | addr-=pos+8; | 376 | addr-=pos+8; |
| 384 | addr/=4; | 377 | addr/=4; |
| 385 | if(addr>=0x1000000 || addr<-0x1000000) { | 378 | if(addr>=0x1000000 || addr<-0x1000000) { |
| 386 | if(fail) | 379 | if(fail) |
| 387 | tcc_error("FIXME: function bigger than 32MB"); | 380 | tcc_error(S, "FIXME: function bigger than 32MB"); |
| 388 | return 0; | 381 | return 0; |
| 389 | } | 382 | } |
| 390 | return 0x0A000000|(addr&0xffffff); | 383 | return 0x0A000000|(addr&0xffffff); |
| 391 | } | 384 | } |
| 392 | 385 | ||
| 393 | int decbranch(int pos) | 386 | int decbranch(TCCState* S, int pos) |
| 394 | { | 387 | { |
| 395 | int x; | 388 | int x; |
| 396 | x=*(uint32_t *)(cur_text_section->data + pos); | 389 | x=*(uint32_t *)(cur_text_section->data + pos); |
| @@ -401,50 +394,50 @@ int decbranch(int pos) · 4 unmodified lines | |||
| 401 | } | 394 | } |
| 402 | 395 | ||
| 403 | /* output a symbol and patch all calls to it */ | 396 | /* output a symbol and patch all calls to it */ |
| 404 | void gsym_addr(int t, int a) | 397 | void gsym_addr(TCCState* S, int t, int a) |
| 405 | { | 398 | { |
| 406 | uint32_t *x; | 399 | uint32_t *x; |
| 407 | int lt; | 400 | int lt; |
| 408 | while(t) { | 401 | while(t) { |
| 409 | x=(uint32_t *)(cur_text_section->data + t); | 402 | x=(uint32_t *)(cur_text_section->data + t); |
| 410 | t=decbranch(lt=t); | 403 | t=decbranch(S, lt=t); |
| 411 | if(a==lt+4) | 404 | if(a==lt+4) |
| 412 | *x=0xE1A00000; // nop | 405 | *x=0xE1A00000; // nop |
| 413 | else { | 406 | else { |
| 414 | *x &= 0xff000000; | 407 | *x &= 0xff000000; |
| 415 | *x |= encbranch(lt,a,1); | 408 | *x |= encbranch(S, lt,a,1); |
| 416 | } | 409 | } |
| 417 | } | 410 | } |
| 418 | } | 411 | } |
| 419 | 412 | ||
| 420 | #ifdef TCC_ARM_VFP | 413 | #ifdef TCC_ARM_VFP |
| 421 | static uint32_t vfpr(int r) | 414 | static uint32_t vfpr(TCCState* S, int r) |
| 422 | { | 415 | { |
| 423 | if(r<TREG_F0 || r>TREG_F7) | 416 | if(r<TREG_F0 || r>TREG_F7) |
| 424 | tcc_error("compiler error! register %i is no vfp register",r); | 417 | tcc_error(S, "compiler error! register %i is no vfp register",r); |
| 425 | return r - TREG_F0; | 418 | return r - TREG_F0; |
| 426 | } | 419 | } |
| 427 | #else | 420 | #else |
| 428 | static uint32_t fpr(int r) | 421 | static uint32_t fpr(TCCState* S, int r) |
| 429 | { | 422 | { |
| 430 | if(r<TREG_F0 || r>TREG_F3) | 423 | if(r<TREG_F0 || r>TREG_F3) |
| 431 | tcc_error("compiler error! register %i is no fpa register",r); | 424 | tcc_error(S, "compiler error! register %i is no fpa register",r); |
| 432 | return r - TREG_F0; | 425 | return r - TREG_F0; |
| 433 | } | 426 | } |
| 434 | #endif | 427 | #endif |
| 435 | 428 | ||
| 436 | static uint32_t intr(int r) | 429 | static uint32_t intr(TCCState* S, int r) |
| 437 | { | 430 | { |
| 438 | if(r == TREG_R12) | 431 | if(r == TREG_R12) |
| 439 | return 12; | 432 | return 12; |
| 440 | if(r >= TREG_R0 && r <= TREG_R3) | 433 | if(r >= TREG_R0 && r <= TREG_R3) |
| 441 | return r - TREG_R0; | 434 | return r - TREG_R0; |
| 442 | if (!(r >= TREG_SP && r <= TREG_LR)) | 435 | if (!(r >= TREG_SP && r <= TREG_LR)) |
| 443 | tcc_error("compiler error! register %i is no int register",r); | 436 | tcc_error(S, "compiler error! register %i is no int register",r); |
| 444 | return r + (13 - TREG_SP); | 437 | return r + (13 - TREG_SP); |
| 445 | } | 438 | } |
| 446 | 439 | ||
| 447 | static void calcaddr(uint32_t *base, int *off, int *sgn, int maxoff, unsigned shift) | 440 | static void calcaddr(TCCState* S, uint32_t *base, int *off, int *sgn, int maxoff, unsigned shift) |
| 448 | { | 441 | { |
| 449 | if(*off>maxoff || *off&((1<<shift)-1)) { | 442 | if(*off>maxoff || *off&((1<<shift)-1)) { |
| 450 | uint32_t x, y; | 443 | uint32_t x, y; |
| @@ -455,23 +448,23 @@ static void calcaddr(uint32_t *base, int *off, int *sgn, int maxoff, unsigned sh · 4 unmodified lines | |||
| 455 | *base=14; // lr | 448 | *base=14; // lr |
| 456 | y=stuff_const(x,*off&~maxoff); | 449 | y=stuff_const(x,*off&~maxoff); |
| 457 | if(y) { | 450 | if(y) { |
| 458 | o(y); | 451 | o(S, y); |
| 459 | *off&=maxoff; | 452 | *off&=maxoff; |
| 460 | return; | 453 | return; |
| 461 | } | 454 | } |
| 462 | y=stuff_const(x,(*off+maxoff)&~maxoff); | 455 | y=stuff_const(x,(*off+maxoff)&~maxoff); |
| 463 | if(y) { | 456 | if(y) { |
| 464 | o(y); | 457 | o(S, y); |
| 465 | *sgn=!*sgn; | 458 | *sgn=!*sgn; |
| 466 | *off=((*off+maxoff)&~maxoff)-*off; | 459 | *off=((*off+maxoff)&~maxoff)-*off; |
| 467 | return; | 460 | return; |
| 468 | } | 461 | } |
| 469 | stuff_const_harder(x,*off&~maxoff); | 462 | stuff_const_harder(S, x,*off&~maxoff); |
| 470 | *off&=maxoff; | 463 | *off&=maxoff; |
| 471 | } | 464 | } |
| 472 | } | 465 | } |
| 473 | 466 | ||
| 474 | static uint32_t mapcc(int cc) | 467 | static uint32_t mapcc(TCCState* S, int cc) |
| 475 | { | 468 | { |
| 476 | switch(cc) | 469 | switch(cc) |
| 477 | { | 470 | { |
| @@ -500,11 +493,11 @@ static uint32_t mapcc(int cc) · 22 unmodified lines | |||
| 500 | case TOK_GT: | 493 | case TOK_GT: |
| 501 | return 0xC0000000; /* GT */ | 494 | return 0xC0000000; /* GT */ |
| 502 | } | 495 | } |
| 503 | tcc_error("unexpected condition code"); | 496 | tcc_error(S, "unexpected condition code"); |
| 504 | return 0xE0000000; /* AL */ | 497 | return 0xE0000000; /* AL */ |
| 505 | } | 498 | } |
| 506 | 499 | ||
| 507 | static int negcc(int cc) | 500 | static int negcc(TCCState* S, int cc) |
| 508 | { | 501 | { |
| 509 | switch(cc) | 502 | switch(cc) |
| 510 | { | 503 | { |
| @@ -533,44 +526,44 @@ static int negcc(int cc) · 22 unmodified lines | |||
| 533 | case TOK_GT: | 526 | case TOK_GT: |
| 534 | return TOK_LE; | 527 | return TOK_LE; |
| 535 | } | 528 | } |
| 536 | tcc_error("unexpected condition code"); | 529 | tcc_error(S, "unexpected condition code"); |
| 537 | return TOK_NE; | 530 | return TOK_NE; |
| 538 | } | 531 | } |
| 539 | 532 | ||
| 540 | /* Load value into register r. | 533 | /* Load value into register r. |
| 541 | Use relative/got addressing to avoid setting DT_TEXTREL */ | 534 | Use relative/got addressing to avoid setting DT_TEXTREL */ |
| 542 | static void load_value(SValue *sv, int r) | 535 | static void load_value(TCCState* S, SValue *sv, int r) |
| 543 | { | 536 | { |
| 544 | o(0xE59F0000|(intr(r)<<12)); /* ldr r, [pc] */ | 537 | o(S, 0xE59F0000|(intr(S, r)<<12)); /* ldr r, [pc] */ |
| 545 | o(0xEA000000); /* b $+4 */ | 538 | o(S, 0xEA000000); /* b $+4 */ |
| 546 | #ifndef CONFIG_TCC_PIE | 539 | #ifndef CONFIG_TCC_PIE |
| 547 | if(sv->r & VT_SYM) | 540 | if(sv->r & VT_SYM) |
| 548 | greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32); | 541 | greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_ARM_ABS32); |
| 549 | o(sv->c.i); | 542 | o(S, sv->c.i); |
| 550 | #else | 543 | #else |
| 551 | if(sv->r & VT_SYM) { | 544 | if(sv->r & VT_SYM) { |
| 552 | if (sv->sym->type.t & VT_STATIC) { | 545 | if (sv->sym->type.t & VT_STATIC) { |
| 553 | greloc(cur_text_section, sv->sym, ind, R_ARM_REL32); | 546 | greloc(cur_text_section, sv->sym, ind, R_ARM_REL32); |
| 554 | o(sv->c.i - 12); | 547 | o(S, sv->c.i - 12); |
| 555 | o(0xe080000f | (intr(r)<<12) | (intr(r)<<16)); // add rx,rx,pc | 548 | o(S, 0xe080000f | (intr(S, r)<<12) | (intr(S, r)<<16)); // add rx,rx,pc |
| 556 | } | 549 | } |
| 557 | else { | 550 | else { |
| 558 | greloc(cur_text_section, sv->sym, ind, R_ARM_GOT_PREL); | 551 | greloc(cur_text_section, sv->sym, ind, R_ARM_GOT_PREL); |
| 559 | o(-12); | 552 | o(S, -12); |
| 560 | o(0xe080000f | (intr(r)<<12) | (intr(r)<<16)); // add rx,rx,pc | 553 | o(S, 0xe080000f | (intr(S, r)<<12) | (intr(S, r)<<16)); // add rx,rx,pc |
| 561 | o(0xe5900000 | (intr(r)<<12) | (intr(r)<<16)); // ldr rx,[rx] | 554 | o(S, 0xe5900000 | (intr(S, r)<<12) | (intr(S, r)<<16)); // ldr rx,[rx] |
| 562 | if (sv->c.i) | 555 | if (sv->c.i) |
| 563 | stuff_const_harder(0xe2800000 | (intr(r)<<12) | (intr(r)<<16), | 556 | stuff_const_harder(S, 0xe2800000 | (intr(S, r)<<12) | (intr(S, r)<<16), |
| 564 | sv->c.i); | 557 | sv->c.i); |
| 565 | } | 558 | } |
| 566 | } | 559 | } |
| 567 | else | 560 | else |
| 568 | o(sv->c.i); | 561 | o(S, sv->c.i); |
| 569 | #endif | 562 | #endif |
| 570 | } | 563 | } |
| 571 | 564 | ||
| 572 | /* load 'r' from value 'sv' */ | 565 | /* load 'r' from value 'sv' */ |
| 573 | void load(int r, SValue *sv) | 566 | void load(TCCState* S, int r, SValue *sv) |
| 574 | { | 567 | { |
| 575 | int v, ft, fc, fr, sign; | 568 | int v, ft, fc, fr, sign; |
| 576 | uint32_t op; | 569 | uint32_t op; |
| @@ -594,7 +587,7 @@ void load(int r, SValue *sv) · 17 unmodified lines | |||
| 594 | v1.type.t = VT_PTR; | 587 | v1.type.t = VT_PTR; |
| 595 | v1.r = VT_LOCAL | VT_LVAL; | 588 | v1.r = VT_LOCAL | VT_LVAL; |
| 596 | v1.c.i = sv->c.i; | 589 | v1.c.i = sv->c.i; |
| 597 | load(TREG_LR, &v1); | 590 | load(S, TREG_LR, &v1); |
| 598 | base = 14; /* lr */ | 591 | base = 14; /* lr */ |
| 599 | fc=sign=0; | 592 | fc=sign=0; |
| 600 | v=VT_LOCAL; | 593 | v=VT_LOCAL; |
| @@ -603,25 +596,25 @@ void load(int r, SValue *sv) · 2 unmodified lines | |||
| 603 | v1.r = fr&~VT_LVAL; | 596 | v1.r = fr&~VT_LVAL; |
| 604 | v1.c.i = sv->c.i; | 597 | v1.c.i = sv->c.i; |
| 605 | v1.sym=sv->sym; | 598 | v1.sym=sv->sym; |
| 606 | load(TREG_LR, &v1); | 599 | load(S, TREG_LR, &v1); |
| 607 | base = 14; /* lr */ | 600 | base = 14; /* lr */ |
| 608 | fc=sign=0; | 601 | fc=sign=0; |
| 609 | v=VT_LOCAL; | 602 | v=VT_LOCAL; |
| 610 | } else if(v < VT_CONST) { | 603 | } else if(v < VT_CONST) { |
| 611 | base=intr(v); | 604 | base=intr(S, v); |
| 612 | fc=sign=0; | 605 | fc=sign=0; |
| 613 | v=VT_LOCAL; | 606 | v=VT_LOCAL; |
| 614 | } | 607 | } |
| 615 | if(v == VT_LOCAL) { | 608 | if(v == VT_LOCAL) { |
| 616 | if(is_float(ft)) { | 609 | if(is_float(ft)) { |
| 617 | calcaddr(&base,&fc,&sign,1020,2); | 610 | calcaddr(S, &base,&fc,&sign,1020,2); |
| 618 | #ifdef TCC_ARM_VFP | 611 | #ifdef TCC_ARM_VFP |
| 619 | op=0xED100A00; /* flds */ | 612 | op=0xED100A00; /* flds */ |
| 620 | if(!sign) | 613 | if(!sign) |
| 621 | op|=0x800000; | 614 | op|=0x800000; |
| 622 | if ((ft & VT_BTYPE) != VT_FLOAT) | 615 | if ((ft & VT_BTYPE) != VT_FLOAT) |
| 623 | op|=0x100; /* flds -> fldd */ | 616 | op|=0x100; /* flds -> fldd */ |
| 624 | o(op|(vfpr(r)<<12)|(fc>>2)|(base<<16)); | 617 | o(S, op|(vfpr(S, r)<<12)|(fc>>2)|(base<<16)); |
| 625 | #else | 618 | #else |
| 626 | op=0xED100100; | 619 | op=0xED100100; |
| 627 | if(!sign) | 620 | if(!sign) |
| @@ -635,11 +628,11 @@ void load(int r, SValue *sv) · 7 unmodified lines | |||
| 635 | else if ((ft & VT_BTYPE) == VT_LDOUBLE) | 628 | else if ((ft & VT_BTYPE) == VT_LDOUBLE) |
| 636 | op|=0x400000; | 629 | op|=0x400000; |
| 637 | #endif | 630 | #endif |
| 638 | o(op|(fpr(r)<<12)|(fc>>2)|(base<<16)); | 631 | o(S, op|(fpr(S, r)<<12)|(fc>>2)|(base<<16)); |
| 639 | #endif | 632 | #endif |
| 640 | } else if((ft & (VT_BTYPE|VT_UNSIGNED)) == VT_BYTE | 633 | } else if((ft & (VT_BTYPE|VT_UNSIGNED)) == VT_BYTE |
| 641 | || (ft & VT_BTYPE) == VT_SHORT) { | 634 | || (ft & VT_BTYPE) == VT_SHORT) { |
| 642 | calcaddr(&base,&fc,&sign,255,0); | 635 | calcaddr(S, &base,&fc,&sign,255,0); |
| 643 | op=0xE1500090; | 636 | op=0xE1500090; |
| 644 | if ((ft & VT_BTYPE) == VT_SHORT) | 637 | if ((ft & VT_BTYPE) == VT_SHORT) |
| 645 | op|=0x20; | 638 | op|=0x20; |
| @@ -647,63 +640,63 @@ void load(int r, SValue *sv) · 1 unmodified line | |||
| 647 | op|=0x40; | 640 | op|=0x40; |
| 648 | if(!sign) | 641 | if(!sign) |
| 649 | op|=0x800000; | 642 | op|=0x800000; |
| 650 | o(op|(intr(r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf)); | 643 | o(S, op|(intr(S, r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf)); |
| 651 | } else { | 644 | } else { |
| 652 | calcaddr(&base,&fc,&sign,4095,0); | 645 | calcaddr(S, &base,&fc,&sign,4095,0); |
| 653 | op=0xE5100000; | 646 | op=0xE5100000; |
| 654 | if(!sign) | 647 | if(!sign) |
| 655 | op|=0x800000; | 648 | op|=0x800000; |
| 656 | if ((ft & VT_BTYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_BOOL) | 649 | if ((ft & VT_BTYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_BOOL) |
| 657 | op|=0x400000; | 650 | op|=0x400000; |
| 658 | o(op|(intr(r)<<12)|fc|(base<<16)); | 651 | o(S, op|(intr(S, r)<<12)|fc|(base<<16)); |
| 659 | } | 652 | } |
| 660 | return; | 653 | return; |
| 661 | } | 654 | } |
| 662 | } else { | 655 | } else { |
| 663 | if (v == VT_CONST) { | 656 | if (v == VT_CONST) { |
| 664 | op=stuff_const(0xE3A00000|(intr(r)<<12),sv->c.i); | 657 | op=stuff_const(0xE3A00000|(intr(S, r)<<12),sv->c.i); |
| 665 | if (fr & VT_SYM || !op) | 658 | if (fr & VT_SYM || !op) |
| 666 | load_value(sv, r); | 659 | load_value(S, sv, r); |
| 667 | else | 660 | else |
| 668 | o(op); | 661 | o(S, op); |
| 669 | return; | 662 | return; |
| 670 | } else if (v == VT_LOCAL) { | 663 | } else if (v == VT_LOCAL) { |
| 671 | op=stuff_const(0xE28B0000|(intr(r)<<12),sv->c.i); | 664 | op=stuff_const(0xE28B0000|(intr(S, r)<<12),sv->c.i); |
| 672 | if (fr & VT_SYM || !op) { | 665 | if (fr & VT_SYM || !op) { |
| 673 | load_value(sv, r); | 666 | load_value(S, sv, r); |
| 674 | o(0xE08B0000|(intr(r)<<12)|intr(r)); | 667 | o(S, 0xE08B0000|(intr(S, r)<<12)|intr(S, r)); |
| 675 | } else | 668 | } else |
| 676 | o(op); | 669 | o(S, op); |
| 677 | return; | 670 | return; |
| 678 | } else if(v == VT_CMP) { | 671 | } else if(v == VT_CMP) { |
| 679 | o(mapcc(sv->c.i)|0x3A00001|(intr(r)<<12)); | 672 | o(S, mapcc(S, sv->c.i)|0x3A00001|(intr(S, r)<<12)); |
| 680 | o(mapcc(negcc(sv->c.i))|0x3A00000|(intr(r)<<12)); | 673 | o(S, mapcc(S, negcc(S, sv->c.i))|0x3A00000|(intr(S, r)<<12)); |
| 681 | return; | 674 | return; |
| 682 | } else if (v == VT_JMP || v == VT_JMPI) { | 675 | } else if (v == VT_JMP || v == VT_JMPI) { |
| 683 | int t; | 676 | int t; |
| 684 | t = v & 1; | 677 | t = v & 1; |
| 685 | o(0xE3A00000|(intr(r)<<12)|t); | 678 | o(S, 0xE3A00000|(intr(S, r)<<12)|t); |
| 686 | o(0xEA000000); | 679 | o(S, 0xEA000000); |
| 687 | gsym(sv->c.i); | 680 | gsym(S, sv->c.i); |
| 688 | o(0xE3A00000|(intr(r)<<12)|(t^1)); | 681 | o(S, 0xE3A00000|(intr(S, r)<<12)|(t^1)); |
| 689 | return; | 682 | return; |
| 690 | } else if (v < VT_CONST) { | 683 | } else if (v < VT_CONST) { |
| 691 | if(is_float(ft)) | 684 | if(is_float(ft)) |
| 692 | #ifdef TCC_ARM_VFP | 685 | #ifdef TCC_ARM_VFP |
| 693 | o(0xEEB00A40|(vfpr(r)<<12)|vfpr(v)|T2CPR(ft)); /* fcpyX */ | 686 | o(S, 0xEEB00A40|(vfpr(S, r)<<12)|vfpr(S, v)|T2CPR(ft)); /* fcpyX */ |
| 694 | #else | 687 | #else |
| 695 | o(0xEE008180|(fpr(r)<<12)|fpr(v)); | 688 | o(S, 0xEE008180|(fpr(S, r)<<12)|fpr(S, v)); |
| 696 | #endif | 689 | #endif |
| 697 | else | 690 | else |
| 698 | o(0xE1A00000|(intr(r)<<12)|intr(v)); | 691 | o(S, 0xE1A00000|(intr(S, r)<<12)|intr(S, v)); |
| 699 | return; | 692 | return; |
| 700 | } | 693 | } |
| 701 | } | 694 | } |
| 702 | tcc_error("load unimplemented!"); | 695 | tcc_error(S, "load unimplemented!"); |
| 703 | } | 696 | } |
| 704 | 697 | ||
| 705 | /* store register 'r' in lvalue 'v' */ | 698 | /* store register 'r' in lvalue 'v' */ |
| 706 | void store(int r, SValue *sv) | 699 | void store(TCCState* S, int r, SValue *sv) |
| 707 | { | 700 | { |
| 708 | SValue v1; | 701 | SValue v1; |
| 709 | int v, ft, fc, fr, sign; | 702 | int v, ft, fc, fr, sign; |
| @@ -724,7 +717,7 @@ void store(int r, SValue *sv) · 14 unmodified lines | |||
| 724 | if (fr & VT_LVAL || fr == VT_LOCAL) { | 717 | if (fr & VT_LVAL || fr == VT_LOCAL) { |
| 725 | uint32_t base = 0xb; /* fp */ | 718 | uint32_t base = 0xb; /* fp */ |
| 726 | if(v < VT_CONST) { | 719 | if(v < VT_CONST) { |
| 727 | base=intr(v); | 720 | base=intr(S, v); |
| 728 | v=VT_LOCAL; | 721 | v=VT_LOCAL; |
| 729 | fc=sign=0; | 722 | fc=sign=0; |
| 730 | } else if(v == VT_CONST) { | 723 | } else if(v == VT_CONST) { |
| @@ -732,21 +725,21 @@ void store(int r, SValue *sv) · 1 unmodified line | |||
| 732 | v1.r = fr&~VT_LVAL; | 725 | v1.r = fr&~VT_LVAL; |
| 733 | v1.c.i = sv->c.i; | 726 | v1.c.i = sv->c.i; |
| 734 | v1.sym=sv->sym; | 727 | v1.sym=sv->sym; |
| 735 | load(TREG_LR, &v1); | 728 | load(S, TREG_LR, &v1); |
| 736 | base = 14; /* lr */ | 729 | base = 14; /* lr */ |
| 737 | fc=sign=0; | 730 | fc=sign=0; |
| 738 | v=VT_LOCAL; | 731 | v=VT_LOCAL; |
| 739 | } | 732 | } |
| 740 | if(v == VT_LOCAL) { | 733 | if(v == VT_LOCAL) { |
| 741 | if(is_float(ft)) { | 734 | if(is_float(ft)) { |
| 742 | calcaddr(&base,&fc,&sign,1020,2); | 735 | calcaddr(S, &base,&fc,&sign,1020,2); |
| 743 | #ifdef TCC_ARM_VFP | 736 | #ifdef TCC_ARM_VFP |
| 744 | op=0xED000A00; /* fsts */ | 737 | op=0xED000A00; /* fsts */ |
| 745 | if(!sign) | 738 | if(!sign) |
| 746 | op|=0x800000; | 739 | op|=0x800000; |
| 747 | if ((ft & VT_BTYPE) != VT_FLOAT) | 740 | if ((ft & VT_BTYPE) != VT_FLOAT) |
| 748 | op|=0x100; /* fsts -> fstd */ | 741 | op|=0x100; /* fsts -> fstd */ |
| 749 | o(op|(vfpr(r)<<12)|(fc>>2)|(base<<16)); | 742 | o(S, op|(vfpr(S, r)<<12)|(fc>>2)|(base<<16)); |
| 750 | #else | 743 | #else |
| 751 | op=0xED000100; | 744 | op=0xED000100; |
| 752 | if(!sign) | 745 | if(!sign) |
| @@ -760,138 +753,138 @@ void store(int r, SValue *sv) · 7 unmodified lines | |||
| 760 | if ((ft & VT_BTYPE) == VT_LDOUBLE) | 753 | if ((ft & VT_BTYPE) == VT_LDOUBLE) |
| 761 | op|=0x400000; | 754 | op|=0x400000; |
| 762 | #endif | 755 | #endif |
| 763 | o(op|(fpr(r)<<12)|(fc>>2)|(base<<16)); | 756 | o(S, op|(fpr(S, r)<<12)|(fc>>2)|(base<<16)); |
| 764 | #endif | 757 | #endif |
| 765 | return; | 758 | return; |
| 766 | } else if((ft & VT_BTYPE) == VT_SHORT) { | 759 | } else if((ft & VT_BTYPE) == VT_SHORT) { |
| 767 | calcaddr(&base,&fc,&sign,255,0); | 760 | calcaddr(S, &base,&fc,&sign,255,0); |
| 768 | op=0xE14000B0; | 761 | op=0xE14000B0; |
| 769 | if(!sign) | 762 | if(!sign) |
| 770 | op|=0x800000; | 763 | op|=0x800000; |
| 771 | o(op|(intr(r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf)); | 764 | o(S, op|(intr(S, r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf)); |
| 772 | } else { | 765 | } else { |
| 773 | calcaddr(&base,&fc,&sign,4095,0); | 766 | calcaddr(S, &base,&fc,&sign,4095,0); |
| 774 | op=0xE5000000; | 767 | op=0xE5000000; |
| 775 | if(!sign) | 768 | if(!sign) |
| 776 | op|=0x800000; | 769 | op|=0x800000; |
| 777 | if ((ft & VT_BTYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_BOOL) | 770 | if ((ft & VT_BTYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_BOOL) |
| 778 | op|=0x400000; | 771 | op|=0x400000; |
| 779 | o(op|(intr(r)<<12)|fc|(base<<16)); | 772 | o(S, op|(intr(S, r)<<12)|fc|(base<<16)); |
| 780 | } | 773 | } |
| 781 | return; | 774 | return; |
| 782 | } | 775 | } |
| 783 | } | 776 | } |
| 784 | tcc_error("store unimplemented"); | 777 | tcc_error(S, "store unimplemented"); |
| 785 | } | 778 | } |
| 786 | 779 | ||
| 787 | static void gadd_sp(int val) | 780 | static void gadd_sp(TCCState* S, int val) |
| 788 | { | 781 | { |
| 789 | stuff_const_harder(0xE28DD000,val); | 782 | stuff_const_harder(S, 0xE28DD000,val); |
| 790 | } | 783 | } |
| 791 | 784 | ||
| 792 | /* 'is_jmp' is '1' if it is a jump */ | 785 | /* 'is_jmp' is '1' if it is a jump */ |
| 793 | static void gcall_or_jmp(int is_jmp) | 786 | static void gcall_or_jmp(TCCState* S, int is_jmp) |
| 794 | { | 787 | { |
| 795 | int r; | 788 | int r; |
| 796 | uint32_t x; | 789 | uint32_t x; |
| 797 | if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { | 790 | if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { |
| 798 | /* constant case */ | 791 | /* constant case */ |
| 799 | if(vtop->r & VT_SYM){ | 792 | if(S->tccgen_vtop->r & VT_SYM){ |
| 800 | x=encbranch(ind,ind+vtop->c.i,0); | 793 | x=encbranch(S, S->tccgen_ind, S->tccgen_ind+S->tccgen_vtop->c.i,0); |
| 801 | if(x) { | 794 | if(x) { |
| 802 | /* relocation case */ | 795 | /* relocation case */ |
| 803 | greloc(cur_text_section, vtop->sym, ind, R_ARM_PC24); | 796 | greloc(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind, R_ARM_PC24); |
| 804 | o(x|(is_jmp?0xE0000000:0xE1000000)); | 797 | o(S, x|(is_jmp?0xE0000000:0xE1000000)); |
| 805 | } else { | 798 | } else { |
| 806 | r = TREG_LR; | 799 | r = TREG_LR; |
| 807 | load_value(vtop, r); | 800 | load_value(S, S->tccgen_vtop, r); |
| 808 | if(is_jmp) | 801 | if(is_jmp) |
| 809 | o(0xE1A0F000 | intr(r)); // mov pc, r | 802 | o(S, 0xE1A0F000 | intr(S, r)); // mov pc, r |
| 810 | else | 803 | else |
| 811 | o(0xe12fff30 | intr(r)); // blx r | 804 | o(S, 0xe12fff30 | intr(S, r)); // blx r |
| 812 | } | 805 | } |
| 813 | }else{ | 806 | }else{ |
| 814 | if(!is_jmp) | 807 | if(!is_jmp) |
| 815 | o(0xE28FE004); // add lr,pc,#4 | 808 | o(S, 0xE28FE004); // add lr,pc,#4 |
| 816 | o(0xE51FF004); // ldr pc,[pc,#-4] | 809 | o(S, 0xE51FF004); // ldr pc,[pc,#-4] |
| 817 | o(vtop->c.i); | 810 | o(S, S->tccgen_vtop->c.i); |
| 818 | } | 811 | } |
| 819 | } else { | 812 | } else { |
| 820 | /* otherwise, indirect call */ | 813 | /* otherwise, indirect call */ |
| 821 | #ifdef CONFIG_TCC_BCHECK | 814 | #ifdef CONFIG_TCC_BCHECK |
| 822 | vtop->r &= ~VT_MUSTBOUND; | 815 | S->tccgen_vtop->r &= ~VT_MUSTBOUND; |
| 823 | #endif | 816 | #endif |
| 824 | r = gv(RC_INT); | 817 | r = gv(S, RC_INT); |
| 825 | if(!is_jmp) | 818 | if(!is_jmp) |
| 826 | o(0xE1A0E00F); // mov lr,pc | 819 | o(S, 0xE1A0E00F); // mov lr,pc |
| 827 | o(0xE1A0F000|intr(r)); // mov pc,r | 820 | o(S, 0xE1A0F000|intr(S, r)); // mov pc,r |
| 828 | } | 821 | } |
| 829 | } | 822 | } |
| 830 | 823 | ||
| 831 | #if defined(CONFIG_TCC_BCHECK) | 824 | #if defined(CONFIG_TCC_BCHECK) |
| 832 | 825 | ||
| 833 | static void gen_bounds_call(int v) | 826 | static void gen_bounds_call(TCCState* S, int v) |
| 834 | { | 827 | { |
| 835 | Sym *sym = external_helper_sym(v); | 828 | Sym *sym = external_helper_sym(S, v); |
| 836 | 829 | ||
| 837 | greloc(cur_text_section, sym, ind, R_ARM_PC24); | 830 | greloc(S, cur_text_section, sym, S->tccgen_ind, R_ARM_PC24); |
| 838 | o(0xebfffffe); | 831 | o(S, 0xebfffffe); |
| 839 | } | 832 | } |
| 840 | 833 | ||
| 841 | static void gen_bounds_prolog(void) | 834 | static void gen_bounds_prolog(TCCState* S) |
| 842 | { | 835 | { |
| 843 | /* leave some room for bound checking code */ | 836 | /* leave some room for bound checking code */ |
| 844 | func_bound_offset = lbounds_section->data_offset; | 837 | S->func_bound_offset = lbounds_section->data_offset; |
| 845 | func_bound_ind = ind; | 838 | S->func_bound_ind = S->tccgen_ind; |
| 846 | func_bound_add_epilog = 0; | 839 | S->func_bound_add_epilog = 0; |
| 847 | o(0xe1a00000); /* ld r0,lbounds_section->data_offset */ | 840 | o(S, 0xe1a00000); /* ld r0,lbounds_section->data_offset */ |
| 848 | o(0xe1a00000); | 841 | o(S, 0xe1a00000); |
| 849 | o(0xe1a00000); | 842 | o(S, 0xe1a00000); |
| 850 | o(0xe1a00000); | 843 | o(S, 0xe1a00000); |
| 851 | o(0xe1a00000); /* call __bound_local_new */ | 844 | o(S, 0xe1a00000); /* call __bound_local_new */ |
| 852 | } | 845 | } |
| 853 | 846 | ||
| 854 | static void gen_bounds_epilog(void) | 847 | static void gen_bounds_epilog(TCCState* S) |
| 855 | { | 848 | { |
| 856 | addr_t saved_ind; | 849 | addr_t saved_ind; |
| 857 | addr_t *bounds_ptr; | 850 | addr_t *bounds_ptr; |
| 858 | Sym *sym_data; | 851 | Sym *sym_data; |
| 859 | int offset_modified = func_bound_offset != lbounds_section->data_offset; | 852 | int offset_modified = S->func_bound_offset != lbounds_section->data_offset; |
| 860 | 853 | ||
| 861 | if (!offset_modified && !func_bound_add_epilog) | 854 | if (!offset_modified && !S->func_bound_add_epilog) |
| 862 | return; | 855 | return; |
| 863 | 856 | ||
| 864 | /* add end of table info */ | 857 | /* add end of table info */ |
| 865 | bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t)); | 858 | bounds_ptr = section_ptr_add(S, lbounds_section, sizeof(addr_t)); |
| 866 | *bounds_ptr = 0; | 859 | *bounds_ptr = 0; |
| 867 | 860 | ||
| 868 | sym_data = get_sym_ref(&char_pointer_type, lbounds_section, | 861 | sym_data = get_sym_ref(S, &S->tccgen_char_pointer_type, lbounds_section, |
| 869 | func_bound_offset, lbounds_section->data_offset); | 862 | S->func_bound_offset, lbounds_section->data_offset); |
| 870 | 863 | ||
| 871 | /* generate bound local allocation */ | 864 | /* generate bound local allocation */ |
| 872 | if (offset_modified) { | 865 | if (offset_modified) { |
| 873 | saved_ind = ind; | 866 | saved_ind = S->tccgen_ind; |
| 874 | ind = func_bound_ind; | 867 | S->tccgen_ind = S->func_bound_ind; |
| 875 | o(0xe59f0000); /* ldr r0, [pc] */ | 868 | o(S, 0xe59f0000); /* ldr r0, [pc] */ |
| 876 | o(0xea000000); /* b $+4 */ | 869 | o(S, 0xea000000); /* b $+4 */ |
| 877 | greloc(cur_text_section, sym_data, ind, R_ARM_REL32); | 870 | greloc(S, cur_text_section, sym_data, S->tccgen_ind, R_ARM_REL32); |
| 878 | o(-12); /* lbounds_section->data_offset */ | 871 | o(S, -12); /* lbounds_section->data_offset */ |
| 879 | o(0xe080000f); /* add r0,r0,pc */ | 872 | o(S, 0xe080000f); /* add r0,r0,pc */ |
| 880 | gen_bounds_call(TOK___bound_local_new); | 873 | gen_bounds_call(S, TOK___bound_local_new); |
| 881 | ind = saved_ind; | 874 | S->tccgen_ind = saved_ind; |
| 882 | } | 875 | } |
| 883 | 876 | ||
| 884 | /* generate bound check local freeing */ | 877 | /* generate bound check local freeing */ |
| 885 | o(0xe92d0003); /* push {r0,r1} */ | 878 | o(S, 0xe92d0003); /* push {r0,r1} */ |
| 886 | o(0xed2d0b02); /* vpush {d0} */ | 879 | o(S, 0xed2d0b02); /* vpush {d0} */ |
| 887 | o(0xe59f0000); /* ldr r0, [pc] */ | 880 | o(S, 0xe59f0000); /* ldr r0, [pc] */ |
| 888 | o(0xea000000); /* b $+4 */ | 881 | o(S, 0xea000000); /* b $+4 */ |
| 889 | greloc(cur_text_section, sym_data, ind, R_ARM_REL32); | 882 | greloc(S, cur_text_section, sym_data, S->tccgen_ind, R_ARM_REL32); |
| 890 | o(-12); /* lbounds_section->data_offset */ | 883 | o(S, -12); /* lbounds_section->data_offset */ |
| 891 | o(0xe080000f); /* add r0,r0,pc */ | 884 | o(S, 0xe080000f); /* add r0,r0,pc */ |
| 892 | gen_bounds_call(TOK___bound_local_delete); | 885 | gen_bounds_call(S, TOK___bound_local_delete); |
| 893 | o(0xecbd0b02); /* vpop {d0} */ | 886 | o(S, 0xecbd0b02); /* vpop {d0} */ |
| 894 | o(0xe8bd0003); /* pop {r0,r1} */ | 887 | o(S, 0xe8bd0003); /* pop {r0,r1} */ |
| 895 | } | 888 | } |
| 896 | #endif | 889 | #endif |
| 897 | 890 | ||
| @@ -1077,7 +1070,7 @@ static void add_param_plan(struct plan* plan, int cls, int start, int end, SValu · 179 unmodified lines | |||
| 1077 | Note: this function allocated an array in plan->pplans with tcc_malloc. It | 1070 | Note: this function allocated an array in plan->pplans with tcc_malloc. It |
| 1078 | is the responsibility of the caller to free this array once used (ie not | 1071 | is the responsibility of the caller to free this array once used (ie not |
| 1079 | before copy_params). */ | 1072 | before copy_params). */ |
| 1080 | static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo) | 1073 | static int assign_regs(TCCState *S, int nb_args, int float_abi, struct plan *plan, int *todo) |
| 1081 | { | 1074 | { |
| 1082 | int i, size, align; | 1075 | int i, size, align; |
| 1083 | int ncrn /* next core register number */, nsaa /* next stacked argument address*/; | 1076 | int ncrn /* next core register number */, nsaa /* next stacked argument address*/; |
| @@ -1088,12 +1081,12 @@ static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo) · 4 unmodified lines | |||
| 1088 | 1081 | ||
| 1089 | for(i = nb_args; i-- ;) { | 1082 | for(i = nb_args; i-- ;) { |
| 1090 | int j, start_vfpreg = 0; | 1083 | int j, start_vfpreg = 0; |
| 1091 | CType type = vtop[-i].type; | 1084 | CType type = S->tccgen_vtop[-i].type; |
| 1092 | type.t &= ~VT_ARRAY; | 1085 | type.t &= ~VT_ARRAY; |
| 1093 | size = type_size(&type, &align); | 1086 | size = type_size(&type, &align); |
| 1094 | size = (size + 3) & ~3; | 1087 | size = (size + 3) & ~3; |
| 1095 | align = (align + 3) & ~3; | 1088 | align = (align + 3) & ~3; |
| 1096 | switch(vtop[-i].type.t & VT_BTYPE) { | 1089 | switch(S->tccgen_vtop[-i].type.t & VT_BTYPE) { |
| 1097 | case VT_STRUCT: | 1090 | case VT_STRUCT: |
| 1098 | case VT_FLOAT: | 1091 | case VT_FLOAT: |
| 1099 | case VT_DOUBLE: | 1092 | case VT_DOUBLE: |
| @@ -1101,15 +1094,15 @@ static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo) · 1 unmodified line | |||
| 1101 | if (float_abi == ARM_HARD_FLOAT) { | 1094 | if (float_abi == ARM_HARD_FLOAT) { |
| 1102 | int is_hfa = 0; /* Homogeneous float aggregate */ | 1095 | int is_hfa = 0; /* Homogeneous float aggregate */ |
| 1103 | 1096 | ||
| 1104 | if (is_float(vtop[-i].type.t) | 1097 | if (is_float(S->tccgen_vtop[-i].type.t) |
| 1105 | || (is_hfa = is_hgen_float_aggr(&vtop[-i].type))) { | 1098 | || (is_hfa = is_hgen_float_aggr(&S->tccgen_vtop[-i].type))) { |
| 1106 | int end_vfpreg; | 1099 | int end_vfpreg; |
| 1107 | 1100 | ||
| 1108 | start_vfpreg = assign_vfpreg(&avregs, align, size); | 1101 | start_vfpreg = assign_vfpreg(&avregs, align, size); |
| 1109 | end_vfpreg = start_vfpreg + ((size - 1) >> 2); | 1102 | end_vfpreg = start_vfpreg + ((size - 1) >> 2); |
| 1110 | if (start_vfpreg >= 0) { | 1103 | if (start_vfpreg >= 0) { |
| 1111 | add_param_plan(plan, is_hfa ? VFP_STRUCT_CLASS : VFP_CLASS, | 1104 | add_param_plan(plan, is_hfa ? VFP_STRUCT_CLASS : VFP_CLASS, |
| 1112 | start_vfpreg, end_vfpreg, &vtop[-i]); | 1105 | start_vfpreg, end_vfpreg, &S->tccgen_vtop[-i]); |
| 1113 | continue; | 1106 | continue; |
| 1114 | } else | 1107 | } else |
| 1115 | break; | 1108 | break; |
| @@ -1122,7 +1115,7 @@ static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo) · 6 unmodified lines | |||
| 1122 | * CORE_STRUCT_CLASS or the first of STACK_CLASS. */ | 1115 | * CORE_STRUCT_CLASS or the first of STACK_CLASS. */ |
| 1123 | for (j = ncrn; j < 4 && j < ncrn + size / 4; j++) | 1116 | for (j = ncrn; j < 4 && j < ncrn + size / 4; j++) |
| 1124 | *todo|=(1<<j); | 1117 | *todo|=(1<<j); |
| 1125 | add_param_plan(plan, CORE_STRUCT_CLASS, ncrn, j, &vtop[-i]); | 1118 | add_param_plan(plan, CORE_STRUCT_CLASS, ncrn, j, &S->tccgen_vtop[-i]); |
| 1126 | ncrn += size/4; | 1119 | ncrn += size/4; |
| 1127 | if (ncrn > 4) | 1120 | if (ncrn > 4) |
| 1128 | nsaa = (ncrn - 4) * 4; | 1121 | nsaa = (ncrn - 4) * 4; |
| @@ -1133,20 +1126,20 @@ static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo) · 4 unmodified lines | |||
| 1133 | continue; | 1126 | continue; |
| 1134 | default: | 1127 | default: |
| 1135 | if (ncrn < 4) { | 1128 | if (ncrn < 4) { |
| 1136 | int is_long = (vtop[-i].type.t & VT_BTYPE) == VT_LLONG; | 1129 | int is_long = (S->tccgen_vtop[-i].type.t & VT_BTYPE) == VT_LLONG; |
| 1137 | 1130 | ||
| 1138 | if (is_long) { | 1131 | if (is_long) { |
| 1139 | ncrn = (ncrn + 1) & -2; | 1132 | ncrn = (ncrn + 1) & -2; |
| 1140 | if (ncrn == 4) | 1133 | if (ncrn == 4) |
| 1141 | break; | 1134 | break; |
| 1142 | } | 1135 | } |
| 1143 | add_param_plan(plan, CORE_CLASS, ncrn, ncrn + is_long, &vtop[-i]); | 1136 | add_param_plan(plan, CORE_CLASS, ncrn, ncrn + is_long, &S->tccgen_vtop[-i]); |
| 1144 | ncrn += 1 + is_long; | 1137 | ncrn += 1 + is_long; |
| 1145 | continue; | 1138 | continue; |
| 1146 | } | 1139 | } |
| 1147 | } | 1140 | } |
| 1148 | nsaa = (nsaa + (align - 1)) & ~(align - 1); | 1141 | nsaa = (nsaa + (align - 1)) & ~(align - 1); |
| 1149 | add_param_plan(plan, STACK_CLASS, nsaa, nsaa + size, &vtop[-i]); | 1142 | add_param_plan(plan, STACK_CLASS, nsaa, nsaa + size, &S->tccgen_vtop[-i]); |
| 1150 | nsaa += size; /* size already rounded up before */ | 1143 | nsaa += size; /* size already rounded up before */ |
| 1151 | } | 1144 | } |
| 1152 | return nsaa; | 1145 | return nsaa; |
| @@ -1160,7 +1153,7 @@ static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo) · 7 unmodified lines | |||
| 1160 | todo: a bitmap indicating what core reg will hold a parameter | 1153 | todo: a bitmap indicating what core reg will hold a parameter |
| 1161 | 1154 | ||
| 1162 | Returns the number of SValue added by this function on the value stack */ | 1155 | Returns the number of SValue added by this function on the value stack */ |
| 1163 | static int copy_params(int nb_args, struct plan *plan, int todo) | 1156 | static int copy_params(TCCState* S, int nb_args, struct plan *plan, int todo) |
| 1164 | { | 1157 | { |
| 1165 | int size, align, r, i, nb_extra_sval = 0; | 1158 | int size, align, r, i, nb_extra_sval = 0; |
| 1166 | struct param_plan *pplan; | 1159 | struct param_plan *pplan; |
| @@ -1189,7 +1182,7 @@ again: · 22 unmodified lines | |||
| 1189 | && (i != CORE_CLASS || pplan->sval->r < VT_CONST)) | 1182 | && (i != CORE_CLASS || pplan->sval->r < VT_CONST)) |
| 1190 | continue; | 1183 | continue; |
| 1191 | 1184 | ||
| 1192 | vpushv(pplan->sval); | 1185 | vpushv(S, pplan->sval); |
| 1193 | pplan->sval->r = pplan->sval->r2 = VT_CONST; /* disable entry */ | 1186 | pplan->sval->r = pplan->sval->r2 = VT_CONST; /* disable entry */ |
| 1194 | switch(i) { | 1187 | switch(i) { |
| 1195 | case STACK_CLASS: | 1188 | case STACK_CLASS: |
| @@ -1204,16 +1197,16 @@ again: · 8 unmodified lines | |||
| 1204 | padding = pplan->start - pplan->prev->end; | 1197 | padding = pplan->start - pplan->prev->end; |
| 1205 | size += padding; /* Add padding if any */ | 1198 | size += padding; /* Add padding if any */ |
| 1206 | /* allocate the necessary size on stack */ | 1199 | /* allocate the necessary size on stack */ |
| 1207 | gadd_sp(-size); | 1200 | gadd_sp(S, -size); |
| 1208 | /* generate structure store */ | 1201 | /* generate structure store */ |
| 1209 | r = get_reg(RC_INT); | 1202 | r = get_reg(S, RC_INT); |
| 1210 | o(0xE28D0000|(intr(r)<<12)|padding); /* add r, sp, padding */ | 1203 | o(S, 0xE28D0000|(intr(S, r)<<12)|padding); /* add r, sp, padding */ |
| 1211 | vset(&vtop->type, r | VT_LVAL, 0); | 1204 | vset(S, &S->tccgen_vtop->type, r | VT_LVAL, 0); |
| 1212 | vswap(); | 1205 | vswap(S); |
| 1213 | /* XXX: optimize. Save all register because memcpy can use them */ | 1206 | /* XXX: optimize. Save all register because memcpy can use them */ |
| 1214 | o(0xED2D0A00|(0&1)<<22|(0>>1)<<12|16); /* vpush {s0-s15} */ | 1207 | o(S, 0xED2D0A00|(0&1)<<22|(0>>1)<<12|16); /* vpush {s0-s15} */ |
| 1215 | vstore(); /* memcpy to current sp + potential padding */ | 1208 | vstore(S); /* memcpy to current sp + potential padding */ |
| 1216 | o(0xECBD0A00|(0&1)<<22|(0>>1)<<12|16); /* vpop {s0-s15} */ | 1209 | o(S, 0xECBD0A00|(0&1)<<22|(0>>1)<<12|16); /* vpop {s0-s15} */ |
| 1217 | 1210 | ||
| 1218 | /* Homogeneous float aggregate are loaded to VFP registers | 1211 | /* Homogeneous float aggregate are loaded to VFP registers |
| 1219 | immediately since there is no way of loading data in multiple | 1212 | immediately since there is no way of loading data in multiple |
| @@ -1222,23 +1215,23 @@ again: · 2 unmodified lines | |||
| 1222 | if (i == VFP_STRUCT_CLASS) { | 1215 | if (i == VFP_STRUCT_CLASS) { |
| 1223 | int first = pplan->start, nb = pplan->end - first + 1; | 1216 | int first = pplan->start, nb = pplan->end - first + 1; |
| 1224 | /* vpop.32 {pplan->start, ..., pplan->end} */ | 1217 | /* vpop.32 {pplan->start, ..., pplan->end} */ |
| 1225 | o(0xECBD0A00|(first&1)<<22|(first>>1)<<12|nb); | 1218 | o(S, 0xECBD0A00|(first&1)<<22|(first>>1)<<12|nb); |
| 1226 | /* No need to write the register used to a SValue since VFP regs | 1219 | /* No need to write the register used to a SValue since VFP regs |
| 1227 | cannot be used for gcall_or_jmp */ | 1220 | cannot be used for gcall_or_jmp */ |
| 1228 | } | 1221 | } |
| 1229 | } else { | 1222 | } else { |
| 1230 | if (is_float(pplan->sval->type.t)) { | 1223 | if (is_float(pplan->sval->type.t)) { |
| 1231 | #ifdef TCC_ARM_VFP | 1224 | #ifdef TCC_ARM_VFP |
| 1232 | r = vfpr(gv(RC_FLOAT)) << 12; | 1225 | r = vfpr(S, gv(S, RC_FLOAT)) << 12; |
| 1233 | if ((pplan->sval->type.t & VT_BTYPE) == VT_FLOAT) | 1226 | if ((pplan->sval->type.t & VT_BTYPE) == VT_FLOAT) |
| 1234 | size = 4; | 1227 | size = 4; |
| 1235 | else { | 1228 | else { |
| 1236 | size = 8; | 1229 | size = 8; |
| 1237 | r |= 0x101; /* vpush.32 -> vpush.64 */ | 1230 | r |= 0x101; /* vpush.32 -> vpush.64 */ |
| 1238 | } | 1231 | } |
| 1239 | o(0xED2D0A01 + r); /* vpush */ | 1232 | o(S, 0xED2D0A01 + r); /* vpush */ |
| 1240 | #else | 1233 | #else |
| 1241 | r = fpr(gv(RC_FLOAT)) << 12; | 1234 | r = fpr(S, gv(S, RC_FLOAT)) << 12; |
| 1242 | if ((pplan->sval->type.t & VT_BTYPE) == VT_FLOAT) | 1235 | if ((pplan->sval->type.t & VT_BTYPE) == VT_FLOAT) |
| 1243 | size = 4; | 1236 | size = 4; |
| 1244 | else if ((pplan->sval->type.t & VT_BTYPE) == VT_DOUBLE) | 1237 | else if ((pplan->sval->type.t & VT_BTYPE) == VT_DOUBLE) |
| @@ -1251,49 +1244,49 @@ again: · 6 unmodified lines | |||
| 1251 | else if(size == 8) | 1244 | else if(size == 8) |
| 1252 | r|=0x8000; | 1245 | r|=0x8000; |
| 1253 | 1246 | ||
| 1254 | o(0xED2D0100|r|(size>>2)); /* some kind of vpush for FPA */ | 1247 | o(S, 0xED2D0100|r|(size>>2)); /* some kind of vpush for FPA */ |
| 1255 | #endif | 1248 | #endif |
| 1256 | } else { | 1249 | } else { |
| 1257 | /* simple type (currently always same size) */ | 1250 | /* simple type (currently always same size) */ |
| 1258 | /* XXX: implicit cast ? */ | 1251 | /* XXX: implicit cast ? */ |
| 1259 | size=4; | 1252 | size=4; |
| 1260 | if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) { | 1253 | if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) { |
| 1261 | lexpand(); | 1254 | lexpand(S); |
| 1262 | size = 8; | 1255 | size = 8; |
| 1263 | r = gv(RC_INT); | 1256 | r = gv(S, RC_INT); |
| 1264 | o(0xE52D0004|(intr(r)<<12)); /* push r */ | 1257 | o(S, 0xE52D0004|(intr(S, r)<<12)); /* push r */ |
| 1265 | vtop--; | 1258 | S->tccgen_vtop--; |
| 1266 | } | 1259 | } |
| 1267 | r = gv(RC_INT); | 1260 | r = gv(S, RC_INT); |
| 1268 | o(0xE52D0004|(intr(r)<<12)); /* push r */ | 1261 | o(S, 0xE52D0004|(intr(S, r)<<12)); /* push r */ |
| 1269 | } | 1262 | } |
| 1270 | if (i == STACK_CLASS && pplan->prev) | 1263 | if (i == STACK_CLASS && pplan->prev) |
| 1271 | gadd_sp(pplan->prev->end - pplan->start); /* Add padding if any */ | 1264 | gadd_sp(S, pplan->prev->end - pplan->start); /* Add padding if any */ |
| 1272 | } | 1265 | } |
| 1273 | break; | 1266 | break; |
| 1274 | 1267 | ||
| 1275 | case VFP_CLASS: | 1268 | case VFP_CLASS: |
| 1276 | gv(regmask(TREG_F0 + (pplan->start >> 1))); | 1269 | gv(S, regmask(S, TREG_F0 + (pplan->start >> 1))); |
| 1277 | if (pplan->start & 1) { /* Must be in upper part of double register */ | 1270 | if (pplan->start & 1) { /* Must be in upper part of double register */ |
| 1278 | o(0xEEF00A40|((pplan->start>>1)<<12)|(pplan->start>>1)); /* vmov.f32 s(n+1), sn */ | 1271 | o(S, 0xEEF00A40|((pplan->start>>1)<<12)|(pplan->start>>1)); /* vmov.f32 s(n+1), sn */ |
| 1279 | vtop->r = VT_CONST; /* avoid being saved on stack by gv for next float */ | 1272 | S->tccgen_vtop->r = VT_CONST; /* avoid being saved on stack by gv for next float */ |
| 1280 | } | 1273 | } |
| 1281 | break; | 1274 | break; |
| 1282 | 1275 | ||
| 1283 | case CORE_CLASS: | 1276 | case CORE_CLASS: |
| 1284 | if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) { | 1277 | if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) { |
| 1285 | lexpand(); | 1278 | lexpand(S); |
| 1286 | gv(regmask(pplan->end)); | 1279 | gv(S, regmask(S, pplan->end)); |
| 1287 | pplan->sval->r2 = vtop->r; | 1280 | pplan->sval->r2 = S->tccgen_vtop->r; |
| 1288 | vtop--; | 1281 | S->tccgen_vtop--; |
| 1289 | } | 1282 | } |
| 1290 | gv(regmask(pplan->start)); | 1283 | gv(S, regmask(S, pplan->start)); |
| 1291 | /* Mark register as used so that gcall_or_jmp use another one | 1284 | /* Mark register as used so that gcall_or_jmp use another one |
| 1292 | (regs >=4 are free as never used to pass parameters) */ | 1285 | (regs >=4 are free as never used to pass parameters) */ |
| 1293 | pplan->sval->r = vtop->r; | 1286 | pplan->sval->r = S->tccgen_vtop->r; |
| 1294 | break; | 1287 | break; |
| 1295 | } | 1288 | } |
| 1296 | vtop--; | 1289 | S->tccgen_vtop--; |
| 1297 | } | 1290 | } |
| 1298 | } | 1291 | } |
| 1299 | 1292 | ||
| @@ -1304,10 +1297,10 @@ again: · 4 unmodified lines | |||
| 1304 | 1297 | ||
| 1305 | /* Manually free remaining registers since next parameters are loaded | 1298 | /* Manually free remaining registers since next parameters are loaded |
| 1306 | * manually, without the help of gv(int). */ | 1299 | * manually, without the help of gv(int). */ |
| 1307 | save_regs(nb_args); | 1300 | save_regs(S, nb_args); |
| 1308 | 1301 | ||
| 1309 | if(todo) { | 1302 | if(todo) { |
| 1310 | o(0xE8BD0000|todo); /* pop {todo} */ | 1303 | o(S, 0xE8BD0000|todo); /* pop {todo} */ |
| 1311 | for(pplan = plan->clsplans[CORE_STRUCT_CLASS]; pplan; pplan = pplan->prev) { | 1304 | for(pplan = plan->clsplans[CORE_STRUCT_CLASS]; pplan; pplan = pplan->prev) { |
| 1312 | int r; | 1305 | int r; |
| 1313 | pplan->sval->r = pplan->start; | 1306 | pplan->sval->r = pplan->start; |
| @@ -1318,8 +1311,8 @@ again: · 4 unmodified lines | |||
| 1318 | for (r = pplan->start + 1; r <= pplan->end; r++) { | 1311 | for (r = pplan->start + 1; r <= pplan->end; r++) { |
| 1319 | if (todo & (1 << r)) { | 1312 | if (todo & (1 << r)) { |
| 1320 | nb_extra_sval++; | 1313 | nb_extra_sval++; |
| 1321 | vpushi(0); | 1314 | vpushi(S, 0); |
| 1322 | vtop->r = r; | 1315 | S->tccgen_vtop->r = r; |
| 1323 | } | 1316 | } |
| 1324 | } | 1317 | } |
| 1325 | } | 1318 | } |
| @@ -1330,7 +1323,7 @@ again: · 4 unmodified lines | |||
| 1330 | /* Generate function call. The function address is pushed first, then | 1323 | /* Generate function call. The function address is pushed first, then |
| 1331 | all the parameters in call order. This functions pops all the | 1324 | all the parameters in call order. This functions pops all the |
| 1332 | parameters and the function address. */ | 1325 | parameters and the function address. */ |
| 1333 | void gfunc_call(int nb_args) | 1326 | void gfunc_call(TCCState* S, int nb_args) |
| 1334 | { | 1327 | { |
| 1335 | int r, args_size; | 1328 | int r, args_size; |
| 1336 | int def_float_abi = float_abi; | 1329 | int def_float_abi = float_abi; |
| @@ -1341,62 +1334,62 @@ void gfunc_call(int nb_args) · 4 unmodified lines | |||
| 1341 | #endif | 1334 | #endif |
| 1342 | 1335 | ||
| 1343 | #ifdef CONFIG_TCC_BCHECK | 1336 | #ifdef CONFIG_TCC_BCHECK |
| 1344 | if (tcc_state->do_bounds_check) | 1337 | if (S->do_bounds_check) |
| 1345 | gbound_args(nb_args); | 1338 | gbound_args(S, nb_args); |
| 1346 | #endif | 1339 | #endif |
| 1347 | 1340 | ||
| 1348 | #ifdef TCC_ARM_EABI | 1341 | #ifdef TCC_ARM_EABI |
| 1349 | if (float_abi == ARM_HARD_FLOAT) { | 1342 | if (float_abi == ARM_HARD_FLOAT) { |
| 1350 | variadic = (vtop[-nb_args].type.ref->f.func_type == FUNC_ELLIPSIS); | 1343 | variadic = (S->tccgen_vtop[-nb_args].type.ref->f.func_type == FUNC_ELLIPSIS); |
| 1351 | if (variadic || floats_in_core_regs(&vtop[-nb_args])) | 1344 | if (variadic || floats_in_core_regs(&S->tccgen_vtop[-nb_args])) |
| 1352 | float_abi = ARM_SOFTFP_FLOAT; | 1345 | float_abi = ARM_SOFTFP_FLOAT; |
| 1353 | } | 1346 | } |
| 1354 | #endif | 1347 | #endif |
| 1355 | /* cannot let cpu flags if other instruction are generated. Also avoid leaving | 1348 | /* cannot let cpu flags if other instruction are generated. Also avoid leaving |
| 1356 | VT_JMP anywhere except on the top of the stack because it would complicate | 1349 | VT_JMP anywhere except on the top of the stack because it would complicate |
| 1357 | the code generator. */ | 1350 | the code generator. */ |
| 1358 | r = vtop->r & VT_VALMASK; | 1351 | r = S->tccgen_vtop->r & VT_VALMASK; |
| 1359 | if (r == VT_CMP || (r & ~1) == VT_JMP) | 1352 | if (r == VT_CMP || (r & ~1) == VT_JMP) |
| 1360 | gv(RC_INT); | 1353 | gv(S, RC_INT); |
| 1361 | 1354 | ||
| 1362 | memset(&plan, 0, sizeof plan); | 1355 | memset(&plan, 0, sizeof plan); |
| 1363 | if (nb_args) | 1356 | if (nb_args) |
| 1364 | plan.pplans = tcc_malloc(nb_args * sizeof(*plan.pplans)); | 1357 | plan.pplans = tcc_malloc(S, nb_args * sizeof(*plan.pplans)); |
| 1365 | 1358 | ||
| 1366 | args_size = assign_regs(nb_args, float_abi, &plan, &todo); | 1359 | args_size = assign_regs(S, nb_args, float_abi, &plan, &todo); |
| 1367 | 1360 | ||
| 1368 | #ifdef TCC_ARM_EABI | 1361 | #ifdef TCC_ARM_EABI |
| 1369 | if (args_size & 7) { /* Stack must be 8 byte aligned at fct call for EABI */ | 1362 | if (args_size & 7) { /* Stack must be 8 byte aligned at fct call for EABI */ |
| 1370 | args_size = (args_size + 7) & ~7; | 1363 | args_size = (args_size + 7) & ~7; |
| 1371 | o(0xE24DD004); /* sub sp, sp, #4 */ | 1364 | o(S, 0xE24DD004); /* sub sp, sp, #4 */ |
| 1372 | } | 1365 | } |
| 1373 | #endif | 1366 | #endif |
| 1374 | 1367 | ||
| 1375 | nb_args += copy_params(nb_args, &plan, todo); | 1368 | nb_args += copy_params(S, nb_args, &plan, todo); |
| 1376 | tcc_free(plan.pplans); | 1369 | tcc_free(S, plan.pplans); |
| 1377 | 1370 | ||
| 1378 | /* Move fct SValue on top as required by gcall_or_jmp */ | 1371 | /* Move fct SValue on top as required by gcall_or_jmp */ |
| 1379 | vrotb(nb_args + 1); | 1372 | vrotb(S, nb_args + 1); |
| 1380 | gcall_or_jmp(0); | 1373 | gcall_or_jmp(S, 0); |
| 1381 | if (args_size) | 1374 | if (args_size) |
| 1382 | gadd_sp(args_size); /* pop all parameters passed on the stack */ | 1375 | gadd_sp(S, args_size); /* pop all parameters passed on the stack */ |
| 1383 | #if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP) | 1376 | #if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP) |
| 1384 | if(float_abi == ARM_SOFTFP_FLOAT && is_float(vtop->type.ref->type.t)) { | 1377 | if(float_abi == ARM_SOFTFP_FLOAT && is_float(S->tccgen_vtop->type.ref->type.t)) { |
| 1385 | if((vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) { | 1378 | if((S->tccgen_vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) { |
| 1386 | o(0xEE000A10); /*vmov s0, r0 */ | 1379 | o(S, 0xEE000A10); /*vmov s0, r0 */ |
| 1387 | } else { | 1380 | } else { |
| 1388 | o(0xEE000B10); /* vmov.32 d0[0], r0 */ | 1381 | o(S, 0xEE000B10); /* vmov.32 d0[0], r0 */ |
| 1389 | o(0xEE201B10); /* vmov.32 d0[1], r1 */ | 1382 | o(S, 0xEE201B10); /* vmov.32 d0[1], r1 */ |
| 1390 | } | 1383 | } |
| 1391 | } | 1384 | } |
| 1392 | #endif | 1385 | #endif |
| 1393 | vtop -= nb_args + 1; /* Pop all params and fct address from value stack */ | 1386 | S->tccgen_vtop -= nb_args + 1; /* Pop all params and fct address from value stack */ |
| 1394 | leaffunc = 0; /* we are calling a function, so we aren't in a leaf function */ | 1387 | leaffunc = 0; /* we are calling a function, so we aren't in a leaf function */ |
| 1395 | float_abi = def_float_abi; | 1388 | float_abi = def_float_abi; |
| 1396 | } | 1389 | } |
| 1397 | 1390 | ||
| 1398 | /* generate function prolog of type 't' */ | 1391 | /* generate function prolog of type 't' */ |
| 1399 | void gfunc_prolog(Sym *func_sym) | 1392 | void gfunc_prolog(TCCState* S, Sym *func_sym) |
| 1400 | { | 1393 | { |
| 1401 | CType *func_type = &func_sym->type; | 1394 | CType *func_type = &func_sym->type; |
| 1402 | Sym *sym,*sym2; | 1395 | Sym *sym,*sym2; |
| @@ -1411,17 +1404,17 @@ void gfunc_prolog(Sym *func_sym) · 8 unmodified lines | |||
| 1411 | sym = func_type->ref; | 1404 | sym = func_type->ref; |
| 1412 | 1405 | ||
| 1413 | n = nf = 0; | 1406 | n = nf = 0; |
| 1414 | if ((func_vt.t & VT_BTYPE) == VT_STRUCT && | 1407 | if ((S->tccgen_func_vt.t & VT_BTYPE) == VT_STRUCT && |
| 1415 | !gfunc_sret(&func_vt, func_var, &ret_type, &align, &rs)) | 1408 | !gfunc_sret(&S->tccgen_func_vt, S->tccgen_func_var, &ret_type, &align, &rs)) |
| 1416 | { | 1409 | { |
| 1417 | n++; | 1410 | n++; |
| 1418 | struct_ret = 1; | 1411 | struct_ret = 1; |
| 1419 | func_vc = 12; /* Offset from fp of the place to store the result */ | 1412 | S->tccgen_func_vc = 12; /* Offset from fp of the place to store the result */ |
| 1420 | } | 1413 | } |
| 1421 | for(sym2 = sym->next; sym2 && (n < 4 || nf < 16); sym2 = sym2->next) { | 1414 | for(sym2 = sym->next; sym2 && (n < 4 || nf < 16); sym2 = sym2->next) { |
| 1422 | size = type_size(&sym2->type, &align); | 1415 | size = type_size(&sym2->type, &align); |
| 1423 | #ifdef TCC_ARM_EABI | 1416 | #ifdef TCC_ARM_EABI |
| 1424 | if (float_abi == ARM_HARD_FLOAT && !func_var && | 1417 | if (float_abi == ARM_HARD_FLOAT && !S->tccgen_func_var && |
| 1425 | (is_float(sym2->type.t) || is_hgen_float_aggr(&sym2->type))) { | 1418 | (is_float(sym2->type.t) || is_hgen_float_aggr(&sym2->type))) { |
| 1426 | int tmpnf = assign_vfpreg(&avregs, align, size); | 1419 | int tmpnf = assign_vfpreg(&avregs, align, size); |
| 1427 | tmpnf += (size + 3) / 4; | 1420 | tmpnf += (size + 3) / 4; |
| @@ -1431,8 +1424,8 @@ void gfunc_prolog(Sym *func_sym) · 3 unmodified lines | |||
| 1431 | if (n < 4) | 1424 | if (n < 4) |
| 1432 | n += (size + 3) / 4; | 1425 | n += (size + 3) / 4; |
| 1433 | } | 1426 | } |
| 1434 | o(0xE1A0C00D); /* mov ip,sp */ | 1427 | o(S, 0xE1A0C00D); /* mov ip,sp */ |
| 1435 | if (func_var) | 1428 | if (S->tccgen_func_var) |
| 1436 | n=4; | 1429 | n=4; |
| 1437 | if (n) { | 1430 | if (n) { |
| 1438 | if(n>4) | 1431 | if(n>4) |
| @@ -1440,22 +1433,22 @@ void gfunc_prolog(Sym *func_sym) · 1 unmodified line | |||
| 1440 | #ifdef TCC_ARM_EABI | 1433 | #ifdef TCC_ARM_EABI |
| 1441 | n=(n+1)&-2; | 1434 | n=(n+1)&-2; |
| 1442 | #endif | 1435 | #endif |
| 1443 | o(0xE92D0000|((1<<n)-1)); /* save r0-r4 on stack if needed */ | 1436 | o(S, 0xE92D0000|((1<<n)-1)); /* save r0-r4 on stack if needed */ |
| 1444 | } | 1437 | } |
| 1445 | if (nf) { | 1438 | if (nf) { |
| 1446 | if (nf>16) | 1439 | if (nf>16) |
| 1447 | nf=16; | 1440 | nf=16; |
| 1448 | nf=(nf+1)&-2; /* nf => HARDFLOAT => EABI */ | 1441 | nf=(nf+1)&-2; /* nf => HARDFLOAT => EABI */ |
| 1449 | o(0xED2D0A00|nf); /* save s0-s15 on stack if needed */ | 1442 | o(S, 0xED2D0A00|nf); /* save s0-s15 on stack if needed */ |
| 1450 | } | 1443 | } |
| 1451 | o(0xE92D5800); /* save fp, ip, lr */ | 1444 | o(S, 0xE92D5800); /* save fp, ip, lr */ |
| 1452 | o(0xE1A0B00D); /* mov fp, sp */ | 1445 | o(S, 0xE1A0B00D); /* mov fp, sp */ |
| 1453 | func_sub_sp_offset = ind; | 1446 | func_sub_sp_offset = S->tccgen_ind; |
| 1454 | o(0xE1A00000); /* nop, leave space for stack adjustment in epilog */ | 1447 | o(S, 0xE1A00000); /* nop, leave space for stack adjustment in epilog */ |
| 1455 | 1448 | ||
| 1456 | #ifdef TCC_ARM_EABI | 1449 | #ifdef TCC_ARM_EABI |
| 1457 | if (float_abi == ARM_HARD_FLOAT) { | 1450 | if (float_abi == ARM_HARD_FLOAT) { |
| 1458 | func_vc += nf * 4; | 1451 | S->tccgen_func_vc += nf * 4; |
| 1459 | memset(&avregs, 0, sizeof avregs); | 1452 | memset(&avregs, 0, sizeof avregs); |
| 1460 | } | 1453 | } |
| 1461 | #endif | 1454 | #endif |
| @@ -1467,7 +1460,7 @@ void gfunc_prolog(Sym *func_sym) · 5 unmodified lines | |||
| 1467 | size = (size + 3) >> 2; | 1460 | size = (size + 3) >> 2; |
| 1468 | align = (align + 3) & ~3; | 1461 | align = (align + 3) & ~3; |
| 1469 | #ifdef TCC_ARM_EABI | 1462 | #ifdef TCC_ARM_EABI |
| 1470 | if (float_abi == ARM_HARD_FLOAT && !func_var && (is_float(sym->type.t) | 1463 | if (float_abi == ARM_HARD_FLOAT && !S->tccgen_func_var && (is_float(sym->type.t) |
| 1471 | || is_hgen_float_aggr(&sym->type))) { | 1464 | || is_hgen_float_aggr(&sym->type))) { |
| 1472 | int fpn = assign_vfpreg(&avregs, align, size << 2); | 1465 | int fpn = assign_vfpreg(&avregs, align, size << 2); |
| 1473 | if (fpn >= 0) | 1466 | if (fpn >= 0) |
| @@ -1492,42 +1485,42 @@ from_stack: · 18 unmodified lines | |||
| 1492 | addr = (n + nf + sn) * 4; | 1485 | addr = (n + nf + sn) * 4; |
| 1493 | sn += size; | 1486 | sn += size; |
| 1494 | } | 1487 | } |
| 1495 | sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL, | 1488 | sym_push(S, sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL, |
| 1496 | addr + 12); | 1489 | addr + 12); |
| 1497 | } | 1490 | } |
| 1498 | last_itod_magic=0; | 1491 | last_itod_magic=0; |
| 1499 | leaffunc = 1; | 1492 | leaffunc = 1; |
| 1500 | loc = 0; | 1493 | S->tccgen_loc = 0; |
| 1501 | #ifdef CONFIG_TCC_BCHECK | 1494 | #ifdef CONFIG_TCC_BCHECK |
| 1502 | if (tcc_state->do_bounds_check) | 1495 | if (S->do_bounds_check) |
| 1503 | gen_bounds_prolog(); | 1496 | gen_bounds_prolog(S); |
| 1504 | #endif | 1497 | #endif |
| 1505 | } | 1498 | } |
| 1506 | 1499 | ||
| 1507 | /* generate function epilog */ | 1500 | /* generate function epilog */ |
| 1508 | void gfunc_epilog(void) | 1501 | void gfunc_epilog(TCCState* S) |
| 1509 | { | 1502 | { |
| 1510 | uint32_t x; | 1503 | uint32_t x; |
| 1511 | int diff; | 1504 | int diff; |
| 1512 | 1505 | ||
| 1513 | #ifdef CONFIG_TCC_BCHECK | 1506 | #ifdef CONFIG_TCC_BCHECK |
| 1514 | if (tcc_state->do_bounds_check) | 1507 | if (S->do_bounds_check) |
| 1515 | gen_bounds_epilog(); | 1508 | gen_bounds_epilog(S); |
| 1516 | #endif | 1509 | #endif |
| 1517 | /* Copy float return value to core register if base standard is used and | 1510 | /* Copy float return value to core register if base standard is used and |
| 1518 | float computation is made with VFP */ | 1511 | float computation is made with VFP */ |
| 1519 | #if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP) | 1512 | #if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP) |
| 1520 | if ((float_abi == ARM_SOFTFP_FLOAT || func_var) && is_float(func_vt.t)) { | 1513 | if ((float_abi == ARM_SOFTFP_FLOAT || S->tccgen_func_var) && is_float(S->tccgen_func_vt.t)) { |
| 1521 | if((func_vt.t & VT_BTYPE) == VT_FLOAT) | 1514 | if((S->tccgen_func_vt.t & VT_BTYPE) == VT_FLOAT) |
| 1522 | o(0xEE100A10); /* fmrs r0, s0 */ | 1515 | o(S, 0xEE100A10); /* fmrs r0, s0 */ |
| 1523 | else { | 1516 | else { |
| 1524 | o(0xEE100B10); /* fmrdl r0, d0 */ | 1517 | o(S, 0xEE100B10); /* fmrdl r0, d0 */ |
| 1525 | o(0xEE301B10); /* fmrdh r1, d0 */ | 1518 | o(S, 0xEE301B10); /* fmrdh r1, d0 */ |
| 1526 | } | 1519 | } |
| 1527 | } | 1520 | } |
| 1528 | #endif | 1521 | #endif |
| 1529 | o(0xE89BA800); /* restore fp, sp, pc */ | 1522 | o(S, 0xE89BA800); /* restore fp, sp, pc */ |
| 1530 | diff = (-loc + 3) & -4; | 1523 | diff = (-S->tccgen_loc + 3) & -4; |
| 1531 | #ifdef TCC_ARM_EABI | 1524 | #ifdef TCC_ARM_EABI |
| 1532 | if(!leaffunc) | 1525 | if(!leaffunc) |
| 1533 | diff = ((diff + 11) & -8) - 4; | 1526 | diff = ((diff + 11) & -8) - 4; |
| @@ -1538,74 +1531,74 @@ void gfunc_epilog(void) · 4 unmodified lines | |||
| 1538 | *(uint32_t *)(cur_text_section->data + func_sub_sp_offset) = x; | 1531 | *(uint32_t *)(cur_text_section->data + func_sub_sp_offset) = x; |
| 1539 | else { | 1532 | else { |
| 1540 | int addr; | 1533 | int addr; |
| 1541 | addr=ind; | 1534 | addr=S->tccgen_ind; |
| 1542 | o(0xE59FC004); /* ldr ip,[pc+4] */ | 1535 | o(S, 0xE59FC004); /* ldr ip,[pc+4] */ |
| 1543 | o(0xE04BD00C); /* sub sp,fp,ip */ | 1536 | o(S, 0xE04BD00C); /* sub sp,fp,ip */ |
| 1544 | o(0xE1A0F00E); /* mov pc,lr */ | 1537 | o(S, 0xE1A0F00E); /* mov pc,lr */ |
| 1545 | o(diff); | 1538 | o(S, diff); |
| 1546 | *(uint32_t *)(cur_text_section->data + func_sub_sp_offset) = 0xE1000000|encbranch(func_sub_sp_offset,addr,1); | 1539 | *(uint32_t *)(cur_text_section->data + func_sub_sp_offset) = 0xE1000000|encbranch(S, func_sub_sp_offset,addr,1); |
| 1547 | } | 1540 | } |
| 1548 | } | 1541 | } |
| 1549 | } | 1542 | } |
| 1550 | 1543 | ||
| 1551 | ST_FUNC void gen_fill_nops(int bytes) | 1544 | ST_FUNC void gen_fill_nops(TCCState* S, int bytes) |
| 1552 | { | 1545 | { |
| 1553 | if ((bytes & 3)) | 1546 | if ((bytes & 3)) |
| 1554 | tcc_error("alignment of code section not multiple of 4"); | 1547 | tcc_error(S, "alignment of code section not multiple of 4"); |
| 1555 | while (bytes > 0) { | 1548 | while (bytes > 0) { |
| 1556 | o(0xE1A00000); | 1549 | o(S, 0xE1A00000); |
| 1557 | bytes -= 4; | 1550 | bytes -= 4; |
| 1558 | } | 1551 | } |
| 1559 | } | 1552 | } |
| 1560 | 1553 | ||
| 1561 | /* generate a jump to a label */ | 1554 | /* generate a jump to a label */ |
| 1562 | ST_FUNC int gjmp(int t) | 1555 | ST_FUNC int gjmp(TCCState* S, int t) |
| 1563 | { | 1556 | { |
| 1564 | int r; | 1557 | int r; |
| 1565 | if (nocode_wanted) | 1558 | if (S->tccgen_nocode_wanted) |
| 1566 | return t; | 1559 | return t; |
| 1567 | r=ind; | 1560 | r=S->tccgen_ind; |
| 1568 | o(0xE0000000|encbranch(r,t,1)); | 1561 | o(S, 0xE0000000|encbranch(S, r,t,1)); |
| 1569 | return r; | 1562 | return r; |
| 1570 | } | 1563 | } |
| 1571 | 1564 | ||
| 1572 | /* generate a jump to a fixed address */ | 1565 | /* generate a jump to a fixed address */ |
| 1573 | ST_FUNC void gjmp_addr(int a) | 1566 | ST_FUNC void gjmp_addr(TCCState* S, int a) |
| 1574 | { | 1567 | { |
| 1575 | gjmp(a); | 1568 | gjmp(S, a); |
| 1576 | } | 1569 | } |
| 1577 | 1570 | ||
| 1578 | ST_FUNC int gjmp_cond(int op, int t) | 1571 | ST_FUNC int gjmp_cond(TCCState* S, int op, int t) |
| 1579 | { | 1572 | { |
| 1580 | int r; | 1573 | int r; |
| 1581 | if (nocode_wanted) | 1574 | if (S->tccgen_nocode_wanted) |
| 1582 | return t; | 1575 | return t; |
| 1583 | r=ind; | 1576 | r=S->tccgen_ind; |
| 1584 | op=mapcc(op); | 1577 | op=mapcc(S, op); |
| 1585 | op|=encbranch(r,t,1); | 1578 | op|=encbranch(S, r,t,1); |
| 1586 | o(op); | 1579 | o(S, op); |
| 1587 | return r; | 1580 | return r; |
| 1588 | } | 1581 | } |
| 1589 | 1582 | ||
| 1590 | ST_FUNC int gjmp_append(int n, int t) | 1583 | ST_FUNC int gjmp_append(TCCState* S, int n, int t) |
| 1591 | { | 1584 | { |
| 1592 | uint32_t *x; | 1585 | uint32_t *x; |
| 1593 | int p,lp; | 1586 | int p,lp; |
| 1594 | if(n) { | 1587 | if(n) { |
| 1595 | p = n; | 1588 | p = n; |
| 1596 | do { | 1589 | do { |
| 1597 | p = decbranch(lp=p); | 1590 | p = decbranch(S, lp=p); |
| 1598 | } while(p); | 1591 | } while(p); |
| 1599 | x = (uint32_t *)(cur_text_section->data + lp); | 1592 | x = (uint32_t *)(cur_text_section->data + lp); |
| 1600 | *x &= 0xff000000; | 1593 | *x &= 0xff000000; |
| 1601 | *x |= encbranch(lp,t,1); | 1594 | *x |= encbranch(S, lp,t,1); |
| 1602 | t = n; | 1595 | t = n; |
| 1603 | } | 1596 | } |
| 1604 | return t; | 1597 | return t; |
| 1605 | } | 1598 | } |
| 1606 | 1599 | ||
| 1607 | /* generate an integer binary operation */ | 1600 | /* generate an integer binary operation */ |
| 1608 | void gen_opi(int op) | 1601 | void gen_opi(TCCState* S, int op) |
| 1609 | { | 1602 | { |
| 1610 | int c, func = 0; | 1603 | int c, func = 0; |
| 1611 | uint32_t opc = 0, r, fr; | 1604 | uint32_t opc = 0, r, fr; |
| @@ -1650,11 +1643,11 @@ void gen_opi(int op) · 38 unmodified lines | |||
| 1650 | c=1; | 1643 | c=1; |
| 1651 | break; | 1644 | break; |
| 1652 | case '*': | 1645 | case '*': |
| 1653 | gv2(RC_INT, RC_INT); | 1646 | gv2(S, RC_INT, RC_INT); |
| 1654 | r = vtop[-1].r; | 1647 | r = S->tccgen_vtop[-1].r; |
| 1655 | fr = vtop[0].r; | 1648 | fr = S->tccgen_vtop[0].r; |
| 1656 | vtop--; | 1649 | S->tccgen_vtop--; |
| 1657 | o(0xE0000090|(intr(r)<<16)|(intr(r)<<8)|intr(fr)); | 1650 | o(S, 0xE0000090|(intr(S, r)<<16)|(intr(S, r)<<8)|intr(S, fr)); |
| 1658 | return; | 1651 | return; |
| 1659 | case TOK_SHL: | 1652 | case TOK_SHL: |
| 1660 | opc = 0; | 1653 | opc = 0; |
| @@ -1696,12 +1689,12 @@ void gen_opi(int op) · 35 unmodified lines | |||
| 1696 | c=3; | 1689 | c=3; |
| 1697 | break; | 1690 | break; |
| 1698 | case TOK_UMULL: | 1691 | case TOK_UMULL: |
| 1699 | gv2(RC_INT, RC_INT); | 1692 | gv2(S, RC_INT, RC_INT); |
| 1700 | r=intr(vtop[-1].r2=get_reg(RC_INT)); | 1693 | r=intr(S, S->tccgen_vtop[-1].r2=get_reg(S, RC_INT)); |
| 1701 | c=vtop[-1].r; | 1694 | c=S->tccgen_vtop[-1].r; |
| 1702 | vtop[-1].r=get_reg_ex(RC_INT,regmask(c)); | 1695 | S->tccgen_vtop[-1].r=get_reg_ex(S, RC_INT,regmask(S, c)); |
| 1703 | vtop--; | 1696 | S->tccgen_vtop--; |
| 1704 | o(0xE0800090|(r<<16)|(intr(vtop->r)<<12)|(intr(c)<<8)|intr(vtop[1].r)); | 1697 | o(S, 0xE0800090|(r<<16)|(intr(S, S->tccgen_vtop->r)<<12)|(intr(S, c)<<8)|intr(S, S->tccgen_vtop[1].r)); |
| 1705 | return; | 1698 | return; |
| 1706 | default: | 1699 | default: |
| 1707 | opc = 0x15; | 1700 | opc = 0x15; |
| @@ -1710,128 +1703,128 @@ void gen_opi(int op) · 2 unmodified lines | |||
| 1710 | } | 1703 | } |
| 1711 | switch(c) { | 1704 | switch(c) { |
| 1712 | case 1: | 1705 | case 1: |
| 1713 | if((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { | 1706 | if((S->tccgen_vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { |
| 1714 | if(opc == 4 || opc == 5 || opc == 0xc) { | 1707 | if(opc == 4 || opc == 5 || opc == 0xc) { |
| 1715 | vswap(); | 1708 | vswap(S); |
| 1716 | opc|=2; // sub -> rsb | 1709 | opc|=2; // sub -> rsb |
| 1717 | } | 1710 | } |
| 1718 | } | 1711 | } |
| 1719 | if ((vtop->r & VT_VALMASK) == VT_CMP || | 1712 | if ((S->tccgen_vtop->r & VT_VALMASK) == VT_CMP || |
| 1720 | (vtop->r & (VT_VALMASK & ~1)) == VT_JMP) | 1713 | (S->tccgen_vtop->r & (VT_VALMASK & ~1)) == VT_JMP) |
| 1721 | gv(RC_INT); | 1714 | gv(S, RC_INT); |
| 1722 | vswap(); | 1715 | vswap(S); |
| 1723 | c=intr(gv(RC_INT)); | 1716 | c=intr(S, gv(S, RC_INT)); |
| 1724 | vswap(); | 1717 | vswap(S); |
| 1725 | opc=0xE0000000|(opc<<20); | 1718 | opc=0xE0000000|(opc<<20); |
| 1726 | if((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { | 1719 | if((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { |
| 1727 | uint32_t x; | 1720 | uint32_t x; |
| 1728 | x=stuff_const(opc|0x2000000|(c<<16),vtop->c.i); | 1721 | x=stuff_const(opc|0x2000000|(c<<16),S->tccgen_vtop->c.i); |
| 1729 | if(x) { | 1722 | if(x) { |
| 1730 | if ((x & 0xfff00000) == 0xe3500000) // cmp rx,#c | 1723 | if ((x & 0xfff00000) == 0xe3500000) // cmp rx,#c |
| 1731 | o(x); | 1724 | o(S, x); |
| 1732 | else { | 1725 | else { |
| 1733 | r=intr(vtop[-1].r=get_reg_ex(RC_INT,regmask(vtop[-1].r))); | 1726 | r=intr(S, S->tccgen_vtop[-1].r=get_reg_ex(S, RC_INT,regmask(S, S->tccgen_vtop[-1].r))); |
| 1734 | o(x|(r<<12)); | 1727 | o(S, x|(r<<12)); |
| 1735 | } | 1728 | } |
| 1736 | goto done; | 1729 | goto done; |
| 1737 | } | 1730 | } |
| 1738 | } | 1731 | } |
| 1739 | fr=intr(gv(RC_INT)); | 1732 | fr=intr(S, gv(S, RC_INT)); |
| 1740 | #ifdef CONFIG_TCC_BCHECK | 1733 | #ifdef CONFIG_TCC_BCHECK |
| 1741 | if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) { | 1734 | if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) { |
| 1742 | vswap(); | 1735 | vswap(S); |
| 1743 | c=intr(gv(RC_INT)); | 1736 | c=intr(S, gv(S, RC_INT)); |
| 1744 | vswap(); | 1737 | vswap(S); |
| 1745 | } | 1738 | } |
| 1746 | #endif | 1739 | #endif |
| 1747 | if ((opc & 0xfff00000) == 0xe1500000) // cmp rx,ry | 1740 | if ((opc & 0xfff00000) == 0xe1500000) // cmp rx,ry |
| 1748 | o(opc|(c<<16)|fr); | 1741 | o(S, opc|(c<<16)|fr); |
| 1749 | else { | 1742 | else { |
| 1750 | r=intr(vtop[-1].r=get_reg_ex(RC_INT,two2mask(vtop->r,vtop[-1].r))); | 1743 | r=intr(S, S->tccgen_vtop[-1].r=get_reg_ex(S, RC_INT,two2mask(S, S->tccgen_vtop->r,S->tccgen_vtop[-1].r))); |
| 1751 | o(opc|(c<<16)|(r<<12)|fr); | 1744 | o(S, opc|(c<<16)|(r<<12)|fr); |
| 1752 | } | 1745 | } |
| 1753 | done: | 1746 | done: |
| 1754 | vtop--; | 1747 | S->tccgen_vtop--; |
| 1755 | if (op >= TOK_ULT && op <= TOK_GT) | 1748 | if (op >= TOK_ULT && op <= TOK_GT) |
| 1756 | vset_VT_CMP(op); | 1749 | vset_VT_CMP(S, op); |
| 1757 | break; | 1750 | break; |
| 1758 | case 2: | 1751 | case 2: |
| 1759 | opc=0xE1A00000|(opc<<5); | 1752 | opc=0xE1A00000|(opc<<5); |
| 1760 | if ((vtop->r & VT_VALMASK) == VT_CMP || | 1753 | if ((S->tccgen_vtop->r & VT_VALMASK) == VT_CMP || |
| 1761 | (vtop->r & (VT_VALMASK & ~1)) == VT_JMP) | 1754 | (S->tccgen_vtop->r & (VT_VALMASK & ~1)) == VT_JMP) |
| 1762 | gv(RC_INT); | 1755 | gv(S, RC_INT); |
| 1763 | vswap(); | 1756 | vswap(S); |
| 1764 | r=intr(gv(RC_INT)); | 1757 | r=intr(S, gv(S, RC_INT)); |
| 1765 | vswap(); | 1758 | vswap(S); |
| 1766 | if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { | 1759 | if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { |
| 1767 | fr=intr(vtop[-1].r=get_reg_ex(RC_INT,regmask(vtop[-1].r))); | 1760 | fr=intr(S, S->tccgen_vtop[-1].r=get_reg_ex(S, RC_INT,regmask(S, S->tccgen_vtop[-1].r))); |
| 1768 | c = vtop->c.i & 0x1f; | 1761 | c = S->tccgen_vtop->c.i & 0x1f; |
| 1769 | o(opc|r|(c<<7)|(fr<<12)); | 1762 | o(S, opc|r|(c<<7)|(fr<<12)); |
| 1770 | } else { | 1763 | } else { |
| 1771 | fr=intr(gv(RC_INT)); | 1764 | fr=intr(S, gv(S, RC_INT)); |
| 1772 | #ifdef CONFIG_TCC_BCHECK | 1765 | #ifdef CONFIG_TCC_BCHECK |
| 1773 | if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) { | 1766 | if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) { |
| 1774 | vswap(); | 1767 | vswap(S); |
| 1775 | r=intr(gv(RC_INT)); | 1768 | r=intr(S, gv(S, RC_INT)); |
| 1776 | vswap(); | 1769 | vswap(S); |
| 1777 | } | 1770 | } |
| 1778 | #endif | 1771 | #endif |
| 1779 | c=intr(vtop[-1].r=get_reg_ex(RC_INT,two2mask(vtop->r,vtop[-1].r))); | 1772 | c=intr(S, S->tccgen_vtop[-1].r=get_reg_ex(S, RC_INT,two2mask(S, S->tccgen_vtop->r,S->tccgen_vtop[-1].r))); |
| 1780 | o(opc|r|(c<<12)|(fr<<8)|0x10); | 1773 | o(S, opc|r|(c<<12)|(fr<<8)|0x10); |
| 1781 | } | 1774 | } |
| 1782 | vtop--; | 1775 | S->tccgen_vtop--; |
| 1783 | break; | 1776 | break; |
| 1784 | case 3: | 1777 | case 3: |
| 1785 | vpush_helper_func(func); | 1778 | vpush_helper_func(S, func); |
| 1786 | vrott(3); | 1779 | vrott(S, 3); |
| 1787 | gfunc_call(2); | 1780 | gfunc_call(S, 2); |
| 1788 | vpushi(0); | 1781 | vpushi(S, 0); |
| 1789 | vtop->r = retreg; | 1782 | S->tccgen_vtop->r = retreg; |
| 1790 | break; | 1783 | break; |
| 1791 | default: | 1784 | default: |
| 1792 | tcc_error("gen_opi %i unimplemented!",op); | 1785 | tcc_error(S, "gen_opi %i unimplemented!",op); |
| 1793 | } | 1786 | } |
| 1794 | } | 1787 | } |
| 1795 | 1788 | ||
| 1796 | #ifdef TCC_ARM_VFP | 1789 | #ifdef TCC_ARM_VFP |
| 1797 | static int is_zero(int i) | 1790 | static int is_zero(TCCState* S, int i) |
| 1798 | { | 1791 | { |
| 1799 | if((vtop[i].r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST) | 1792 | if((S->tccgen_vtop[i].r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST) |
| 1800 | return 0; | 1793 | return 0; |
| 1801 | if (vtop[i].type.t == VT_FLOAT) | 1794 | if (S->tccgen_vtop[i].type.t == VT_FLOAT) |
| 1802 | return (vtop[i].c.f == 0.f); | 1795 | return (S->tccgen_vtop[i].c.f == 0.f); |
| 1803 | else if (vtop[i].type.t == VT_DOUBLE) | 1796 | else if (S->tccgen_vtop[i].type.t == VT_DOUBLE) |
| 1804 | return (vtop[i].c.d == 0.0); | 1797 | return (S->tccgen_vtop[i].c.d == 0.0); |
| 1805 | return (vtop[i].c.ld == 0.l); | 1798 | return (S->tccgen_vtop[i].c.ld == 0.l); |
| 1806 | } | 1799 | } |
| 1807 | 1800 | ||
| 1808 | /* generate a floating point operation 'v = t1 op t2' instruction. The | 1801 | /* generate a floating point operation 'v = t1 op t2' instruction. The |
| 1809 | * two operands are guaranteed to have the same floating point type */ | 1802 | * two operands are guaranteed to have the same floating point type */ |
| 1810 | void gen_opf(int op) | 1803 | void gen_opf(TCCState* S, int op) |
| 1811 | { | 1804 | { |
| 1812 | uint32_t x; | 1805 | uint32_t x; |
| 1813 | int fneg=0,r; | 1806 | int fneg=0,r; |
| 1814 | x=0xEE000A00|T2CPR(vtop->type.t); | 1807 | x=0xEE000A00|T2CPR(S->tccgen_vtop->type.t); |
| 1815 | switch(op) { | 1808 | switch(op) { |
| 1816 | case '+': | 1809 | case '+': |
| 1817 | if(is_zero(-1)) | 1810 | if(is_zero(S, -1)) |
| 1818 | vswap(); | 1811 | vswap(S); |
| 1819 | if(is_zero(0)) { | 1812 | if(is_zero(S, 0)) { |
| 1820 | vtop--; | 1813 | S->tccgen_vtop--; |
| 1821 | return; | 1814 | return; |
| 1822 | } | 1815 | } |
| 1823 | x|=0x300000; | 1816 | x|=0x300000; |
| 1824 | break; | 1817 | break; |
| 1825 | case '-': | 1818 | case '-': |
| 1826 | x|=0x300040; | 1819 | x|=0x300040; |
| 1827 | if(is_zero(0)) { | 1820 | if(is_zero(S, 0)) { |
| 1828 | vtop--; | 1821 | S->tccgen_vtop--; |
| 1829 | return; | 1822 | return; |
| 1830 | } | 1823 | } |
| 1831 | if(is_zero(-1)) { | 1824 | if(is_zero(S, -1)) { |
| 1832 | x|=0x810000; /* fsubX -> fnegX */ | 1825 | x|=0x810000; /* fsubX -> fnegX */ |
| 1833 | vswap(); | 1826 | vswap(S); |
| 1834 | vtop--; | 1827 | S->tccgen_vtop--; |
| 1835 | fneg=1; | 1828 | fneg=1; |
| 1836 | } | 1829 | } |
| 1837 | break; | 1830 | break; |
| @@ -1843,11 +1836,11 @@ void gen_opf(int op) · 5 unmodified lines | |||
| 1843 | break; | 1836 | break; |
| 1844 | default: | 1837 | default: |
| 1845 | if(op < TOK_ULT || op > TOK_GT) { | 1838 | if(op < TOK_ULT || op > TOK_GT) { |
| 1846 | tcc_error("unknown fp op %x!",op); | 1839 | tcc_error(S, "unknown fp op %x!",op); |
| 1847 | return; | 1840 | return; |
| 1848 | } | 1841 | } |
| 1849 | if(is_zero(-1)) { | 1842 | if(is_zero(S, -1)) { |
| 1850 | vswap(); | 1843 | vswap(S); |
| 1851 | switch(op) { | 1844 | switch(op) { |
| 1852 | case TOK_LT: op=TOK_GT; break; | 1845 | case TOK_LT: op=TOK_GT; break; |
| 1853 | case TOK_GE: op=TOK_ULE; break; | 1846 | case TOK_GE: op=TOK_ULE; break; |
| @@ -1858,16 +1851,16 @@ void gen_opf(int op) · 4 unmodified lines | |||
| 1858 | x|=0xB40040; /* fcmpX */ | 1851 | x|=0xB40040; /* fcmpX */ |
| 1859 | if(op!=TOK_EQ && op!=TOK_NE) | 1852 | if(op!=TOK_EQ && op!=TOK_NE) |
| 1860 | x|=0x80; /* fcmpX -> fcmpeX */ | 1853 | x|=0x80; /* fcmpX -> fcmpeX */ |
| 1861 | if(is_zero(0)) { | 1854 | if(is_zero(S, 0)) { |
| 1862 | vtop--; | 1855 | S->tccgen_vtop--; |
| 1863 | o(x|0x10000|(vfpr(gv(RC_FLOAT))<<12)); /* fcmp(e)X -> fcmp(e)zX */ | 1856 | o(S, x|0x10000|(vfpr(S, gv(S, RC_FLOAT))<<12)); /* fcmp(e)X -> fcmp(e)zX */ |
| 1864 | } else { | 1857 | } else { |
| 1865 | gv2(RC_FLOAT,RC_FLOAT); | 1858 | gv2(S, RC_FLOAT,RC_FLOAT); |
| 1866 | x|=vfpr(vtop[0].r); | 1859 | x|=vfpr(S, S->tccgen_vtop[0].r); |
| 1867 | o(x|(vfpr(vtop[-1].r) << 12)); | 1860 | o(S, x|(vfpr(S, S->tccgen_vtop[-1].r) << 12)); |
| 1868 | vtop--; | 1861 | S->tccgen_vtop--; |
| 1869 | } | 1862 | } |
| 1870 | o(0xEEF1FA10); /* fmstat */ | 1863 | o(S, 0xEEF1FA10); /* fmstat */ |
| 1871 | 1864 | ||
| 1872 | switch(op) { | 1865 | switch(op) { |
| 1873 | case TOK_LE: op=TOK_ULE; break; | 1866 | case TOK_LE: op=TOK_ULE; break; |
| @@ -1875,46 +1868,46 @@ void gen_opf(int op) · 1 unmodified line | |||
| 1875 | case TOK_UGE: op=TOK_GE; break; | 1868 | case TOK_UGE: op=TOK_GE; break; |
| 1876 | case TOK_UGT: op=TOK_GT; break; | 1869 | case TOK_UGT: op=TOK_GT; break; |
| 1877 | } | 1870 | } |
| 1878 | vset_VT_CMP(op); | 1871 | vset_VT_CMP(S, op); |
| 1879 | return; | 1872 | return; |
| 1880 | } | 1873 | } |
| 1881 | r=gv(RC_FLOAT); | 1874 | r=gv(S, RC_FLOAT); |
| 1882 | x|=vfpr(r); | 1875 | x|=vfpr(S, r); |
| 1883 | r=regmask(r); | 1876 | r=regmask(S, r); |
| 1884 | if(!fneg) { | 1877 | if(!fneg) { |
| 1885 | int r2; | 1878 | int r2; |
| 1886 | vswap(); | 1879 | vswap(S); |
| 1887 | r2=gv(RC_FLOAT); | 1880 | r2=gv(S, RC_FLOAT); |
| 1888 | x|=vfpr(r2)<<16; | 1881 | x|=vfpr(S, r2)<<16; |
| 1889 | r|=regmask(r2); | 1882 | r|=regmask(S, r2); |
| 1890 | #ifdef CONFIG_TCC_BCHECK | 1883 | #ifdef CONFIG_TCC_BCHECK |
| 1891 | if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) { | 1884 | if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) { |
| 1892 | vswap(); | 1885 | vswap(S); |
| 1893 | r=gv(RC_FLOAT); | 1886 | r=gv(S, RC_FLOAT); |
| 1894 | vswap(); | 1887 | vswap(S); |
| 1895 | x=(x&~0xf)|vfpr(r); | 1888 | x=(x&~0xf)|vfpr(S, r); |
| 1896 | } | 1889 | } |
| 1897 | #endif | 1890 | #endif |
| 1898 | } | 1891 | } |
| 1899 | vtop->r=get_reg_ex(RC_FLOAT,r); | 1892 | S->tccgen_vtop->r=get_reg_ex(S, RC_FLOAT,r); |
| 1900 | if(!fneg) | 1893 | if(!fneg) |
| 1901 | vtop--; | 1894 | S->tccgen_vtop--; |
| 1902 | o(x|(vfpr(vtop->r)<<12)); | 1895 | o(S, x|(vfpr(S, S->tccgen_vtop->r)<<12)); |
| 1903 | } | 1896 | } |
| 1904 | 1897 | ||
| 1905 | #else | 1898 | #else |
| 1906 | static uint32_t is_fconst() | 1899 | static uint32_t is_fconst(TCCState* S) |
| 1907 | { | 1900 | { |
| 1908 | long double f; | 1901 | long double f; |
| 1909 | uint32_t r; | 1902 | uint32_t r; |
| 1910 | if((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST) | 1903 | if((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST) |
| 1911 | return 0; | 1904 | return 0; |
| 1912 | if (vtop->type.t == VT_FLOAT) | 1905 | if (S->tccgen_vtop->type.t == VT_FLOAT) |
| 1913 | f = vtop->c.f; | 1906 | f = S->tccgen_vtop->c.f; |
| 1914 | else if (vtop->type.t == VT_DOUBLE) | 1907 | else if (S->tccgen_vtop->type.t == VT_DOUBLE) |
| 1915 | f = vtop->c.d; | 1908 | f = S->tccgen_vtop->c.d; |
| 1916 | else | 1909 | else |
| 1917 | f = vtop->c.ld; | 1910 | f = S->tccgen_vtop->c.ld; |
| 1918 | if(!ieee_finite(f)) | 1911 | if(!ieee_finite(f)) |
| 1919 | return 0; | 1912 | return 0; |
| 1920 | r=0x8; | 1913 | r=0x8; |
| @@ -1943,45 +1936,45 @@ static uint32_t is_fconst() · 22 unmodified lines | |||
| 1943 | 1936 | ||
| 1944 | /* generate a floating point operation 'v = t1 op t2' instruction. The | 1937 | /* generate a floating point operation 'v = t1 op t2' instruction. The |
| 1945 | two operands are guaranteed to have the same floating point type */ | 1938 | two operands are guaranteed to have the same floating point type */ |
| 1946 | void gen_opf(int op) | 1939 | void gen_opf(TCCState* S, int op) |
| 1947 | { | 1940 | { |
| 1948 | uint32_t x, r, r2, c1, c2; | 1941 | uint32_t x, r, r2, c1, c2; |
| 1949 | //fputs("gen_opf\n",stderr); | 1942 | //fputs("gen_opf\n",stderr); |
| 1950 | vswap(); | 1943 | vswap(S); |
| 1951 | c1 = is_fconst(); | 1944 | c1 = is_fconst(S); |
| 1952 | vswap(); | 1945 | vswap(S); |
| 1953 | c2 = is_fconst(); | 1946 | c2 = is_fconst(S); |
| 1954 | x=0xEE000100; | 1947 | x=0xEE000100; |
| 1955 | #if LDOUBLE_SIZE == 8 | 1948 | #if LDOUBLE_SIZE == 8 |
| 1956 | if ((vtop->type.t & VT_BTYPE) != VT_FLOAT) | 1949 | if ((S->tccgen_vtop->type.t & VT_BTYPE) != VT_FLOAT) |
| 1957 | x|=0x80; | 1950 | x|=0x80; |
| 1958 | #else | 1951 | #else |
| 1959 | if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) | 1952 | if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_DOUBLE) |
| 1960 | x|=0x80; | 1953 | x|=0x80; |
| 1961 | else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) | 1954 | else if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LDOUBLE) |
| 1962 | x|=0x80000; | 1955 | x|=0x80000; |
| 1963 | #endif | 1956 | #endif |
| 1964 | switch(op) | 1957 | switch(op) |
| 1965 | { | 1958 | { |
| 1966 | case '+': | 1959 | case '+': |
| 1967 | if(!c2) { | 1960 | if(!c2) { |
| 1968 | vswap(); | 1961 | vswap(S); |
| 1969 | c2=c1; | 1962 | c2=c1; |
| 1970 | } | 1963 | } |
| 1971 | vswap(); | 1964 | vswap(S); |
| 1972 | r=fpr(gv(RC_FLOAT)); | 1965 | r=fpr(S, gv(S, RC_FLOAT)); |
| 1973 | vswap(); | 1966 | vswap(S); |
| 1974 | if(c2) { | 1967 | if(c2) { |
| 1975 | if(c2>0xf) | 1968 | if(c2>0xf) |
| 1976 | x|=0x200000; // suf | 1969 | x|=0x200000; // suf |
| 1977 | r2=c2&0xf; | 1970 | r2=c2&0xf; |
| 1978 | } else { | 1971 | } else { |
| 1979 | r2=fpr(gv(RC_FLOAT)); | 1972 | r2=fpr(S, gv(S, RC_FLOAT)); |
| 1980 | #ifdef CONFIG_TCC_BCHECK | 1973 | #ifdef CONFIG_TCC_BCHECK |
| 1981 | if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) { | 1974 | if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) { |
| 1982 | vswap(); | 1975 | vswap(S); |
| 1983 | r=fpr(gv(RC_FLOAT)); | 1976 | r=fpr(S, gv(S, RC_FLOAT)); |
| 1984 | vswap(); | 1977 | vswap(S); |
| 1985 | } | 1978 | } |
| 1986 | #endif | 1979 | #endif |
| 1987 | } | 1980 | } |
| @@ -1991,46 +1984,46 @@ void gen_opf(int op) · 3 unmodified lines | |||
| 1991 | if(c2<=0xf) | 1984 | if(c2<=0xf) |
| 1992 | x|=0x200000; // suf | 1985 | x|=0x200000; // suf |
| 1993 | r2=c2&0xf; | 1986 | r2=c2&0xf; |
| 1994 | vswap(); | 1987 | vswap(S); |
| 1995 | r=fpr(gv(RC_FLOAT)); | 1988 | r=fpr(S, gv(S, RC_FLOAT)); |
| 1996 | vswap(); | 1989 | vswap(S); |
| 1997 | } else if(c1 && c1<=0xf) { | 1990 | } else if(c1 && c1<=0xf) { |
| 1998 | x|=0x300000; // rsf | 1991 | x|=0x300000; // rsf |
| 1999 | r2=c1; | 1992 | r2=c1; |
| 2000 | r=fpr(gv(RC_FLOAT)); | 1993 | r=fpr(S, gv(S, RC_FLOAT)); |
| 2001 | vswap(); | 1994 | vswap(S); |
| 2002 | } else { | 1995 | } else { |
| 2003 | x|=0x200000; // suf | 1996 | x|=0x200000; // suf |
| 2004 | vswap(); | 1997 | vswap(S); |
| 2005 | r=fpr(gv(RC_FLOAT)); | 1998 | r=fpr(S, gv(S, RC_FLOAT)); |
| 2006 | vswap(); | 1999 | vswap(S); |
| 2007 | r2=fpr(gv(RC_FLOAT)); | 2000 | r2=fpr(S, gv(S, RC_FLOAT)); |
| 2008 | #ifdef CONFIG_TCC_BCHECK | 2001 | #ifdef CONFIG_TCC_BCHECK |
| 2009 | if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) { | 2002 | if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) { |
| 2010 | vswap(); | 2003 | vswap(S); |
| 2011 | r=fpr(gv(RC_FLOAT)); | 2004 | r=fpr(S, gv(S, RC_FLOAT)); |
| 2012 | vswap(); | 2005 | vswap(S); |
| 2013 | } | 2006 | } |
| 2014 | #endif | 2007 | #endif |
| 2015 | } | 2008 | } |
| 2016 | break; | 2009 | break; |
| 2017 | case '*': | 2010 | case '*': |
| 2018 | if(!c2 || c2>0xf) { | 2011 | if(!c2 || c2>0xf) { |
| 2019 | vswap(); | 2012 | vswap(S); |
| 2020 | c2=c1; | 2013 | c2=c1; |
| 2021 | } | 2014 | } |
| 2022 | vswap(); | 2015 | vswap(S); |
| 2023 | r=fpr(gv(RC_FLOAT)); | 2016 | r=fpr(S, gv(S, RC_FLOAT)); |
| 2024 | vswap(); | 2017 | vswap(S); |
| 2025 | if(c2 && c2<=0xf) | 2018 | if(c2 && c2<=0xf) |
| 2026 | r2=c2; | 2019 | r2=c2; |
| 2027 | else { | 2020 | else { |
| 2028 | r2=fpr(gv(RC_FLOAT)); | 2021 | r2=fpr(S, gv(S, RC_FLOAT)); |
| 2029 | #ifdef CONFIG_TCC_BCHECK | 2022 | #ifdef CONFIG_TCC_BCHECK |
| 2030 | if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) { | 2023 | if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) { |
| 2031 | vswap(); | 2024 | vswap(S); |
| 2032 | r=fpr(gv(RC_FLOAT)); | 2025 | r=fpr(S, gv(S, RC_FLOAT)); |
| 2033 | vswap(); | 2026 | vswap(S); |
| 2034 | } | 2027 | } |
| 2035 | #endif | 2028 | #endif |
| 2036 | } | 2029 | } |
| @@ -2040,25 +2033,25 @@ void gen_opf(int op) · 3 unmodified lines | |||
| 2040 | if(c2 && c2<=0xf) { | 2033 | if(c2 && c2<=0xf) { |
| 2041 | x|=0x400000; // dvf | 2034 | x|=0x400000; // dvf |
| 2042 | r2=c2; | 2035 | r2=c2; |
| 2043 | vswap(); | 2036 | vswap(S); |
| 2044 | r=fpr(gv(RC_FLOAT)); | 2037 | r=fpr(S, gv(S, RC_FLOAT)); |
| 2045 | vswap(); | 2038 | vswap(S); |
| 2046 | } else if(c1 && c1<=0xf) { | 2039 | } else if(c1 && c1<=0xf) { |
| 2047 | x|=0x500000; // rdf | 2040 | x|=0x500000; // rdf |
| 2048 | r2=c1; | 2041 | r2=c1; |
| 2049 | r=fpr(gv(RC_FLOAT)); | 2042 | r=fpr(S, gv(S, RC_FLOAT)); |
| 2050 | vswap(); | 2043 | vswap(S); |
| 2051 | } else { | 2044 | } else { |
| 2052 | x|=0x400000; // dvf | 2045 | x|=0x400000; // dvf |
| 2053 | vswap(); | 2046 | vswap(S); |
| 2054 | r=fpr(gv(RC_FLOAT)); | 2047 | r=fpr(S, gv(S, RC_FLOAT)); |
| 2055 | vswap(); | 2048 | vswap(S); |
| 2056 | r2=fpr(gv(RC_FLOAT)); | 2049 | r2=fpr(S, gv(S, RC_FLOAT)); |
| 2057 | #ifdef CONFIG_TCC_BCHECK | 2050 | #ifdef CONFIG_TCC_BCHECK |
| 2058 | if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) { | 2051 | if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) { |
| 2059 | vswap(); | 2052 | vswap(S); |
| 2060 | r=fpr(gv(RC_FLOAT)); | 2053 | r=fpr(S, gv(S, RC_FLOAT)); |
| 2061 | vswap(); | 2054 | vswap(S); |
| 2062 | } | 2055 | } |
| 2063 | #endif | 2056 | #endif |
| 2064 | } | 2057 | } |
| @@ -2073,7 +2066,7 @@ void gen_opf(int op) · 8 unmodified lines | |||
| 2073 | case TOK_UGE: | 2066 | case TOK_UGE: |
| 2074 | case TOK_ULE: | 2067 | case TOK_ULE: |
| 2075 | case TOK_UGT: | 2068 | case TOK_UGT: |
| 2076 | tcc_error("unsigned comparison on floats?"); | 2069 | tcc_error(S, "unsigned comparison on floats?"); |
| 2077 | break; | 2070 | break; |
| 2078 | case TOK_LT: | 2071 | case TOK_LT: |
| 2079 | op=TOK_Nset; | 2072 | op=TOK_Nset; |
| @@ -2088,7 +2081,7 @@ void gen_opf(int op) · 8 unmodified lines | |||
| 2088 | } | 2081 | } |
| 2089 | if(c1 && !c2) { | 2082 | if(c1 && !c2) { |
| 2090 | c2=c1; | 2083 | c2=c1; |
| 2091 | vswap(); | 2084 | vswap(S); |
| 2092 | switch(op) { | 2085 | switch(op) { |
| 2093 | case TOK_Nset: | 2086 | case TOK_Nset: |
| 2094 | op=TOK_GT; | 2087 | op=TOK_GT; |
| @@ -2104,86 +2097,86 @@ void gen_opf(int op) · 9 unmodified lines | |||
| 2104 | break; | 2097 | break; |
| 2105 | } | 2098 | } |
| 2106 | } | 2099 | } |
| 2107 | vswap(); | 2100 | vswap(S); |
| 2108 | r=fpr(gv(RC_FLOAT)); | 2101 | r=fpr(S, gv(S, RC_FLOAT)); |
| 2109 | vswap(); | 2102 | vswap(S); |
| 2110 | if(c2) { | 2103 | if(c2) { |
| 2111 | if(c2>0xf) | 2104 | if(c2>0xf) |
| 2112 | x|=0x200000; | 2105 | x|=0x200000; |
| 2113 | r2=c2&0xf; | 2106 | r2=c2&0xf; |
| 2114 | } else { | 2107 | } else { |
| 2115 | r2=fpr(gv(RC_FLOAT)); | 2108 | r2=fpr(S, gv(S, RC_FLOAT)); |
| 2116 | #ifdef CONFIG_TCC_BCHECK | 2109 | #ifdef CONFIG_TCC_BCHECK |
| 2117 | if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) { | 2110 | if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) { |
| 2118 | vswap(); | 2111 | vswap(S); |
| 2119 | r=fpr(gv(RC_FLOAT)); | 2112 | r=fpr(S, gv(S, RC_FLOAT)); |
| 2120 | vswap(); | 2113 | vswap(S); |
| 2121 | } | 2114 | } |
| 2122 | #endif | 2115 | #endif |
| 2123 | } | 2116 | } |
| 2124 | --vtop; | 2117 | --S->tccgen_vtop; |
| 2125 | vset_VT_CMP(op); | 2118 | vset_VT_CMP(S, op); |
| 2126 | ++vtop; | 2119 | ++S->tccgen_vtop; |
| 2127 | } else { | 2120 | } else { |
| 2128 | tcc_error("unknown fp op %x!",op); | 2121 | tcc_error(S, "unknown fp op %x!",op); |
| 2129 | return; | 2122 | return; |
| 2130 | } | 2123 | } |
| 2131 | } | 2124 | } |
| 2132 | if(vtop[-1].r == VT_CMP) | 2125 | if(S->tccgen_vtop[-1].r == VT_CMP) |
| 2133 | c1=15; | 2126 | c1=15; |
| 2134 | else { | 2127 | else { |
| 2135 | c1=vtop->r; | 2128 | c1=S->tccgen_vtop->r; |
| 2136 | if(r2&0x8) | 2129 | if(r2&0x8) |
| 2137 | c1=vtop[-1].r; | 2130 | c1=S->tccgen_vtop[-1].r; |
| 2138 | vtop[-1].r=get_reg_ex(RC_FLOAT,two2mask(vtop[-1].r,c1)); | 2131 | S->tccgen_vtop[-1].r=get_reg_ex(S, RC_FLOAT,two2mask(S, S->tccgen_vtop[-1].r,c1)); |
| 2139 | c1=fpr(vtop[-1].r); | 2132 | c1=fpr(S, S->tccgen_vtop[-1].r); |
| 2140 | } | 2133 | } |
| 2141 | vtop--; | 2134 | S->tccgen_vtop--; |
| 2142 | o(x|(r<<16)|(c1<<12)|r2); | 2135 | o(S, x|(r<<16)|(c1<<12)|r2); |
| 2143 | } | 2136 | } |
| 2144 | #endif | 2137 | #endif |
| 2145 | 2138 | ||
| 2146 | /* convert integers to fp 't' type. Must handle 'int', 'unsigned int' | 2139 | /* convert integers to fp 't' type. Must handle 'int', 'unsigned int' |
| 2147 | and 'long long' cases. */ | 2140 | and 'long long' cases. */ |
| 2148 | ST_FUNC void gen_cvt_itof(int t) | 2141 | ST_FUNC void gen_cvt_itof(TCCState* S, int t) |
| 2149 | { | 2142 | { |
| 2150 | uint32_t r, r2; | 2143 | uint32_t r, r2; |
| 2151 | int bt; | 2144 | int bt; |
| 2152 | bt=vtop->type.t & VT_BTYPE; | 2145 | bt=S->tccgen_vtop->type.t & VT_BTYPE; |
| 2153 | if(bt == VT_INT || bt == VT_SHORT || bt == VT_BYTE) { | 2146 | if(bt == VT_INT || bt == VT_SHORT || bt == VT_BYTE) { |
| 2154 | #ifndef TCC_ARM_VFP | 2147 | #ifndef TCC_ARM_VFP |
| 2155 | uint32_t dsize = 0; | 2148 | uint32_t dsize = 0; |
| 2156 | #endif | 2149 | #endif |
| 2157 | r=intr(gv(RC_INT)); | 2150 | r=intr(S, gv(S, RC_INT)); |
| 2158 | #ifdef TCC_ARM_VFP | 2151 | #ifdef TCC_ARM_VFP |
| 2159 | r2=vfpr(vtop->r=get_reg(RC_FLOAT)); | 2152 | r2=vfpr(S, S->tccgen_vtop->r=get_reg(S, RC_FLOAT)); |
| 2160 | o(0xEE000A10|(r<<12)|(r2<<16)); /* fmsr */ | 2153 | o(S, 0xEE000A10|(r<<12)|(r2<<16)); /* fmsr */ |
| 2161 | r2|=r2<<12; | 2154 | r2|=r2<<12; |
| 2162 | if(!(vtop->type.t & VT_UNSIGNED)) | 2155 | if(!(S->tccgen_vtop->type.t & VT_UNSIGNED)) |
| 2163 | r2|=0x80; /* fuitoX -> fsituX */ | 2156 | r2|=0x80; /* fuitoX -> fsituX */ |
| 2164 | o(0xEEB80A40|r2|T2CPR(t)); /* fYitoX*/ | 2157 | o(S, 0xEEB80A40|r2|T2CPR(t)); /* fYitoX*/ |
| 2165 | #else | 2158 | #else |
| 2166 | r2=fpr(vtop->r=get_reg(RC_FLOAT)); | 2159 | r2=fpr(S, S->tccgen_vtop->r=get_reg(S, RC_FLOAT)); |
| 2167 | if((t & VT_BTYPE) != VT_FLOAT) | 2160 | if((t & VT_BTYPE) != VT_FLOAT) |
| 2168 | dsize=0x80; /* flts -> fltd */ | 2161 | dsize=0x80; /* flts -> fltd */ |
| 2169 | o(0xEE000110|dsize|(r2<<16)|(r<<12)); /* flts */ | 2162 | o(S, 0xEE000110|dsize|(r2<<16)|(r<<12)); /* flts */ |
| 2170 | if((vtop->type.t & (VT_UNSIGNED|VT_BTYPE)) == (VT_UNSIGNED|VT_INT)) { | 2163 | if((S->tccgen_vtop->type.t & (VT_UNSIGNED|VT_BTYPE)) == (VT_UNSIGNED|VT_INT)) { |
| 2171 | uint32_t off = 0; | 2164 | uint32_t off = 0; |
| 2172 | o(0xE3500000|(r<<12)); /* cmp */ | 2165 | o(S, 0xE3500000|(r<<12)); /* cmp */ |
| 2173 | r=fpr(get_reg(RC_FLOAT)); | 2166 | r=fpr(S, get_reg(S, RC_FLOAT)); |
| 2174 | if(last_itod_magic) { | 2167 | if(last_itod_magic) { |
| 2175 | off=ind+8-last_itod_magic; | 2168 | off=S->tccgen_ind+8-last_itod_magic; |
| 2176 | off/=4; | 2169 | off/=4; |
| 2177 | if(off>255) | 2170 | if(off>255) |
| 2178 | off=0; | 2171 | off=0; |
| 2179 | } | 2172 | } |
| 2180 | o(0xBD1F0100|(r<<12)|off); /* ldflts */ | 2173 | o(S, 0xBD1F0100|(r<<12)|off); /* ldflts */ |
| 2181 | if(!off) { | 2174 | if(!off) { |
| 2182 | o(0xEA000000); /* b */ | 2175 | o(S, 0xEA000000); /* b */ |
| 2183 | last_itod_magic=ind; | 2176 | last_itod_magic=S->tccgen_ind; |
| 2184 | o(0x4F800000); /* 4294967296.0f */ | 2177 | o(S, 0x4F800000); /* 4294967296.0f */ |
| 2185 | } | 2178 | } |
| 2186 | o(0xBE000100|dsize|(r2<<16)|(r2<<12)|r); /* adflt */ | 2179 | o(S, 0xBE000100|dsize|(r2<<16)|(r2<<12)|r); /* adflt */ |
| 2187 | } | 2180 | } |
| 2188 | #endif | 2181 | #endif |
| 2189 | return; | 2182 | return; |
| @@ -2191,15 +2184,15 @@ ST_FUNC void gen_cvt_itof(int t) · 1 unmodified line | |||
| 2191 | int func; | 2184 | int func; |
| 2192 | CType *func_type = 0; | 2185 | CType *func_type = 0; |
| 2193 | if((t & VT_BTYPE) == VT_FLOAT) { | 2186 | if((t & VT_BTYPE) == VT_FLOAT) { |
| 2194 | func_type = &func_float_type; | 2187 | func_type = &S->armgen_func_float_type; |
| 2195 | if(vtop->type.t & VT_UNSIGNED) | 2188 | if(S->tccgen_vtop->type.t & VT_UNSIGNED) |
| 2196 | func=TOK___floatundisf; | 2189 | func=TOK___floatundisf; |
| 2197 | else | 2190 | else |
| 2198 | func=TOK___floatdisf; | 2191 | func=TOK___floatdisf; |
| 2199 | #if LDOUBLE_SIZE != 8 | 2192 | #if LDOUBLE_SIZE != 8 |
| 2200 | } else if((t & VT_BTYPE) == VT_LDOUBLE) { | 2193 | } else if((t & VT_BTYPE) == VT_LDOUBLE) { |
| 2201 | func_type = &func_ldouble_type; | 2194 | func_type = &S->armgen_func_ldouble_type; |
| 2202 | if(vtop->type.t & VT_UNSIGNED) | 2195 | if(S->tccgen_vtop->type.t & VT_UNSIGNED) |
| 2203 | func=TOK___floatundixf; | 2196 | func=TOK___floatundixf; |
| 2204 | else | 2197 | else |
| 2205 | func=TOK___floatdixf; | 2198 | func=TOK___floatdixf; |
| @@ -2207,39 +2200,39 @@ ST_FUNC void gen_cvt_itof(int t) · 1 unmodified line | |||
| 2207 | #else | 2200 | #else |
| 2208 | } else if((t & VT_BTYPE) == VT_DOUBLE || (t & VT_BTYPE) == VT_LDOUBLE) { | 2201 | } else if((t & VT_BTYPE) == VT_DOUBLE || (t & VT_BTYPE) == VT_LDOUBLE) { |
| 2209 | #endif | 2202 | #endif |
| 2210 | func_type = &func_double_type; | 2203 | func_type = &S->armgen_func_double_type; |
| 2211 | if(vtop->type.t & VT_UNSIGNED) | 2204 | if(S->tccgen_vtop->type.t & VT_UNSIGNED) |
| 2212 | func=TOK___floatundidf; | 2205 | func=TOK___floatundidf; |
| 2213 | else | 2206 | else |
| 2214 | func=TOK___floatdidf; | 2207 | func=TOK___floatdidf; |
| 2215 | } | 2208 | } |
| 2216 | if(func_type) { | 2209 | if(func_type) { |
| 2217 | vpushsym(func_type, external_helper_sym(func)); | 2210 | vpushsym(S, func_type, external_helper_sym(S, func)); |
| 2218 | vswap(); | 2211 | vswap(S); |
| 2219 | gfunc_call(1); | 2212 | gfunc_call(S, 1); |
| 2220 | vpushi(0); | 2213 | vpushi(S, 0); |
| 2221 | vtop->r=TREG_F0; | 2214 | S->tccgen_vtop->r=TREG_F0; |
| 2222 | return; | 2215 | return; |
| 2223 | } | 2216 | } |
| 2224 | } | 2217 | } |
| 2225 | tcc_error("unimplemented gen_cvt_itof %x!",vtop->type.t); | 2218 | tcc_error(S, "unimplemented gen_cvt_itof %x!",S->tccgen_vtop->type.t); |
| 2226 | } | 2219 | } |
| 2227 | 2220 | ||
| 2228 | /* convert fp to int 't' type */ | 2221 | /* convert fp to int 't' type */ |
| 2229 | void gen_cvt_ftoi(int t) | 2222 | void gen_cvt_ftoi(TCCState* S, int t) |
| 2230 | { | 2223 | { |
| 2231 | uint32_t r, r2; | 2224 | uint32_t r, r2; |
| 2232 | int u, func = 0; | 2225 | int u, func = 0; |
| 2233 | u=t&VT_UNSIGNED; | 2226 | u=t&VT_UNSIGNED; |
| 2234 | t&=VT_BTYPE; | 2227 | t&=VT_BTYPE; |
| 2235 | r2=vtop->type.t & VT_BTYPE; | 2228 | r2=S->tccgen_vtop->type.t & VT_BTYPE; |
| 2236 | if(t==VT_INT) { | 2229 | if(t==VT_INT) { |
| 2237 | #ifdef TCC_ARM_VFP | 2230 | #ifdef TCC_ARM_VFP |
| 2238 | r=vfpr(gv(RC_FLOAT)); | 2231 | r=vfpr(S, gv(S, RC_FLOAT)); |
| 2239 | u=u?0:0x10000; | 2232 | u=u?0:0x10000; |
| 2240 | o(0xEEBC0AC0|(r<<12)|r|T2CPR(r2)|u); /* ftoXizY */ | 2233 | o(S, 0xEEBC0AC0|(r<<12)|r|T2CPR(r2)|u); /* ftoXizY */ |
| 2241 | r2=intr(vtop->r=get_reg(RC_INT)); | 2234 | r2=intr(S, S->tccgen_vtop->r=get_reg(S, RC_INT)); |
| 2242 | o(0xEE100A10|(r<<16)|(r2<<12)); | 2235 | o(S, 0xEE100A10|(r<<16)|(r2<<12)); |
| 2243 | return; | 2236 | return; |
| 2244 | #else | 2237 | #else |
| 2245 | if(u) { | 2238 | if(u) { |
| @@ -2254,9 +2247,9 @@ void gen_cvt_ftoi(int t) · 8 unmodified lines | |||
| 2254 | #endif | 2247 | #endif |
| 2255 | func=TOK___fixunsdfsi; | 2248 | func=TOK___fixunsdfsi; |
| 2256 | } else { | 2249 | } else { |
| 2257 | r=fpr(gv(RC_FLOAT)); | 2250 | r=fpr(S, gv(S, RC_FLOAT)); |
| 2258 | r2=intr(vtop->r=get_reg(RC_INT)); | 2251 | r2=intr(S, S->tccgen_vtop->r=get_reg(S, RC_INT)); |
| 2259 | o(0xEE100170|(r2<<12)|r); | 2252 | o(S, 0xEE100170|(r2<<12)|r); |
| 2260 | return; | 2253 | return; |
| 2261 | } | 2254 | } |
| 2262 | #endif | 2255 | #endif |
| @@ -2273,93 +2266,93 @@ void gen_cvt_ftoi(int t) · 10 unmodified lines | |||
| 2273 | func=TOK___fixdfdi; | 2266 | func=TOK___fixdfdi; |
| 2274 | } | 2267 | } |
| 2275 | if(func) { | 2268 | if(func) { |
| 2276 | vpush_helper_func(func); | 2269 | vpush_helper_func(S, func); |
| 2277 | vswap(); | 2270 | vswap(S); |
| 2278 | gfunc_call(1); | 2271 | gfunc_call(S, 1); |
| 2279 | vpushi(0); | 2272 | vpushi(S, 0); |
| 2280 | if(t == VT_LLONG) | 2273 | if(t == VT_LLONG) |
| 2281 | vtop->r2 = REG_IRE2; | 2274 | S->tccgen_vtop->r2 = REG_IRE2; |
| 2282 | vtop->r = REG_IRET; | 2275 | S->tccgen_vtop->r = REG_IRET; |
| 2283 | return; | 2276 | return; |
| 2284 | } | 2277 | } |
| 2285 | tcc_error("unimplemented gen_cvt_ftoi!"); | 2278 | tcc_error(S, "unimplemented gen_cvt_ftoi!"); |
| 2286 | } | 2279 | } |
| 2287 | 2280 | ||
| 2288 | /* convert from one floating point type to another */ | 2281 | /* convert from one floating point type to another */ |
| 2289 | void gen_cvt_ftof(int t) | 2282 | void gen_cvt_ftof(TCCState* S, int t) |
| 2290 | { | 2283 | { |
| 2291 | #ifdef TCC_ARM_VFP | 2284 | #ifdef TCC_ARM_VFP |
| 2292 | if(((vtop->type.t & VT_BTYPE) == VT_FLOAT) != ((t & VT_BTYPE) == VT_FLOAT)) { | 2285 | if(((S->tccgen_vtop->type.t & VT_BTYPE) == VT_FLOAT) != ((t & VT_BTYPE) == VT_FLOAT)) { |
| 2293 | uint32_t r = vfpr(gv(RC_FLOAT)); | 2286 | uint32_t r = vfpr(S, gv(S, RC_FLOAT)); |
| 2294 | o(0xEEB70AC0|(r<<12)|r|T2CPR(vtop->type.t)); | 2287 | o(S, 0xEEB70AC0|(r<<12)|r|T2CPR(S->tccgen_vtop->type.t)); |
| 2295 | } | 2288 | } |
| 2296 | #else | 2289 | #else |
| 2297 | /* all we have to do on i386 and FPA ARM is to put the float in a register */ | 2290 | /* all we have to do on i386 and FPA ARM is to put the float in a register */ |
| 2298 | gv(RC_FLOAT); | 2291 | gv(S, RC_FLOAT); |
| 2299 | #endif | 2292 | #endif |
| 2300 | } | 2293 | } |
| 2301 | 2294 | ||
| 2302 | /* increment tcov counter */ | 2295 | /* increment tcov counter */ |
| 2303 | ST_FUNC void gen_increment_tcov (SValue *sv) | 2296 | ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv) |
| 2304 | { | 2297 | { |
| 2305 | int r1, r2; | 2298 | int r1, r2; |
| 2306 | 2299 | ||
| 2307 | vpushv(sv); | 2300 | vpushv(S, sv); |
| 2308 | vtop->r = r1 = get_reg(RC_INT); | 2301 | S->tccgen_vtop->r = r1 = get_reg(S, RC_INT); |
| 2309 | r2 = get_reg(RC_INT); | 2302 | r2 = get_reg(S, RC_INT); |
| 2310 | o(0xE59F0000 | (intr(r1)<<12)); // ldr r1,[pc] | 2303 | o(S, 0xE59F0000 | (intr(S, r1)<<12)); // ldr r1,[pc] |
| 2311 | o(0xEA000000); // b $+4 | 2304 | o(S, 0xEA000000); // b $+4 |
| 2312 | greloc(cur_text_section, sv->sym, ind, R_ARM_REL32); | 2305 | greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_ARM_REL32); |
| 2313 | o(-12); | 2306 | o(S, -12); |
| 2314 | o(0xe080000f | (intr(r1)<<16) | (intr(r1)<<12)); // add r1,r1,pc | 2307 | o(S, 0xe080000f | (intr(S, r1)<<16) | (intr(S, r1)<<12)); // add r1,r1,pc |
| 2315 | o(0xe5900000 | (intr(r1)<<16) | (intr(r2)<<12)); // ldr r2, [r1] | 2308 | o(S, 0xe5900000 | (intr(S, r1)<<16) | (intr(S, r2)<<12)); // ldr r2, [r1] |
| 2316 | o(0xe2900001 | (intr(r2)<<16) | (intr(r2)<<12)); // adds r2, r2, #1 | 2309 | o(S, 0xe2900001 | (intr(S, r2)<<16) | (intr(S, r2)<<12)); // adds r2, r2, #1 |
| 2317 | o(0xe5800000 | (intr(r1)<<16) | (intr(r2)<<12)); // str r2, [r1] | 2310 | o(S, 0xe5800000 | (intr(S, r1)<<16) | (intr(S, r2)<<12)); // str r2, [r1] |
| 2318 | o(0xe2800004 | (intr(r1)<<16) | (intr(r1)<<12)); // add r1, r1, #4 | 2311 | o(S, 0xe2800004 | (intr(S, r1)<<16) | (intr(S, r1)<<12)); // add r1, r1, #4 |
| 2319 | o(0xe5900000 | (intr(r1)<<16) | (intr(r2)<<12)); // ldr r2, [r1] | 2312 | o(S, 0xe5900000 | (intr(S, r1)<<16) | (intr(S, r2)<<12)); // ldr r2, [r1] |
| 2320 | o(0xe2a00000 | (intr(r2)<<16) | (intr(r2)<<12)); // adc r2, r2, #0 | 2313 | o(S, 0xe2a00000 | (intr(S, r2)<<16) | (intr(S, r2)<<12)); // adc r2, r2, #0 |
| 2321 | o(0xe5800000 | (intr(r1)<<16) | (intr(r2)<<12)); // str r2, [r1] | 2314 | o(S, 0xe5800000 | (intr(S, r1)<<16) | (intr(S, r2)<<12)); // str r2, [r1] |
| 2322 | vpop(); | 2315 | vpop(S); |
| 2323 | } | 2316 | } |
| 2324 | 2317 | ||
| 2325 | /* computed goto support */ | 2318 | /* computed goto support */ |
| 2326 | void ggoto(void) | 2319 | void ggoto(TCCState* S) |
| 2327 | { | 2320 | { |
| 2328 | gcall_or_jmp(1); | 2321 | gcall_or_jmp(S, 1); |
| 2329 | vtop--; | 2322 | S->tccgen_vtop--; |
| 2330 | } | 2323 | } |
| 2331 | 2324 | ||
| 2332 | /* Save the stack pointer onto the stack and return the location of its address */ | 2325 | /* Save the stack pointer onto the stack and return the location of its address */ |
| 2333 | ST_FUNC void gen_vla_sp_save(int addr) { | 2326 | ST_FUNC void gen_vla_sp_save(TCCState* S, int addr) { |
| 2334 | SValue v; | 2327 | SValue v; |
| 2335 | v.type.t = VT_PTR; | 2328 | v.type.t = VT_PTR; |
| 2336 | v.r = VT_LOCAL | VT_LVAL; | 2329 | v.r = VT_LOCAL | VT_LVAL; |
| 2337 | v.c.i = addr; | 2330 | v.c.i = addr; |
| 2338 | store(TREG_SP, &v); | 2331 | store(S, TREG_SP, &v); |
| 2339 | } | 2332 | } |
| 2340 | 2333 | ||
| 2341 | /* Restore the SP from a location on the stack */ | 2334 | /* Restore the SP from a location on the stack */ |
| 2342 | ST_FUNC void gen_vla_sp_restore(int addr) { | 2335 | ST_FUNC void gen_vla_sp_restore(TCCState* S, int addr) { |
| 2343 | SValue v; | 2336 | SValue v; |
| 2344 | v.type.t = VT_PTR; | 2337 | v.type.t = VT_PTR; |
| 2345 | v.r = VT_LOCAL | VT_LVAL; | 2338 | v.r = VT_LOCAL | VT_LVAL; |
| 2346 | v.c.i = addr; | 2339 | v.c.i = addr; |
| 2347 | load(TREG_SP, &v); | 2340 | load(S, TREG_SP, &v); |
| 2348 | } | 2341 | } |
| 2349 | 2342 | ||
| 2350 | /* Subtract from the stack pointer, and push the resulting value onto the stack */ | 2343 | /* Subtract from the stack pointer, and push the resulting value onto the stack */ |
| 2351 | ST_FUNC void gen_vla_alloc(CType *type, int align) { | 2344 | ST_FUNC void gen_vla_alloc(TCCState* S, CType *type, int align) { |
| 2352 | int r; | 2345 | int r; |
| 2353 | #if defined(CONFIG_TCC_BCHECK) | 2346 | #if defined(CONFIG_TCC_BCHECK) |
| 2354 | if (tcc_state->do_bounds_check) | 2347 | if (S->do_bounds_check) |
| 2355 | vpushv(vtop); | 2348 | vpushv(S, S->tccgen_vtop); |
| 2356 | #endif | 2349 | #endif |
| 2357 | r = intr(gv(RC_INT)); | 2350 | r = intr(S, gv(S, RC_INT)); |
| 2358 | #if defined(CONFIG_TCC_BCHECK) | 2351 | #if defined(CONFIG_TCC_BCHECK) |
| 2359 | if (tcc_state->do_bounds_check) | 2352 | if (S->do_bounds_check) |
| 2360 | o(0xe2800001 | (r<<16)|(r<<12)); /* add r,r,#1 */ | 2353 | o(S, 0xe2800001 | (r<<16)|(r<<12)); /* add r,r,#1 */ |
| 2361 | #endif | 2354 | #endif |
| 2362 | o(0xE04D0000|(r<<12)|r); /* sub r, sp, r */ | 2355 | o(S, 0xE04D0000|(r<<12)|r); /* sub r, sp, r */ |
| 2363 | #ifdef TCC_ARM_EABI | 2356 | #ifdef TCC_ARM_EABI |
| 2364 | if (align < 8) | 2357 | if (align < 8) |
| 2365 | align = 8; | 2358 | align = 8; |
| @@ -2368,19 +2361,19 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) { · 2 unmodified lines | |||
| 2368 | align = 4; | 2361 | align = 4; |
| 2369 | #endif | 2362 | #endif |
| 2370 | if (align & (align - 1)) | 2363 | if (align & (align - 1)) |
| 2371 | tcc_error("alignment is not a power of 2: %i", align); | 2364 | tcc_error(S, "alignment is not a power of 2: %i", align); |
| 2372 | o(stuff_const(0xE3C0D000|(r<<16), align - 1)); /* bic sp, r, #align-1 */ | 2365 | o(S, stuff_const(0xE3C0D000|(r<<16), align - 1)); /* bic sp, r, #align-1 */ |
| 2373 | vpop(); | 2366 | vpop(S); |
| 2374 | #if defined(CONFIG_TCC_BCHECK) | 2367 | #if defined(CONFIG_TCC_BCHECK) |
| 2375 | if (tcc_state->do_bounds_check) { | 2368 | if (S->do_bounds_check) { |
| 2376 | vpushi(0); | 2369 | vpushi(S, 0); |
| 2377 | vtop->r = TREG_R0; | 2370 | S->tccgen_vtop->r = TREG_R0; |
| 2378 | o(0xe1a0000d | (vtop->r << 12)); // mov r0,sp | 2371 | o(S, 0xe1a0000d | (S->tccgen_vtop->r << 12)); // mov r0,sp |
| 2379 | vswap(); | 2372 | vswap(S); |
| 2380 | vpush_helper_func(TOK___bound_new_region); | 2373 | vpush_helper_func(S, TOK___bound_new_region); |
| 2381 | vrott(3); | 2374 | vrott(S, 3); |
| 2382 | gfunc_call(2); | 2375 | gfunc_call(S, 2); |
| 2383 | func_bound_add_epilog = 1; | 2376 | S->func_bound_add_epilog = 1; |
| 2384 | } | 2377 | } |
| 2385 | #endif | 2378 | #endif |
| 2386 | } | 2379 | } |
| @@ -107,9 +107,9 @@ int gotplt_entry_type (int reloc_type) · 106 unmodified lines | |||
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | #ifndef TCC_TARGET_PE | 109 | #ifndef TCC_TARGET_PE |
| 110 | ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr) | 110 | ST_FUNC unsigned create_plt_entry(TCCState *S, unsigned got_offset, struct sym_attr *attr) |
| 111 | { | 111 | { |
| 112 | Section *plt = s1->plt; | 112 | Section *plt = S->plt; |
| 113 | uint8_t *p; | 113 | uint8_t *p; |
| 114 | unsigned plt_offset; | 114 | unsigned plt_offset; |
| 115 | 115 | ||
| @@ -119,7 +119,7 @@ ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_ · 3 unmodified lines | |||
| 119 | /* empty PLT: create PLT0 entry that push address of call site and | 119 | /* empty PLT: create PLT0 entry that push address of call site and |
| 120 | jump to ld.so resolution routine (GOT + 8) */ | 120 | jump to ld.so resolution routine (GOT + 8) */ |
| 121 | if (plt->data_offset == 0) { | 121 | if (plt->data_offset == 0) { |
| 122 | p = section_ptr_add(plt, 20); | 122 | p = section_ptr_add(S, plt, 20); |
| 123 | write32le(p, 0xe52de004); /* push {lr} */ | 123 | write32le(p, 0xe52de004); /* push {lr} */ |
| 124 | write32le(p+4, 0xe59fe004); /* ldr lr, [pc, #4] */ | 124 | write32le(p+4, 0xe59fe004); /* ldr lr, [pc, #4] */ |
| 125 | write32le(p+8, 0xe08fe00e); /* add lr, pc, lr */ | 125 | write32le(p+8, 0xe08fe00e); /* add lr, pc, lr */ |
| @@ -129,11 +129,11 @@ ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_ · 3 unmodified lines | |||
| 129 | plt_offset = plt->data_offset; | 129 | plt_offset = plt->data_offset; |
| 130 | 130 | ||
| 131 | if (attr->plt_thumb_stub) { | 131 | if (attr->plt_thumb_stub) { |
| 132 | p = section_ptr_add(plt, 4); | 132 | p = section_ptr_add(S, plt, 4); |
| 133 | write32le(p, 0x4778); /* bx pc */ | 133 | write32le(p, 0x4778); /* bx pc */ |
| 134 | write32le(p+2, 0x46c0); /* nop */ | 134 | write32le(p+2, 0x46c0); /* nop */ |
| 135 | } | 135 | } |
| 136 | p = section_ptr_add(plt, 16); | 136 | p = section_ptr_add(S, plt, 16); |
| 137 | /* save GOT offset for relocate_plt */ | 137 | /* save GOT offset for relocate_plt */ |
| 138 | write32le(p + 4, got_offset); | 138 | write32le(p + 4, got_offset); |
| 139 | return plt_offset; | 139 | return plt_offset; |
| @@ -141,22 +141,22 @@ ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_ · 1 unmodified line | |||
| 141 | 141 | ||
| 142 | /* relocate the PLT: compute addresses and offsets in the PLT now that final | 142 | /* relocate the PLT: compute addresses and offsets in the PLT now that final |
| 143 | address for PLT and GOT are known (see fill_program_header) */ | 143 | address for PLT and GOT are known (see fill_program_header) */ |
| 144 | ST_FUNC void relocate_plt(TCCState *s1) | 144 | ST_FUNC void relocate_plt(TCCState *S) |
| 145 | { | 145 | { |
| 146 | uint8_t *p, *p_end; | 146 | uint8_t *p, *p_end; |
| 147 | 147 | ||
| 148 | if (!s1->plt) | 148 | if (!S->plt) |
| 149 | return; | 149 | return; |
| 150 | 150 | ||
| 151 | p = s1->plt->data; | 151 | p = S->plt->data; |
| 152 | p_end = p + s1->plt->data_offset; | 152 | p_end = p + S->plt->data_offset; |
| 153 | 153 | ||
| 154 | if (p < p_end) { | 154 | if (p < p_end) { |
| 155 | int x = s1->got->sh_addr - s1->plt->sh_addr - 12; | 155 | int x = S->got->sh_addr - S->plt->sh_addr - 12; |
| 156 | write32le(s1->plt->data + 16, x - 4); | 156 | write32le(S->plt->data + 16, x - 4); |
| 157 | p += 20; | 157 | p += 20; |
| 158 | while (p < p_end) { | 158 | while (p < p_end) { |
| 159 | unsigned off = x + read32le(p + 4) + (s1->plt->data - p) + 4; | 159 | unsigned off = x + read32le(p + 4) + (S->plt->data - p) + 4; |
| 160 | if (read32le(p) == 0x46c04778) /* PLT Thumb stub present */ | 160 | if (read32le(p) == 0x46c04778) /* PLT Thumb stub present */ |
| 161 | p += 4; | 161 | p += 4; |
| 162 | write32le(p, 0xe28fc200 | ((off >> 28) & 0xf)); // add ip, pc, #0xN0000000 | 162 | write32le(p, 0xe28fc200 | ((off >> 28) & 0xf)); // add ip, pc, #0xN0000000 |
| @@ -167,17 +167,17 @@ ST_FUNC void relocate_plt(TCCState *s1) · 4 unmodified lines | |||
| 167 | } | 167 | } |
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | if (s1->plt->reloc) { | 170 | if (S->plt->reloc) { |
| 171 | ElfW_Rel *rel; | 171 | ElfW_Rel *rel; |
| 172 | p = s1->got->data; | 172 | p = S->got->data; |
| 173 | for_each_elem(s1->plt->reloc, 0, rel, ElfW_Rel) { | 173 | for_each_elem(S->plt->reloc, 0, rel, ElfW_Rel) { |
| 174 | write32le(p + rel->r_offset, s1->plt->sh_addr); | 174 | write32le(p + rel->r_offset, S->plt->sh_addr); |
| 175 | } | 175 | } |
| 176 | } | 176 | } |
| 177 | } | 177 | } |
| 178 | #endif | 178 | #endif |
| 179 | 179 | ||
| 180 | void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val) | 180 | void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val) |
| 181 | { | 181 | { |
| 182 | ElfW(Sym) *sym; | 182 | ElfW(Sym) *sym; |
| 183 | int sym_index, esym_index; | 183 | int sym_index, esym_index; |
| @@ -212,7 +212,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 28 unmodified lines | |||
| 212 | h = x & 2; | 212 | h = x & 2; |
| 213 | th_ko = (x & 3) && (!blx_avail || !is_call); | 213 | th_ko = (x & 3) && (!blx_avail || !is_call); |
| 214 | if (th_ko || x >= 0x2000000 || x < -0x2000000) | 214 | if (th_ko || x >= 0x2000000 || x < -0x2000000) |
| 215 | tcc_error("can't relocate value at %x,%d",addr, type); | 215 | tcc_error(S, "can't relocate value at %x,%d",addr, type); |
| 216 | x >>= 2; | 216 | x >>= 2; |
| 217 | x &= 0xffffff; | 217 | x &= 0xffffff; |
| 218 | /* Only reached if blx is avail and it is a call */ | 218 | /* Only reached if blx is avail and it is a call */ |
| @@ -255,7 +255,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 36 unmodified lines | |||
| 255 | 255 | ||
| 256 | /* Relocation infos */ | 256 | /* Relocation infos */ |
| 257 | to_thumb = val & 1; | 257 | to_thumb = val & 1; |
| 258 | plt = s1->plt; | 258 | plt = S->plt; |
| 259 | to_plt = (val >= plt->sh_addr) && | 259 | to_plt = (val >= plt->sh_addr) && |
| 260 | (val < plt->sh_addr + plt->data_offset); | 260 | (val < plt->sh_addr + plt->data_offset); |
| 261 | is_call = (type == R_ARM_THM_PC22); | 261 | is_call = (type == R_ARM_THM_PC22); |
| @@ -267,10 +267,10 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 5 unmodified lines | |||
| 267 | Section *text; | 267 | Section *text; |
| 268 | 268 | ||
| 269 | name = (char *) symtab_section->link->data + sym->st_name; | 269 | name = (char *) symtab_section->link->data + sym->st_name; |
| 270 | text = s1->sections[sym->st_shndx]; | 270 | text = S->sections[sym->st_shndx]; |
| 271 | /* Modify reloc to target a thumb stub to switch to ARM */ | 271 | /* Modify reloc to target a thumb stub to switch to ARM */ |
| 272 | snprintf(buf, sizeof(buf), "%s_from_thumb", name); | 272 | snprintf(buf, sizeof(buf), "%s_from_thumb", name); |
| 273 | index = put_elf_sym(symtab_section, | 273 | index = put_elf_sym(S, symtab_section, |
| 274 | text->data_offset + 1, | 274 | text->data_offset + 1, |
| 275 | sym->st_size, sym->st_info, 0, | 275 | sym->st_size, sym->st_info, 0, |
| 276 | sym->st_shndx, buf); | 276 | sym->st_shndx, buf); |
| @@ -281,7 +281,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 4 unmodified lines | |||
| 281 | put_elf_reloc(symtab_section, text, | 281 | put_elf_reloc(symtab_section, text, |
| 282 | text->data_offset + 4, R_ARM_JUMP24, | 282 | text->data_offset + 4, R_ARM_JUMP24, |
| 283 | sym_index); | 283 | sym_index); |
| 284 | p = section_ptr_add(text, 8); | 284 | p = section_ptr_add(S, text, 8); |
| 285 | write32le(p, 0x4778); /* bx pc */ | 285 | write32le(p, 0x4778); /* bx pc */ |
| 286 | write32le(p+2, 0x46c0); /* nop */ | 286 | write32le(p+2, 0x46c0); /* nop */ |
| 287 | write32le(p+4, 0xeafffffe); /* b $sym */ | 287 | write32le(p+4, 0xeafffffe); /* b $sym */ |
| @@ -301,7 +301,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 13 unmodified lines | |||
| 301 | - instruction must be a call (bl) or a jump to PLT */ | 301 | - instruction must be a call (bl) or a jump to PLT */ |
| 302 | if (!to_thumb || x >= 0x1000000 || x < -0x1000000) | 302 | if (!to_thumb || x >= 0x1000000 || x < -0x1000000) |
| 303 | if (to_thumb || (val & 2) || (!is_call && !to_plt)) | 303 | if (to_thumb || (val & 2) || (!is_call && !to_plt)) |
| 304 | tcc_error("can't relocate value at %x,%d",addr, type); | 304 | tcc_error(S, "can't relocate value at %x,%d",addr, type); |
| 305 | 305 | ||
| 306 | /* Compute and store final offset */ | 306 | /* Compute and store final offset */ |
| 307 | s = (x >> 24) & 1; | 307 | s = (x >> 24) & 1; |
| @@ -372,14 +372,14 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 64 unmodified lines | |||
| 372 | x = (x * 2) / 2; | 372 | x = (x * 2) / 2; |
| 373 | x += val - addr; | 373 | x += val - addr; |
| 374 | if((x^(x>>1))&0x40000000) | 374 | if((x^(x>>1))&0x40000000) |
| 375 | tcc_error("can't relocate value at %x,%d",addr, type); | 375 | tcc_error(S, "can't relocate value at %x,%d",addr, type); |
| 376 | (*(int *)ptr) |= x & 0x7fffffff; | 376 | (*(int *)ptr) |= x & 0x7fffffff; |
| 377 | } | 377 | } |
| 378 | return; | 378 | return; |
| 379 | case R_ARM_ABS32: | 379 | case R_ARM_ABS32: |
| 380 | case R_ARM_TARGET1: | 380 | case R_ARM_TARGET1: |
| 381 | if (s1->output_type == TCC_OUTPUT_DLL) { | 381 | if (S->output_type == TCC_OUTPUT_DLL) { |
| 382 | esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index; | 382 | esym_index = get_sym_attr(S, sym_index, 0)->dyn_index; |
| 383 | qrel->r_offset = rel->r_offset; | 383 | qrel->r_offset = rel->r_offset; |
| 384 | if (esym_index) { | 384 | if (esym_index) { |
| 385 | qrel->r_info = ELFW(R_INFO)(esym_index, R_ARM_ABS32); | 385 | qrel->r_info = ELFW(R_INFO)(esym_index, R_ARM_ABS32); |
| @@ -396,19 +396,19 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 10 unmodified lines | |||
| 396 | *(int *)ptr += val - addr; | 396 | *(int *)ptr += val - addr; |
| 397 | return; | 397 | return; |
| 398 | case R_ARM_GOTPC: | 398 | case R_ARM_GOTPC: |
| 399 | *(int *)ptr += s1->got->sh_addr - addr; | 399 | *(int *)ptr += S->got->sh_addr - addr; |
| 400 | return; | 400 | return; |
| 401 | case R_ARM_GOTOFF: | 401 | case R_ARM_GOTOFF: |
| 402 | *(int *)ptr += val - s1->got->sh_addr; | 402 | *(int *)ptr += val - S->got->sh_addr; |
| 403 | return; | 403 | return; |
| 404 | case R_ARM_GOT32: | 404 | case R_ARM_GOT32: |
| 405 | /* we load the got offset */ | 405 | /* we load the got offset */ |
| 406 | *(int *)ptr += get_sym_attr(s1, sym_index, 0)->got_offset; | 406 | *(int *)ptr += get_sym_attr(S, sym_index, 0)->got_offset; |
| 407 | return; | 407 | return; |
| 408 | case R_ARM_GOT_PREL: | 408 | case R_ARM_GOT_PREL: |
| 409 | /* we load the pc relative got offset */ | 409 | /* we load the pc relative got offset */ |
| 410 | *(int *)ptr += s1->got->sh_addr + | 410 | *(int *)ptr += S->got->sh_addr + |
| 411 | get_sym_attr(s1, sym_index, 0)->got_offset - | 411 | get_sym_attr(S, sym_index, 0)->got_offset - |
| 412 | addr; | 412 | addr; |
| 413 | return; | 413 | return; |
| 414 | case R_ARM_COPY: | 414 | case R_ARM_COPY: |
| @@ -428,7 +428,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 13 unmodified lines | |||
| 428 | return; | 428 | return; |
| 429 | case R_ARM_RELATIVE: | 429 | case R_ARM_RELATIVE: |
| 430 | #ifdef TCC_TARGET_PE | 430 | #ifdef TCC_TARGET_PE |
| 431 | add32le(ptr, val - s1->pe_imagebase); | 431 | add32le(ptr, val - S->pe_imagebase); |
| 432 | #endif | 432 | #endif |
| 433 | /* do nothing */ | 433 | /* do nothing */ |
| 434 | return; | 434 | return; |
| @@ -9,9 +9,9 @@ · 8 unmodified lines | |||
| 9 | #define CONFIG_TCC_ASM | 9 | #define CONFIG_TCC_ASM |
| 10 | #define NB_ASM_REGS 16 | 10 | #define NB_ASM_REGS 16 |
| 11 | 11 | ||
| 12 | ST_FUNC void g(int c); | 12 | ST_FUNC void g(TCCState* S, int c); |
| 13 | ST_FUNC void gen_le16(int c); | 13 | ST_FUNC void gen_le16(TCCState* S, int c); |
| 14 | ST_FUNC void gen_le32(int c); | 14 | ST_FUNC void gen_le32(TCCState* S, int c); |
| 15 | 15 | ||
| 16 | /*************************************************************/ | 16 | /*************************************************************/ |
| 17 | #else | 17 | #else |
| @@ -25,7 +25,7 @@ static void asm_error(void) · 7 unmodified lines | |||
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | /* XXX: make it faster ? */ | 27 | /* XXX: make it faster ? */ |
| 28 | ST_FUNC void g(int c) | 28 | ST_FUNC void g(TCCState* S, int c) |
| 29 | { | 29 | { |
| 30 | int ind1; | 30 | int ind1; |
| 31 | if (nocode_wanted) | 31 | if (nocode_wanted) |
| @@ -37,24 +37,24 @@ ST_FUNC void g(int c) · 5 unmodified lines | |||
| 37 | ind = ind1; | 37 | ind = ind1; |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | ST_FUNC void gen_le16 (int i) | 40 | ST_FUNC void gen_le16 (TCCState* S, int i) |
| 41 | { | 41 | { |
| 42 | g(i); | 42 | g(S, i); |
| 43 | g(i>>8); | 43 | g(S, i>>8); |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | ST_FUNC void gen_le32 (int i) | 46 | ST_FUNC void gen_le32 (TCCState* S, int i) |
| 47 | { | 47 | { |
| 48 | gen_le16(i); | 48 | gen_le16(S, i); |
| 49 | gen_le16(i>>16); | 49 | gen_le16(S, i>>16); |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | ST_FUNC void gen_expr32(ExprValue *pe) | 52 | ST_FUNC void gen_expr32(TCCState* S, ExprValue *pe) |
| 53 | { | 53 | { |
| 54 | gen_le32(pe->v); | 54 | gen_le32(S, pe->v); |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | ST_FUNC void asm_opcode(TCCState *s1, int opcode) | 57 | ST_FUNC void asm_opcode(TCCState *S, int opcode) |
| 58 | { | 58 | { |
| 59 | asm_error(); | 59 | asm_error(); |
| 60 | } | 60 | } |
| @@ -90,15 +90,9 @@ ST_DATA const int reg_classes[NB_REGS] = { · 89 unmodified lines | |||
| 90 | RC_FLOAT | RC_F(7) | 90 | RC_FLOAT | RC_F(7) |
| 91 | }; | 91 | }; |
| 92 | 92 | ||
| 93 | #if defined(CONFIG_TCC_BCHECK) | ||
| 94 | static addr_t func_bound_offset; | ||
| 95 | static unsigned long func_bound_ind; | ||
| 96 | ST_DATA int func_bound_add_epilog; | ||
| 97 | #endif | ||
| 98 | |||
| 99 | #define IS_FREG(x) ((x) >= TREG_F(0)) | 93 | #define IS_FREG(x) ((x) >= TREG_F(0)) |
| 100 | 94 | ||
| 101 | static uint32_t intr(int r) | 95 | static uint32_t intr(TCCState *S, int r) |
| 102 | { | 96 | { |
| 103 | assert(TREG_R(0) <= r && r <= TREG_R30); | 97 | assert(TREG_R(0) <= r && r <= TREG_R30); |
| 104 | return r < TREG_R30 ? r : 30; | 98 | return r < TREG_R30 ? r : 30; |
| @@ -111,15 +105,15 @@ static uint32_t fltr(int r) · 6 unmodified lines | |||
| 111 | } | 105 | } |
| 112 | 106 | ||
| 113 | // Add an instruction to text section: | 107 | // Add an instruction to text section: |
| 114 | ST_FUNC void o(unsigned int c) | 108 | ST_FUNC void o(TCCState *S, unsigned int c) |
| 115 | { | 109 | { |
| 116 | int ind1 = ind + 4; | 110 | int ind1 = S->tccgen_ind + 4; |
| 117 | if (nocode_wanted) | 111 | if (S->tccgen_nocode_wanted) |
| 118 | return; | 112 | return; |
| 119 | if (ind1 > cur_text_section->data_allocated) | 113 | if (ind1 > cur_text_section->data_allocated) |
| 120 | section_realloc(cur_text_section, ind1); | 114 | section_realloc(S, cur_text_section, ind1); |
| 121 | write32le(cur_text_section->data + ind, c); | 115 | write32le(cur_text_section->data + S->tccgen_ind, c); |
| 122 | ind = ind1; | 116 | S->tccgen_ind = ind1; |
| 123 | } | 117 | } |
| 124 | 118 | ||
| 125 | static int arm64_encode_bimm64(uint64_t x) | 119 | static int arm64_encode_bimm64(uint64_t x) |
| @@ -208,11 +202,11 @@ static uint32_t arm64_movi(int r, uint64_t x) · 82 unmodified lines | |||
| 208 | return 0; | 202 | return 0; |
| 209 | } | 203 | } |
| 210 | 204 | ||
| 211 | static void arm64_movimm(int r, uint64_t x) | 205 | static void arm64_movimm(TCCState *S, int r, uint64_t x) |
| 212 | { | 206 | { |
| 213 | uint32_t i; | 207 | uint32_t i; |
| 214 | if ((i = arm64_movi(r, x))) | 208 | if ((i = arm64_movi(r, x))) |
| 215 | o(i); // a single MOV | 209 | o(S, i); // a single MOV |
| 216 | else { | 210 | else { |
| 217 | // MOVZ/MOVN and 1-3 MOVKs | 211 | // MOVZ/MOVN and 1-3 MOVKs |
| 218 | int z = 0, m = 0; | 212 | int z = 0, m = 0; |
| @@ -228,19 +222,19 @@ static void arm64_movimm(int r, uint64_t x) · 9 unmodified lines | |||
| 228 | } | 222 | } |
| 229 | for (i = 0; i < 64; i += 16) | 223 | for (i = 0; i < 64; i += 16) |
| 230 | if (x1 >> i & 0xffff) { | 224 | if (x1 >> i & 0xffff) { |
| 231 | o(mov1 | r | (x1 >> i & 0xffff) << 5 | i << 17); | 225 | o(S, mov1 | r | (x1 >> i & 0xffff) << 5 | i << 17); |
| 232 | // movz/movn x(r),#(*),lsl #(i) | 226 | // movz/movn x(r),#(*),lsl #(i) |
| 233 | break; | 227 | break; |
| 234 | } | 228 | } |
| 235 | for (i += 16; i < 64; i += 16) | 229 | for (i += 16; i < 64; i += 16) |
| 236 | if (x1 >> i & 0xffff) | 230 | if (x1 >> i & 0xffff) |
| 237 | o(0xf2800000 | r | (x >> i & 0xffff) << 5 | i << 17); | 231 | o(S, 0xf2800000 | r | (x >> i & 0xffff) << 5 | i << 17); |
| 238 | // movk x(r),#(*),lsl #(i) | 232 | // movk x(r),#(*),lsl #(i) |
| 239 | } | 233 | } |
| 240 | } | 234 | } |
| 241 | 235 | ||
| 242 | // Patch all branches in list pointed to by t to branch to a: | 236 | // Patch all branches in list pointed to by t to branch to a: |
| 243 | ST_FUNC void gsym_addr(int t_, int a_) | 237 | ST_FUNC void gsym_addr(TCCState *S, int t_, int a_) |
| 244 | { | 238 | { |
| 245 | uint32_t t = t_; | 239 | uint32_t t = t_; |
| 246 | uint32_t a = a_; | 240 | uint32_t a = a_; |
| @@ -248,7 +242,7 @@ ST_FUNC void gsym_addr(int t_, int a_) · 1 unmodified line | |||
| 248 | unsigned char *ptr = cur_text_section->data + t; | 242 | unsigned char *ptr = cur_text_section->data + t; |
| 249 | uint32_t next = read32le(ptr); | 243 | uint32_t next = read32le(ptr); |
| 250 | if (a - t + 0x8000000 >= 0x10000000) | 244 | if (a - t + 0x8000000 >= 0x10000000) |
| 251 | tcc_error("branch out of range"); | 245 | tcc_error(S, "branch out of range"); |
| 252 | write32le(ptr, (a - t == 4 ? 0xd503201f : // nop | 246 | write32le(ptr, (a - t == 4 ? 0xd503201f : // nop |
| 253 | 0x14000000 | ((a - t) >> 2 & 0x3ffffff))); // b | 247 | 0x14000000 | ((a - t) >> 2 & 0x3ffffff))); // b |
| 254 | t = next; | 248 | t = next; |
| @@ -278,17 +272,17 @@ static int arm64_type_size(int t) · 23 unmodified lines | |||
| 278 | return 0; | 272 | return 0; |
| 279 | } | 273 | } |
| 280 | 274 | ||
| 281 | static void arm64_spoff(int reg, uint64_t off) | 275 | static void arm64_spoff(TCCState *S, int reg, uint64_t off) |
| 282 | { | 276 | { |
| 283 | uint32_t sub = off >> 63; | 277 | uint32_t sub = off >> 63; |
| 284 | if (sub) | 278 | if (sub) |
| 285 | off = -off; | 279 | off = -off; |
| 286 | if (off < 4096) | 280 | if (off < 4096) |
| 287 | o(0x910003e0 | sub << 30 | reg | off << 10); | 281 | o(S, 0x910003e0 | sub << 30 | reg | off << 10); |
| 288 | // (add|sub) x(reg),sp,#(off) | 282 | // (add|sub) x(reg),sp,#(off) |
| 289 | else { | 283 | else { |
| 290 | arm64_movimm(30, off); // use x30 for offset | 284 | arm64_movimm(S, 30, off); // use x30 for offset |
| 291 | o(0x8b3e63e0 | sub << 30 | reg); // (add|sub) x(reg),sp,x30 | 285 | o(S, 0x8b3e63e0 | sub << 30 | reg); // (add|sub) x(reg),sp,x30 |
| 292 | } | 286 | } |
| 293 | } | 287 | } |
| 294 | 288 | ||
| @@ -309,41 +303,41 @@ static uint64_t arm64_check_offset(int invert, int sz_, uint64_t off) · 14 unmodified lines | |||
| 309 | return invert ? 0ul : off; | 303 | return invert ? 0ul : off; |
| 310 | } | 304 | } |
| 311 | 305 | ||
| 312 | static void arm64_ldrx(int sg, int sz_, int dst, int bas, uint64_t off) | 306 | static void arm64_ldrx(TCCState *S, int sg, int sz_, int dst, int bas, uint64_t off) |
| 313 | { | 307 | { |
| 314 | uint32_t sz = sz_; | 308 | uint32_t sz = sz_; |
| 315 | if (sz >= 2) | 309 | if (sz >= 2) |
| 316 | sg = 0; | 310 | sg = 0; |
| 317 | if (!(off & ~((uint32_t)0xfff << sz))) | 311 | if (!(off & ~((uint32_t)0xfff << sz))) |
| 318 | o(0x39400000 | dst | bas << 5 | off << (10 - sz) | | 312 | o(S, 0x39400000 | dst | bas << 5 | off << (10 - sz) | |
| 319 | (uint32_t)!!sg << 23 | sz << 30); // ldr(*) x(dst),[x(bas),#(off)] | 313 | (uint32_t)!!sg << 23 | sz << 30); // ldr(*) x(dst),[x(bas),#(off)] |
| 320 | else if (off < 256 || -off <= 256) | 314 | else if (off < 256 || -off <= 256) |
| 321 | o(0x38400000 | dst | bas << 5 | (off & 511) << 12 | | 315 | o(S, 0x38400000 | dst | bas << 5 | (off & 511) << 12 | |
| 322 | (uint32_t)!!sg << 23 | sz << 30); // ldur(*) x(dst),[x(bas),#(off)] | 316 | (uint32_t)!!sg << 23 | sz << 30); // ldur(*) x(dst),[x(bas),#(off)] |
| 323 | else { | 317 | else { |
| 324 | arm64_movimm(30, off); // use x30 for offset | 318 | arm64_movimm(S, 30, off); // use x30 for offset |
| 325 | o(0x38206800 | dst | bas << 5 | (uint32_t)30 << 16 | | 319 | o(S, 0x38206800 | dst | bas << 5 | (uint32_t)30 << 16 | |
| 326 | (uint32_t)(!!sg + 1) << 22 | sz << 30); // ldr(*) x(dst),[x(bas),x30] | 320 | (uint32_t)(!!sg + 1) << 22 | sz << 30); // ldr(*) x(dst),[x(bas),x30] |
| 327 | } | 321 | } |
| 328 | } | 322 | } |
| 329 | 323 | ||
| 330 | static void arm64_ldrv(int sz_, int dst, int bas, uint64_t off) | 324 | static void arm64_ldrv(TCCState *S, int sz_, int dst, int bas, uint64_t off) |
| 331 | { | 325 | { |
| 332 | uint32_t sz = sz_; | 326 | uint32_t sz = sz_; |
| 333 | if (!(off & ~((uint32_t)0xfff << sz))) | 327 | if (!(off & ~((uint32_t)0xfff << sz))) |
| 334 | o(0x3d400000 | dst | bas << 5 | off << (10 - sz) | | 328 | o(S, 0x3d400000 | dst | bas << 5 | off << (10 - sz) | |
| 335 | (sz & 4) << 21 | (sz & 3) << 30); // ldr (s|d|q)(dst),[x(bas),#(off)] | 329 | (sz & 4) << 21 | (sz & 3) << 30); // ldr (s|d|q)(dst),[x(bas),#(off)] |
| 336 | else if (off < 256 || -off <= 256) | 330 | else if (off < 256 || -off <= 256) |
| 337 | o(0x3c400000 | dst | bas << 5 | (off & 511) << 12 | | 331 | o(S, 0x3c400000 | dst | bas << 5 | (off & 511) << 12 | |
| 338 | (sz & 4) << 21 | (sz & 3) << 30); // ldur (s|d|q)(dst),[x(bas),#(off)] | 332 | (sz & 4) << 21 | (sz & 3) << 30); // ldur (s|d|q)(dst),[x(bas),#(off)] |
| 339 | else { | 333 | else { |
| 340 | arm64_movimm(30, off); // use x30 for offset | 334 | arm64_movimm(S, 30, off); // use x30 for offset |
| 341 | o(0x3c606800 | dst | bas << 5 | (uint32_t)30 << 16 | | 335 | o(S, 0x3c606800 | dst | bas << 5 | (uint32_t)30 << 16 | |
| 342 | sz << 30 | (sz & 4) << 21); // ldr (s|d|q)(dst),[x(bas),x30] | 336 | sz << 30 | (sz & 4) << 21); // ldr (s|d|q)(dst),[x(bas),x30] |
| 343 | } | 337 | } |
| 344 | } | 338 | } |
| 345 | 339 | ||
| 346 | static void arm64_ldrs(int reg_, int size) | 340 | static void arm64_ldrs(TCCState *S, int reg_, int size) |
| 347 | { | 341 | { |
| 348 | uint32_t reg = reg_; | 342 | uint32_t reg = reg_; |
| 349 | // Use x30 for intermediate value in some cases. | 343 | // Use x30 for intermediate value in some cases. |
| @@ -353,138 +347,138 @@ static void arm64_ldrs(int reg_, int size) · 3 unmodified lines | |||
| 353 | /* Can happen with zero size structs */ | 347 | /* Can happen with zero size structs */ |
| 354 | break; | 348 | break; |
| 355 | case 1: | 349 | case 1: |
| 356 | arm64_ldrx(0, 0, reg, reg, 0); | 350 | arm64_ldrx(S, 0, 0, reg, reg, 0); |
| 357 | break; | 351 | break; |
| 358 | case 2: | 352 | case 2: |
| 359 | arm64_ldrx(0, 1, reg, reg, 0); | 353 | arm64_ldrx(S, 0, 1, reg, reg, 0); |
| 360 | break; | 354 | break; |
| 361 | case 3: | 355 | case 3: |
| 362 | arm64_ldrx(0, 1, 30, reg, 0); | 356 | arm64_ldrx(S, 0, 1, 30, reg, 0); |
| 363 | arm64_ldrx(0, 0, reg, reg, 2); | 357 | arm64_ldrx(S, 0, 0, reg, reg, 2); |
| 364 | o(0x2a0043c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #16 | 358 | o(S, 0x2a0043c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #16 |
| 365 | break; | 359 | break; |
| 366 | case 4: | 360 | case 4: |
| 367 | arm64_ldrx(0, 2, reg, reg, 0); | 361 | arm64_ldrx(S, 0, 2, reg, reg, 0); |
| 368 | break; | 362 | break; |
| 369 | case 5: | 363 | case 5: |
| 370 | arm64_ldrx(0, 2, 30, reg, 0); | 364 | arm64_ldrx(S, 0, 2, 30, reg, 0); |
| 371 | arm64_ldrx(0, 0, reg, reg, 4); | 365 | arm64_ldrx(S, 0, 0, reg, reg, 4); |
| 372 | o(0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32 | 366 | o(S, 0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32 |
| 373 | break; | 367 | break; |
| 374 | case 6: | 368 | case 6: |
| 375 | arm64_ldrx(0, 2, 30, reg, 0); | 369 | arm64_ldrx(S, 0, 2, 30, reg, 0); |
| 376 | arm64_ldrx(0, 1, reg, reg, 4); | 370 | arm64_ldrx(S, 0, 1, reg, reg, 4); |
| 377 | o(0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32 | 371 | o(S, 0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32 |
| 378 | break; | 372 | break; |
| 379 | case 7: | 373 | case 7: |
| 380 | arm64_ldrx(0, 2, 30, reg, 0); | 374 | arm64_ldrx(S, 0, 2, 30, reg, 0); |
| 381 | arm64_ldrx(0, 2, reg, reg, 3); | 375 | arm64_ldrx(S, 0, 2, reg, reg, 3); |
| 382 | o(0x53087c00 | reg | reg << 5); // lsr w(reg), w(reg), #8 | 376 | o(S, 0x53087c00 | reg | reg << 5); // lsr w(reg), w(reg), #8 |
| 383 | o(0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32 | 377 | o(S, 0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32 |
| 384 | break; | 378 | break; |
| 385 | case 8: | 379 | case 8: |
| 386 | arm64_ldrx(0, 3, reg, reg, 0); | 380 | arm64_ldrx(S, 0, 3, reg, reg, 0); |
| 387 | break; | 381 | break; |
| 388 | case 9: | 382 | case 9: |
| 389 | arm64_ldrx(0, 0, reg + 1, reg, 8); | 383 | arm64_ldrx(S, 0, 0, reg + 1, reg, 8); |
| 390 | arm64_ldrx(0, 3, reg, reg, 0); | 384 | arm64_ldrx(S, 0, 3, reg, reg, 0); |
| 391 | break; | 385 | break; |
| 392 | case 10: | 386 | case 10: |
| 393 | arm64_ldrx(0, 1, reg + 1, reg, 8); | 387 | arm64_ldrx(S, 0, 1, reg + 1, reg, 8); |
| 394 | arm64_ldrx(0, 3, reg, reg, 0); | 388 | arm64_ldrx(S, 0, 3, reg, reg, 0); |
| 395 | break; | 389 | break; |
| 396 | case 11: | 390 | case 11: |
| 397 | arm64_ldrx(0, 2, reg + 1, reg, 7); | 391 | arm64_ldrx(S, 0, 2, reg + 1, reg, 7); |
| 398 | o(0x53087c00 | (reg+1) | (reg+1) << 5); // lsr w(reg+1), w(reg+1), #8 | 392 | o(S, 0x53087c00 | (reg+1) | (reg+1) << 5); // lsr w(reg+1), w(reg+1), #8 |
| 399 | arm64_ldrx(0, 3, reg, reg, 0); | 393 | arm64_ldrx(S, 0, 3, reg, reg, 0); |
| 400 | break; | 394 | break; |
| 401 | case 12: | 395 | case 12: |
| 402 | arm64_ldrx(0, 2, reg + 1, reg, 8); | 396 | arm64_ldrx(S, 0, 2, reg + 1, reg, 8); |
| 403 | arm64_ldrx(0, 3, reg, reg, 0); | 397 | arm64_ldrx(S, 0, 3, reg, reg, 0); |
| 404 | break; | 398 | break; |
| 405 | case 13: | 399 | case 13: |
| 406 | arm64_ldrx(0, 3, reg + 1, reg, 5); | 400 | arm64_ldrx(S, 0, 3, reg + 1, reg, 5); |
| 407 | o(0xd358fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #24 | 401 | o(S, 0xd358fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #24 |
| 408 | arm64_ldrx(0, 3, reg, reg, 0); | 402 | arm64_ldrx(S, 0, 3, reg, reg, 0); |
| 409 | break; | 403 | break; |
| 410 | case 14: | 404 | case 14: |
| 411 | arm64_ldrx(0, 3, reg + 1, reg, 6); | 405 | arm64_ldrx(S, 0, 3, reg + 1, reg, 6); |
| 412 | o(0xd350fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #16 | 406 | o(S, 0xd350fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #16 |
| 413 | arm64_ldrx(0, 3, reg, reg, 0); | 407 | arm64_ldrx(S, 0, 3, reg, reg, 0); |
| 414 | break; | 408 | break; |
| 415 | case 15: | 409 | case 15: |
| 416 | arm64_ldrx(0, 3, reg + 1, reg, 7); | 410 | arm64_ldrx(S, 0, 3, reg + 1, reg, 7); |
| 417 | o(0xd348fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #8 | 411 | o(S, 0xd348fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #8 |
| 418 | arm64_ldrx(0, 3, reg, reg, 0); | 412 | arm64_ldrx(S, 0, 3, reg, reg, 0); |
| 419 | break; | 413 | break; |
| 420 | case 16: | 414 | case 16: |
| 421 | o(0xa9400000 | reg | (reg+1) << 10 | reg << 5); | 415 | o(S, 0xa9400000 | reg | (reg+1) << 10 | reg << 5); |
| 422 | // ldp x(reg),x(reg+1),[x(reg)] | 416 | // ldp x(reg),x(reg+1),[x(reg)] |
| 423 | break; | 417 | break; |
| 424 | } | 418 | } |
| 425 | } | 419 | } |
| 426 | 420 | ||
| 427 | static void arm64_strx(int sz_, int dst, int bas, uint64_t off) | 421 | static void arm64_strx(TCCState *S, int sz_, int dst, int bas, uint64_t off) |
| 428 | { | 422 | { |
| 429 | uint32_t sz = sz_; | 423 | uint32_t sz = sz_; |
| 430 | if (!(off & ~((uint32_t)0xfff << sz))) | 424 | if (!(off & ~((uint32_t)0xfff << sz))) |
| 431 | o(0x39000000 | dst | bas << 5 | off << (10 - sz) | sz << 30); | 425 | o(S, 0x39000000 | dst | bas << 5 | off << (10 - sz) | sz << 30); |
| 432 | // str(*) x(dst),[x(bas],#(off)] | 426 | // str(*) x(dst),[x(bas],#(off)] |
| 433 | else if (off < 256 || -off <= 256) | 427 | else if (off < 256 || -off <= 256) |
| 434 | o(0x38000000 | dst | bas << 5 | (off & 511) << 12 | sz << 30); | 428 | o(S, 0x38000000 | dst | bas << 5 | (off & 511) << 12 | sz << 30); |
| 435 | // stur(*) x(dst),[x(bas],#(off)] | 429 | // stur(*) x(dst),[x(bas],#(off)] |
| 436 | else { | 430 | else { |
| 437 | arm64_movimm(30, off); // use x30 for offset | 431 | arm64_movimm(S, 30, off); // use x30 for offset |
| 438 | o(0x38206800 | dst | bas << 5 | (uint32_t)30 << 16 | sz << 30); | 432 | o(S, 0x38206800 | dst | bas << 5 | (uint32_t)30 << 16 | sz << 30); |
| 439 | // str(*) x(dst),[x(bas),x30] | 433 | // str(*) x(dst),[x(bas),x30] |
| 440 | } | 434 | } |
| 441 | } | 435 | } |
| 442 | 436 | ||
| 443 | static void arm64_strv(int sz_, int dst, int bas, uint64_t off) | 437 | static void arm64_strv(TCCState *S, int sz_, int dst, int bas, uint64_t off) |
| 444 | { | 438 | { |
| 445 | uint32_t sz = sz_; | 439 | uint32_t sz = sz_; |
| 446 | if (!(off & ~((uint32_t)0xfff << sz))) | 440 | if (!(off & ~((uint32_t)0xfff << sz))) |
| 447 | o(0x3d000000 | dst | bas << 5 | off << (10 - sz) | | 441 | o(S, 0x3d000000 | dst | bas << 5 | off << (10 - sz) | |
| 448 | (sz & 4) << 21 | (sz & 3) << 30); // str (s|d|q)(dst),[x(bas),#(off)] | 442 | (sz & 4) << 21 | (sz & 3) << 30); // str (s|d|q)(dst),[x(bas),#(off)] |
| 449 | else if (off < 256 || -off <= 256) | 443 | else if (off < 256 || -off <= 256) |
| 450 | o(0x3c000000 | dst | bas << 5 | (off & 511) << 12 | | 444 | o(S, 0x3c000000 | dst | bas << 5 | (off & 511) << 12 | |
| 451 | (sz & 4) << 21 | (sz & 3) << 30); // stur (s|d|q)(dst),[x(bas),#(off)] | 445 | (sz & 4) << 21 | (sz & 3) << 30); // stur (s|d|q)(dst),[x(bas),#(off)] |
| 452 | else { | 446 | else { |
| 453 | arm64_movimm(30, off); // use x30 for offset | 447 | arm64_movimm(S, 30, off); // use x30 for offset |
| 454 | o(0x3c206800 | dst | bas << 5 | (uint32_t)30 << 16 | | 448 | o(S, 0x3c206800 | dst | bas << 5 | (uint32_t)30 << 16 | |
| 455 | sz << 30 | (sz & 4) << 21); // str (s|d|q)(dst),[x(bas),x30] | 449 | sz << 30 | (sz & 4) << 21); // str (s|d|q)(dst),[x(bas),x30] |
| 456 | } | 450 | } |
| 457 | } | 451 | } |
| 458 | 452 | ||
| 459 | static void arm64_sym(int r, Sym *sym, unsigned long addend) | 453 | static void arm64_sym(TCCState *S, int r, Sym *sym, unsigned long addend) |
| 460 | { | 454 | { |
| 461 | greloca(cur_text_section, sym, ind, R_AARCH64_ADR_GOT_PAGE, 0); | 455 | greloca(S, cur_text_section, sym, S->tccgen_ind, R_AARCH64_ADR_GOT_PAGE, 0); |
| 462 | o(0x90000000 | r); // adrp xr, #sym | 456 | o(S, 0x90000000 | r); // adrp xr, #sym |
| 463 | greloca(cur_text_section, sym, ind, R_AARCH64_LD64_GOT_LO12_NC, 0); | 457 | greloca(S, cur_text_section, sym, S->tccgen_ind, R_AARCH64_LD64_GOT_LO12_NC, 0); |
| 464 | o(0xf9400000 | r | (r << 5)); // ld xr,[xr, #sym] | 458 | o(S, 0xf9400000 | r | (r << 5)); // ld xr,[xr, #sym] |
| 465 | if (addend) { | 459 | if (addend) { |
| 466 | // add xr, xr, #addend | 460 | // add xr, xr, #addend |
| 467 | if (addend & 0xffful) | 461 | if (addend & 0xffful) |
| 468 | o(0x91000000 | r | r << 5 | (addend & 0xfff) << 10); | 462 | o(S, 0x91000000 | r | r << 5 | (addend & 0xfff) << 10); |
| 469 | if (addend > 0xffful) { | 463 | if (addend > 0xffful) { |
| 470 | // add xr, xr, #addend, lsl #12 | 464 | // add xr, xr, #addend, lsl #12 |
| 471 | if (addend & 0xfff000ul) | 465 | if (addend & 0xfff000ul) |
| 472 | o(0x91400000 | r | r << 5 | ((addend >> 12) & 0xfff) << 10); | 466 | o(S, 0x91400000 | r | r << 5 | ((addend >> 12) & 0xfff) << 10); |
| 473 | if (addend > 0xfffffful) { | 467 | if (addend > 0xfffffful) { |
| 474 | /* very unlikely */ | 468 | /* very unlikely */ |
| 475 | int t = r ? 0 : 1; | 469 | int t = r ? 0 : 1; |
| 476 | o(0xf81f0fe0 | t); /* str xt, [sp, #-16]! */ | 470 | o(S, 0xf81f0fe0 | t); /* str xt, [sp, #-16]! */ |
| 477 | arm64_movimm(t, addend & ~0xfffffful); // use xt for addent | 471 | arm64_movimm(S, t, addend & ~0xfffffful); // use xt for addent |
| 478 | o(0x91000000 | r | (t << 5)); /* add xr, xt, #0 */ | 472 | o(S, 0x91000000 | r | (t << 5)); /* add xr, xt, #0 */ |
| 479 | o(0xf84107e0 | t); /* ldr xt, [sp], #16 */ | 473 | o(S, 0xf84107e0 | t); /* ldr xt, [sp], #16 */ |
| 480 | } | 474 | } |
| 481 | } | 475 | } |
| 482 | } | 476 | } |
| 483 | } | 477 | } |
| 484 | 478 | ||
| 485 | static void arm64_load_cmp(int r, SValue *sv); | 479 | static void arm64_load_cmp(TCCState *S, int r, SValue *sv); |
| 486 | 480 | ||
| 487 | ST_FUNC void load(int r, SValue *sv) | 481 | ST_FUNC void load(TCCState *S, int r, SValue *sv) |
| 488 | { | 482 | { |
| 489 | int svtt = sv->type.t; | 483 | int svtt = sv->type.t; |
| 490 | int svr = sv->r & ~VT_BOUNDED; | 484 | int svr = sv->r & ~VT_BOUNDED; |
| @@ -494,24 +488,24 @@ ST_FUNC void load(int r, SValue *sv) · 3 unmodified lines | |||
| 494 | 488 | ||
| 495 | if (svr == (VT_LOCAL | VT_LVAL)) { | 489 | if (svr == (VT_LOCAL | VT_LVAL)) { |
| 496 | if (IS_FREG(r)) | 490 | if (IS_FREG(r)) |
| 497 | arm64_ldrv(arm64_type_size(svtt), fltr(r), 29, svcul); | 491 | arm64_ldrv(S, arm64_type_size(svtt), fltr(r), 29, svcul); |
| 498 | else | 492 | else |
| 499 | arm64_ldrx(!(svtt & VT_UNSIGNED), arm64_type_size(svtt), | 493 | arm64_ldrx(S, !(svtt & VT_UNSIGNED), arm64_type_size(svtt), |
| 500 | intr(r), 29, svcul); | 494 | intr(S, r), 29, svcul); |
| 501 | return; | 495 | return; |
| 502 | } | 496 | } |
| 503 | 497 | ||
| 504 | if (svr == (VT_CONST | VT_LVAL)) { | 498 | if (svr == (VT_CONST | VT_LVAL)) { |
| 505 | if (sv->sym) | 499 | if (sv->sym) |
| 506 | arm64_sym(30, sv->sym, // use x30 for address | 500 | arm64_sym(S, 30, sv->sym, // use x30 for address |
| 507 | arm64_check_offset(0, arm64_type_size(svtt), sv->c.i)); | 501 | arm64_check_offset(0, arm64_type_size(svtt), sv->c.i)); |
| 508 | else | 502 | else |
| 509 | arm64_movimm (30, sv->c.i); | 503 | arm64_movimm (S, 30, sv->c.i); |
| 510 | if (IS_FREG(r)) | 504 | if (IS_FREG(r)) |
| 511 | arm64_ldrv(arm64_type_size(svtt), fltr(r), 30, | 505 | arm64_ldrv(S, arm64_type_size(svtt), fltr(r), 30, |
| 512 | arm64_check_offset(1, arm64_type_size(svtt), sv->c.i)); | 506 | arm64_check_offset(1, arm64_type_size(svtt), sv->c.i)); |
| 513 | else | 507 | else |
| 514 | arm64_ldrx(!(svtt&VT_UNSIGNED), arm64_type_size(svtt), intr(r), 30, | 508 | arm64_ldrx(S, !(svtt&VT_UNSIGNED), arm64_type_size(svtt), intr(S, r), 30, |
| 515 | arm64_check_offset(1, arm64_type_size(svtt), sv->c.i)); | 509 | arm64_check_offset(1, arm64_type_size(svtt), sv->c.i)); |
| 516 | return; | 510 | return; |
| 517 | } | 511 | } |
| @@ -519,34 +513,34 @@ ST_FUNC void load(int r, SValue *sv) · 1 unmodified line | |||
| 519 | if ((svr & ~VT_VALMASK) == VT_LVAL && svrv < VT_CONST) { | 513 | if ((svr & ~VT_VALMASK) == VT_LVAL && svrv < VT_CONST) { |
| 520 | if ((svtt & VT_BTYPE) != VT_VOID) { | 514 | if ((svtt & VT_BTYPE) != VT_VOID) { |
| 521 | if (IS_FREG(r)) | 515 | if (IS_FREG(r)) |
| 522 | arm64_ldrv(arm64_type_size(svtt), fltr(r), intr(svrv), 0); | 516 | arm64_ldrv(S, arm64_type_size(svtt), fltr(r), intr(S, svrv), 0); |
| 523 | else | 517 | else |
| 524 | arm64_ldrx(!(svtt & VT_UNSIGNED), arm64_type_size(svtt), | 518 | arm64_ldrx(S, !(svtt & VT_UNSIGNED), arm64_type_size(svtt), |
| 525 | intr(r), intr(svrv), 0); | 519 | intr(S, r), intr(S, svrv), 0); |
| 526 | } | 520 | } |
| 527 | return; | 521 | return; |
| 528 | } | 522 | } |
| 529 | 523 | ||
| 530 | if (svr == (VT_CONST | VT_LVAL | VT_SYM)) { | 524 | if (svr == (VT_CONST | VT_LVAL | VT_SYM)) { |
| 531 | arm64_sym(30, sv->sym, // use x30 for address | 525 | arm64_sym(S, 30, sv->sym, // use x30 for address |
| 532 | arm64_check_offset(0, arm64_type_size(svtt), svcul)); | 526 | arm64_check_offset(0, arm64_type_size(svtt), svcul)); |
| 533 | if (IS_FREG(r)) | 527 | if (IS_FREG(r)) |
| 534 | arm64_ldrv(arm64_type_size(svtt), fltr(r), 30, | 528 | arm64_ldrv(S, arm64_type_size(svtt), fltr(r), 30, |
| 535 | arm64_check_offset(1, arm64_type_size(svtt), svcul)); | 529 | arm64_check_offset(1, arm64_type_size(svtt), svcul)); |
| 536 | else | 530 | else |
| 537 | arm64_ldrx(!(svtt&VT_UNSIGNED), arm64_type_size(svtt), intr(r), 30, | 531 | arm64_ldrx(S, !(svtt&VT_UNSIGNED), arm64_type_size(svtt), intr(S, r), 30, |
| 538 | arm64_check_offset(1, arm64_type_size(svtt), svcul)); | 532 | arm64_check_offset(1, arm64_type_size(svtt), svcul)); |
| 539 | return; | 533 | return; |
| 540 | } | 534 | } |
| 541 | 535 | ||
| 542 | if (svr == (VT_CONST | VT_SYM)) { | 536 | if (svr == (VT_CONST | VT_SYM)) { |
| 543 | arm64_sym(intr(r), sv->sym, svcul); | 537 | arm64_sym(S, intr(S, r), sv->sym, svcul); |
| 544 | return; | 538 | return; |
| 545 | } | 539 | } |
| 546 | 540 | ||
| 547 | if (svr == VT_CONST) { | 541 | if (svr == VT_CONST) { |
| 548 | if ((svtt & VT_BTYPE) != VT_VOID) | 542 | if ((svtt & VT_BTYPE) != VT_VOID) |
| 549 | arm64_movimm(intr(r), arm64_type_size(svtt) == 3 ? | 543 | arm64_movimm(S, intr(S, r), arm64_type_size(svtt) == 3 ? |
| 550 | sv->c.i : (uint32_t)svcul); | 544 | sv->c.i : (uint32_t)svcul); |
| 551 | return; | 545 | return; |
| 552 | } | 546 | } |
| @@ -554,12 +548,12 @@ ST_FUNC void load(int r, SValue *sv) · 1 unmodified line | |||
| 554 | if (svr < VT_CONST) { | 548 | if (svr < VT_CONST) { |
| 555 | if (IS_FREG(r) && IS_FREG(svr)) | 549 | if (IS_FREG(r) && IS_FREG(svr)) |
| 556 | if (svtt == VT_LDOUBLE) | 550 | if (svtt == VT_LDOUBLE) |
| 557 | o(0x4ea01c00 | fltr(r) | fltr(svr) << 5); | 551 | o(S, 0x4ea01c00 | fltr(r) | fltr(svr) << 5); |
| 558 | // mov v(r).16b,v(svr).16b | 552 | // mov v(r).16b,v(svr).16b |
| 559 | else | 553 | else |
| 560 | o(0x1e604000 | fltr(r) | fltr(svr) << 5); // fmov d(r),d(svr) | 554 | o(S, 0x1e604000 | fltr(r) | fltr(svr) << 5); // fmov d(r),d(svr) |
| 561 | else if (!IS_FREG(r) && !IS_FREG(svr)) | 555 | else if (!IS_FREG(r) && !IS_FREG(svr)) |
| 562 | o(0xaa0003e0 | intr(r) | intr(svr) << 16); // mov x(r),x(svr) | 556 | o(S, 0xaa0003e0 | intr(S, r) | intr(S, svr) << 16); // mov x(r),x(svr) |
| 563 | else | 557 | else |
| 564 | assert(0); | 558 | assert(0); |
| 565 | return; | 559 | return; |
| @@ -567,35 +561,35 @@ ST_FUNC void load(int r, SValue *sv) · 1 unmodified line | |||
| 567 | 561 | ||
| 568 | if (svr == VT_LOCAL) { | 562 | if (svr == VT_LOCAL) { |
| 569 | if (-svcul < 0x1000) | 563 | if (-svcul < 0x1000) |
| 570 | o(0xd10003a0 | intr(r) | -svcul << 10); // sub x(r),x29,#... | 564 | o(S, 0xd10003a0 | intr(S, r) | -svcul << 10); // sub x(r),x29,#... |
| 571 | else { | 565 | else { |
| 572 | arm64_movimm(30, -svcul); // use x30 for offset | 566 | arm64_movimm(S, 30, -svcul); // use x30 for offset |
| 573 | o(0xcb0003a0 | intr(r) | (uint32_t)30 << 16); // sub x(r),x29,x30 | 567 | o(S, 0xcb0003a0 | intr(S, r) | (uint32_t)30 << 16); // sub x(r),x29,x30 |
| 574 | } | 568 | } |
| 575 | return; | 569 | return; |
| 576 | } | 570 | } |
| 577 | 571 | ||
| 578 | if (svr == VT_JMP || svr == VT_JMPI) { | 572 | if (svr == VT_JMP || svr == VT_JMPI) { |
| 579 | int t = (svr == VT_JMPI); | 573 | int t = (svr == VT_JMPI); |
| 580 | arm64_movimm(intr(r), t); | 574 | arm64_movimm(S, intr(S, r), t); |
| 581 | o(0x14000002); // b .+8 | 575 | o(S, 0x14000002); // b .+8 |
| 582 | gsym(svcul); | 576 | gsym(S, svcul); |
| 583 | arm64_movimm(intr(r), t ^ 1); | 577 | arm64_movimm(S, intr(S, r), t ^ 1); |
| 584 | return; | 578 | return; |
| 585 | } | 579 | } |
| 586 | 580 | ||
| 587 | if (svr == (VT_LLOCAL | VT_LVAL)) { | 581 | if (svr == (VT_LLOCAL | VT_LVAL)) { |
| 588 | arm64_ldrx(0, 3, 30, 29, svcul); // use x30 for offset | 582 | arm64_ldrx(S, 0, 3, 30, 29, svcul); // use x30 for offset |
| 589 | if (IS_FREG(r)) | 583 | if (IS_FREG(r)) |
| 590 | arm64_ldrv(arm64_type_size(svtt), fltr(r), 30, 0); | 584 | arm64_ldrv(S, arm64_type_size(svtt), fltr(r), 30, 0); |
| 591 | else | 585 | else |
| 592 | arm64_ldrx(!(svtt & VT_UNSIGNED), arm64_type_size(svtt), | 586 | arm64_ldrx(S, !(svtt & VT_UNSIGNED), arm64_type_size(svtt), |
| 593 | intr(r), 30, 0); | 587 | intr(S, r), 30, 0); |
| 594 | return; | 588 | return; |
| 595 | } | 589 | } |
| 596 | 590 | ||
| 597 | if (svr == VT_CMP) { | 591 | if (svr == VT_CMP) { |
| 598 | arm64_load_cmp(r, sv); | 592 | arm64_load_cmp(S, r, sv); |
| 599 | return; | 593 | return; |
| 600 | } | 594 | } |
| 601 | 595 | ||
| @@ -603,7 +597,7 @@ ST_FUNC void load(int r, SValue *sv) · 1 unmodified line | |||
| 603 | assert(0); | 597 | assert(0); |
| 604 | } | 598 | } |
| 605 | 599 | ||
| 606 | ST_FUNC void store(int r, SValue *sv) | 600 | ST_FUNC void store(TCCState *S, int r, SValue *sv) |
| 607 | { | 601 | { |
| 608 | int svtt = sv->type.t; | 602 | int svtt = sv->type.t; |
| 609 | int svr = sv->r & ~VT_BOUNDED; | 603 | int svr = sv->r & ~VT_BOUNDED; |
| @@ -613,43 +607,43 @@ ST_FUNC void store(int r, SValue *sv) · 3 unmodified lines | |||
| 613 | 607 | ||
| 614 | if (svr == (VT_LOCAL | VT_LVAL)) { | 608 | if (svr == (VT_LOCAL | VT_LVAL)) { |
| 615 | if (IS_FREG(r)) | 609 | if (IS_FREG(r)) |
| 616 | arm64_strv(arm64_type_size(svtt), fltr(r), 29, svcul); | 610 | arm64_strv(S, arm64_type_size(svtt), fltr(r), 29, svcul); |
| 617 | else | 611 | else |
| 618 | arm64_strx(arm64_type_size(svtt), intr(r), 29, svcul); | 612 | arm64_strx(S, arm64_type_size(svtt), intr(S, r), 29, svcul); |
| 619 | return; | 613 | return; |
| 620 | } | 614 | } |
| 621 | 615 | ||
| 622 | if (svr == (VT_CONST | VT_LVAL)) { | 616 | if (svr == (VT_CONST | VT_LVAL)) { |
| 623 | if (sv->sym) | 617 | if (sv->sym) |
| 624 | arm64_sym(30, sv->sym, // use x30 for address | 618 | arm64_sym(S, 30, sv->sym, // use x30 for address |
| 625 | arm64_check_offset(0, arm64_type_size(svtt), sv->c.i)); | 619 | arm64_check_offset(0, arm64_type_size(svtt), sv->c.i)); |
| 626 | else | 620 | else |
| 627 | arm64_movimm (30, sv->c.i); | 621 | arm64_movimm(S, 30, sv->c.i); |
| 628 | if (IS_FREG(r)) | 622 | if (IS_FREG(r)) |
| 629 | arm64_strv(arm64_type_size(svtt), fltr(r), 30, | 623 | arm64_strv(S, arm64_type_size(svtt), fltr(r), 30, |
| 630 | arm64_check_offset(1, arm64_type_size(svtt), sv->c.i)); | 624 | arm64_check_offset(1, arm64_type_size(svtt), sv->c.i)); |
| 631 | else | 625 | else |
| 632 | arm64_strx(arm64_type_size(svtt), intr(r), 30, | 626 | arm64_strx(S, arm64_type_size(svtt), intr(S, r), 30, |
| 633 | arm64_check_offset(1, arm64_type_size(svtt), sv->c.i)); | 627 | arm64_check_offset(1, arm64_type_size(svtt), sv->c.i)); |
| 634 | return; | 628 | return; |
| 635 | } | 629 | } |
| 636 | 630 | ||
| 637 | if ((svr & ~VT_VALMASK) == VT_LVAL && svrv < VT_CONST) { | 631 | if ((svr & ~VT_VALMASK) == VT_LVAL && svrv < VT_CONST) { |
| 638 | if (IS_FREG(r)) | 632 | if (IS_FREG(r)) |
| 639 | arm64_strv(arm64_type_size(svtt), fltr(r), intr(svrv), 0); | 633 | arm64_strv(S, arm64_type_size(svtt), fltr(r), intr(S, svrv), 0); |
| 640 | else | 634 | else |
| 641 | arm64_strx(arm64_type_size(svtt), intr(r), intr(svrv), 0); | 635 | arm64_strx(S, arm64_type_size(svtt), intr(S, r), intr(S, svrv), 0); |
| 642 | return; | 636 | return; |
| 643 | } | 637 | } |
| 644 | 638 | ||
| 645 | if (svr == (VT_CONST | VT_LVAL | VT_SYM)) { | 639 | if (svr == (VT_CONST | VT_LVAL | VT_SYM)) { |
| 646 | arm64_sym(30, sv->sym, // use x30 for address | 640 | arm64_sym(S, 30, sv->sym, // use x30 for address |
| 647 | arm64_check_offset(0, arm64_type_size(svtt), svcul)); | 641 | arm64_check_offset(0, arm64_type_size(svtt), svcul)); |
| 648 | if (IS_FREG(r)) | 642 | if (IS_FREG(r)) |
| 649 | arm64_strv(arm64_type_size(svtt), fltr(r), 30, | 643 | arm64_strv(S, arm64_type_size(svtt), fltr(r), 30, |
| 650 | arm64_check_offset(1, arm64_type_size(svtt), svcul)); | 644 | arm64_check_offset(1, arm64_type_size(svtt), svcul)); |
| 651 | else | 645 | else |
| 652 | arm64_strx(arm64_type_size(svtt), intr(r), 30, | 646 | arm64_strx(S, arm64_type_size(svtt), intr(S, r), 30, |
| 653 | arm64_check_offset(1, arm64_type_size(svtt), svcul)); | 647 | arm64_check_offset(1, arm64_type_size(svtt), svcul)); |
| 654 | return; | 648 | return; |
| 655 | } | 649 | } |
| @@ -658,82 +652,82 @@ ST_FUNC void store(int r, SValue *sv) · 2 unmodified lines | |||
| 658 | assert(0); | 652 | assert(0); |
| 659 | } | 653 | } |
| 660 | 654 | ||
| 661 | static void arm64_gen_bl_or_b(int b) | 655 | static void arm64_gen_bl_or_b(TCCState *S, int b) |
| 662 | { | 656 | { |
| 663 | if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (vtop->r & VT_SYM)) { | 657 | if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (S->tccgen_vtop->r & VT_SYM)) { |
| 664 | greloca(cur_text_section, vtop->sym, ind, | 658 | greloca(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind, |
| 665 | b ? R_AARCH64_JUMP26 : R_AARCH64_CALL26, 0); | 659 | b ? R_AARCH64_JUMP26 : R_AARCH64_CALL26, 0); |
| 666 | o(0x14000000 | (uint32_t)!b << 31); // b/bl . | 660 | o(S, 0x14000000 | (uint32_t)!b << 31); // b/bl . |
| 667 | } | 661 | } |
| 668 | else { | 662 | else { |
| 669 | #ifdef CONFIG_TCC_BCHECK | 663 | #ifdef CONFIG_TCC_BCHECK |
| 670 | vtop->r &= ~VT_MUSTBOUND; | 664 | S->tccgen_vtop->r &= ~VT_MUSTBOUND; |
| 671 | #endif | 665 | #endif |
| 672 | o(0xd61f0000 | (uint32_t)!b << 21 | intr(gv(RC_R30)) << 5); // br/blr | 666 | o(S, 0xd61f0000 | (uint32_t)!b << 21 | intr(S, gv(S, RC_R30)) << 5); // br/blr |
| 673 | } | 667 | } |
| 674 | } | 668 | } |
| 675 | 669 | ||
| 676 | #if defined(CONFIG_TCC_BCHECK) | 670 | #if defined(CONFIG_TCC_BCHECK) |
| 677 | 671 | ||
| 678 | static void gen_bounds_call(int v) | 672 | static void gen_bounds_call(TCCState *S, int v) |
| 679 | { | 673 | { |
| 680 | Sym *sym = external_helper_sym(v); | 674 | Sym *sym = external_helper_sym(S, v); |
| 681 | 675 | ||
| 682 | greloca(cur_text_section, sym, ind, R_AARCH64_CALL26, 0); | 676 | greloca(S, cur_text_section, sym, S->tccgen_ind, R_AARCH64_CALL26, 0); |
| 683 | o(0x94000000); // bl | 677 | o(S, 0x94000000); // bl |
| 684 | } | 678 | } |
| 685 | 679 | ||
| 686 | static void gen_bounds_prolog(void) | 680 | static void gen_bounds_prolog(TCCState *S) |
| 687 | { | 681 | { |
| 688 | /* leave some room for bound checking code */ | 682 | /* leave some room for bound checking code */ |
| 689 | func_bound_offset = lbounds_section->data_offset; | 683 | S->func_bound_offset = lbounds_section->data_offset; |
| 690 | func_bound_ind = ind; | 684 | S->func_bound_ind = S->tccgen_ind; |
| 691 | func_bound_add_epilog = 0; | 685 | S->func_bound_add_epilog = 0; |
| 692 | o(0xd503201f); /* nop -> mov x0, lbound section pointer */ | 686 | o(S, 0xd503201f); /* nop -> mov x0, lbound section pointer */ |
| 693 | o(0xd503201f); | 687 | o(S, 0xd503201f); |
| 694 | o(0xd503201f); | 688 | o(S, 0xd503201f); |
| 695 | o(0xd503201f); /* nop -> call __bound_local_new */ | 689 | o(S, 0xd503201f); /* nop -> call __bound_local_new */ |
| 696 | } | 690 | } |
| 697 | 691 | ||
| 698 | static void gen_bounds_epilog(void) | 692 | static void gen_bounds_epilog(TCCState *S) |
| 699 | { | 693 | { |
| 700 | addr_t saved_ind; | 694 | addr_t saved_ind; |
| 701 | addr_t *bounds_ptr; | 695 | addr_t *bounds_ptr; |
| 702 | Sym *sym_data; | 696 | Sym *sym_data; |
| 703 | int offset_modified = func_bound_offset != lbounds_section->data_offset; | 697 | int offset_modified = S->func_bound_offset != lbounds_section->data_offset; |
| 704 | 698 | ||
| 705 | if (!offset_modified && !func_bound_add_epilog) | 699 | if (!offset_modified && !S->func_bound_add_epilog) |
| 706 | return; | 700 | return; |
| 707 | 701 | ||
| 708 | /* add end of table info */ | 702 | /* add end of table info */ |
| 709 | bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t)); | 703 | bounds_ptr = section_ptr_add(S, lbounds_section, sizeof(addr_t)); |
| 710 | *bounds_ptr = 0; | 704 | *bounds_ptr = 0; |
| 711 | 705 | ||
| 712 | sym_data = get_sym_ref(&char_pointer_type, lbounds_section, | 706 | sym_data = get_sym_ref(S, &S->tccgen_char_pointer_type, lbounds_section, |
| 713 | func_bound_offset, lbounds_section->data_offset); | 707 | S->func_bound_offset, lbounds_section->data_offset); |
| 714 | 708 | ||
| 715 | /* generate bound local allocation */ | 709 | /* generate bound local allocation */ |
| 716 | if (offset_modified) { | 710 | if (offset_modified) { |
| 717 | saved_ind = ind; | 711 | saved_ind = S->tccgen_ind; |
| 718 | ind = func_bound_ind; | 712 | S->tccgen_ind = S->func_bound_ind; |
| 719 | greloca(cur_text_section, sym_data, ind, R_AARCH64_ADR_GOT_PAGE, 0); | 713 | greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_AARCH64_ADR_GOT_PAGE, 0); |
| 720 | o(0x90000000 | 0); // adrp x0, #sym_data | 714 | o(S, 0x90000000 | 0); // adrp x0, #sym_data |
| 721 | greloca(cur_text_section, sym_data, ind, R_AARCH64_LD64_GOT_LO12_NC, 0); | 715 | greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_AARCH64_LD64_GOT_LO12_NC, 0); |
| 722 | o(0xf9400000 | 0 | (0 << 5)); // ld x0,[x0, #sym_data] | 716 | o(S, 0xf9400000 | 0 | (0 << 5)); // ld x0,[x0, #sym_data] |
| 723 | gen_bounds_call(TOK___bound_local_new); | 717 | gen_bounds_call(S, TOK___bound_local_new); |
| 724 | ind = saved_ind; | 718 | S->tccgen_ind = saved_ind; |
| 725 | } | 719 | } |
| 726 | 720 | ||
| 727 | /* generate bound check local freeing */ | 721 | /* generate bound check local freeing */ |
| 728 | o(0xf81f0fe0); /* str x0, [sp, #-16]! */ | 722 | o(S, 0xf81f0fe0); /* str x0, [sp, #-16]! */ |
| 729 | o(0x3c9f0fe0); /* str q0, [sp, #-16]! */ | 723 | o(S, 0x3c9f0fe0); /* str q0, [sp, #-16]! */ |
| 730 | greloca(cur_text_section, sym_data, ind, R_AARCH64_ADR_GOT_PAGE, 0); | 724 | greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_AARCH64_ADR_GOT_PAGE, 0); |
| 731 | o(0x90000000 | 0); // adrp x0, #sym_data | 725 | o(S, 0x90000000 | 0); // adrp x0, #sym_data |
| 732 | greloca(cur_text_section, sym_data, ind, R_AARCH64_LD64_GOT_LO12_NC, 0); | 726 | greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_AARCH64_LD64_GOT_LO12_NC, 0); |
| 733 | o(0xf9400000 | 0 | (0 << 5)); // ld x0,[x0, #sym_data] | 727 | o(S, 0xf9400000 | 0 | (0 << 5)); // ld x0,[x0, #sym_data] |
| 734 | gen_bounds_call(TOK___bound_local_delete); | 728 | gen_bounds_call(S, TOK___bound_local_delete); |
| 735 | o(0x3cc107e0); /* ldr q0, [sp], #16 */ | 729 | o(S, 0x3cc107e0); /* ldr q0, [sp], #16 */ |
| 736 | o(0xf84107e0); /* ldr x0, [sp], #16 */ | 730 | o(S, 0xf84107e0); /* ldr x0, [sp], #16 */ |
| 737 | } | 731 | } |
| 738 | #endif | 732 | #endif |
| 739 | 733 | ||
| @@ -970,7 +964,7 @@ static unsigned long arm64_pcs(int n, CType **type, unsigned long *a) · 230 unmodified lines | |||
| 970 | return stack; | 964 | return stack; |
| 971 | } | 965 | } |
| 972 | 966 | ||
| 973 | ST_FUNC void gfunc_call(int nb_args) | 967 | ST_FUNC void gfunc_call(TCCState *S, int nb_args) |
| 974 | { | 968 | { |
| 975 | CType *return_type; | 969 | CType *return_type; |
| 976 | CType **t; | 970 | CType **t; |
| @@ -979,28 +973,28 @@ ST_FUNC void gfunc_call(int nb_args) · 2 unmodified lines | |||
| 979 | int i; | 973 | int i; |
| 980 | 974 | ||
| 981 | #ifdef CONFIG_TCC_BCHECK | 975 | #ifdef CONFIG_TCC_BCHECK |
| 982 | if (tcc_state->do_bounds_check) | 976 | if (S->do_bounds_check) |
| 983 | gbound_args(nb_args); | 977 | gbound_args(S, nb_args); |
| 984 | #endif | 978 | #endif |
| 985 | 979 | ||
| 986 | return_type = &vtop[-nb_args].type.ref->type; | 980 | return_type = &S->tccgen_vtop[-nb_args].type.ref->type; |
| 987 | if ((return_type->t & VT_BTYPE) == VT_STRUCT) | 981 | if ((return_type->t & VT_BTYPE) == VT_STRUCT) |
| 988 | --nb_args; | 982 | --nb_args; |
| 989 | 983 | ||
| 990 | t = tcc_malloc((nb_args + 1) * sizeof(*t)); | 984 | t = tcc_malloc(S, (nb_args + 1) * sizeof(*t)); |
| 991 | a = tcc_malloc((nb_args + 1) * sizeof(*a)); | 985 | a = tcc_malloc(S, (nb_args + 1) * sizeof(*a)); |
| 992 | a1 = tcc_malloc((nb_args + 1) * sizeof(*a1)); | 986 | a1 = tcc_malloc(S, (nb_args + 1) * sizeof(*a1)); |
| 993 | 987 | ||
| 994 | t[0] = return_type; | 988 | t[0] = return_type; |
| 995 | for (i = 0; i < nb_args; i++) | 989 | for (i = 0; i < nb_args; i++) |
| 996 | t[nb_args - i] = &vtop[-i].type; | 990 | t[nb_args - i] = &S->tccgen_vtop[-i].type; |
| 997 | 991 | ||
| 998 | stack = arm64_pcs(nb_args, t, a); | 992 | stack = arm64_pcs(nb_args, t, a); |
| 999 | 993 | ||
| 1000 | // Allocate space for structs replaced by pointer: | 994 | // Allocate space for structs replaced by pointer: |
| 1001 | for (i = nb_args; i; i--) | 995 | for (i = nb_args; i; i--) |
| 1002 | if (a[i] & 1) { | 996 | if (a[i] & 1) { |
| 1003 | SValue *arg = &vtop[i - nb_args]; | 997 | SValue *arg = &S->tccgen_vtop[i - nb_args]; |
| 1004 | int align, size = type_size(&arg->type, &align); | 998 | int align, size = type_size(&arg->type, &align); |
| 1005 | assert((arg->type.t & VT_BTYPE) == VT_STRUCT); | 999 | assert((arg->type.t & VT_BTYPE) == VT_STRUCT); |
| 1006 | stack = (stack + align - 1) & -align; | 1000 | stack = (stack + align - 1) & -align; |
| @@ -1011,134 +1005,134 @@ ST_FUNC void gfunc_call(int nb_args) · 4 unmodified lines | |||
| 1011 | stack = (stack + 15) >> 4 << 4; | 1005 | stack = (stack + 15) >> 4 << 4; |
| 1012 | 1006 | ||
| 1013 | /* fetch cpu flag before generating any code */ | 1007 | /* fetch cpu flag before generating any code */ |
| 1014 | if ((vtop->r & VT_VALMASK) == VT_CMP) | 1008 | if ((S->tccgen_vtop->r & VT_VALMASK) == VT_CMP) |
| 1015 | gv(RC_INT); | 1009 | gv(S, RC_INT); |
| 1016 | 1010 | ||
| 1017 | if (stack >= 0x1000000) // 16Mb | 1011 | if (stack >= 0x1000000) // 16Mb |
| 1018 | tcc_error("stack size too big %lu", stack); | 1012 | tcc_error(S, "stack size too big %lu", stack); |
| 1019 | if (stack & 0xfff) | 1013 | if (stack & 0xfff) |
| 1020 | o(0xd10003ff | (stack & 0xfff) << 10); // sub sp,sp,#(n) | 1014 | o(S, 0xd10003ff | (stack & 0xfff) << 10); // sub sp,sp,#(n) |
| 1021 | if (stack >> 12) | 1015 | if (stack >> 12) |
| 1022 | o(0xd14003ff | (stack >> 12) << 10); | 1016 | o(S, 0xd14003ff | (stack >> 12) << 10); |
| 1023 | 1017 | ||
| 1024 | // First pass: set all values on stack | 1018 | // First pass: set all values on stack |
| 1025 | for (i = nb_args; i; i--) { | 1019 | for (i = nb_args; i; i--) { |
| 1026 | vpushv(vtop - nb_args + i); | 1020 | vpushv(S, S->tccgen_vtop - nb_args + i); |
| 1027 | 1021 | ||
| 1028 | if (a[i] & 1) { | 1022 | if (a[i] & 1) { |
| 1029 | // struct replaced by pointer | 1023 | // struct replaced by pointer |
| 1030 | int r = get_reg(RC_INT); | 1024 | int r = get_reg(S, RC_INT); |
| 1031 | arm64_spoff(intr(r), a1[i]); | 1025 | arm64_spoff(S, intr(S, r), a1[i]); |
| 1032 | vset(&vtop->type, r | VT_LVAL, 0); | 1026 | vset(S, &S->tccgen_vtop->type, r | VT_LVAL, 0); |
| 1033 | vswap(); | 1027 | vswap(S); |
| 1034 | vstore(); | 1028 | vstore(S); |
| 1035 | if (a[i] >= 32) { | 1029 | if (a[i] >= 32) { |
| 1036 | // pointer on stack | 1030 | // pointer on stack |
| 1037 | r = get_reg(RC_INT); | 1031 | r = get_reg(S, RC_INT); |
| 1038 | arm64_spoff(intr(r), a1[i]); | 1032 | arm64_spoff(S, intr(S, r), a1[i]); |
| 1039 | arm64_strx(3, intr(r), 31, (a[i] - 32) >> 1 << 1); | 1033 | arm64_strx(S, 3, intr(S, r), 31, (a[i] - 32) >> 1 << 1); |
| 1040 | } | 1034 | } |
| 1041 | } | 1035 | } |
| 1042 | else if (a[i] >= 32) { | 1036 | else if (a[i] >= 32) { |
| 1043 | // value on stack | 1037 | // value on stack |
| 1044 | if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) { | 1038 | if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_STRUCT) { |
| 1045 | int r = get_reg(RC_INT); | 1039 | int r = get_reg(S, RC_INT); |
| 1046 | arm64_spoff(intr(r), a[i] - 32); | 1040 | arm64_spoff(S, intr(S, r), a[i] - 32); |
| 1047 | vset(&vtop->type, r | VT_LVAL, 0); | 1041 | vset(S, &S->tccgen_vtop->type, r | VT_LVAL, 0); |
| 1048 | vswap(); | 1042 | vswap(S); |
| 1049 | vstore(); | 1043 | vstore(S); |
| 1050 | } | 1044 | } |
| 1051 | else if (is_float(vtop->type.t)) { | 1045 | else if (is_float(S->tccgen_vtop->type.t)) { |
| 1052 | gv(RC_FLOAT); | 1046 | gv(S, RC_FLOAT); |
| 1053 | arm64_strv(arm64_type_size(vtop[0].type.t), | 1047 | arm64_strv(S, arm64_type_size(S->tccgen_vtop[0].type.t), |
| 1054 | fltr(vtop[0].r), 31, a[i] - 32); | 1048 | fltr(S->tccgen_vtop[0].r), 31, a[i] - 32); |
| 1055 | } | 1049 | } |
| 1056 | else { | 1050 | else { |
| 1057 | gv(RC_INT); | 1051 | gv(S, RC_INT); |
| 1058 | arm64_strx(arm64_type_size(vtop[0].type.t), | 1052 | arm64_strx(S, arm64_type_size(S->tccgen_vtop[0].type.t), |
| 1059 | intr(vtop[0].r), 31, a[i] - 32); | 1053 | intr(S, S->tccgen_vtop[0].r), 31, a[i] - 32); |
| 1060 | } | 1054 | } |
| 1061 | } | 1055 | } |
| 1062 | 1056 | ||
| 1063 | --vtop; | 1057 | --S->tccgen_vtop; |
| 1064 | } | 1058 | } |
| 1065 | 1059 | ||
| 1066 | // Second pass: assign values to registers | 1060 | // Second pass: assign values to registers |
| 1067 | for (i = nb_args; i; i--, vtop--) { | 1061 | for (i = nb_args; i; i--, S->tccgen_vtop--) { |
| 1068 | if (a[i] < 16 && !(a[i] & 1)) { | 1062 | if (a[i] < 16 && !(a[i] & 1)) { |
| 1069 | // value in general-purpose registers | 1063 | // value in general-purpose registers |
| 1070 | if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) { | 1064 | if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_STRUCT) { |
| 1071 | int align, size = type_size(&vtop->type, &align); | 1065 | int align, size = type_size(&S->tccgen_vtop->type, &align); |
| 1072 | if (size) { | 1066 | if (size) { |
| 1073 | vtop->type.t = VT_PTR; | 1067 | S->tccgen_vtop->type.t = VT_PTR; |
| 1074 | gaddrof(); | 1068 | gaddrof(S); |
| 1075 | gv(RC_R(a[i] / 2)); | 1069 | gv(S, RC_R(a[i] / 2)); |
| 1076 | arm64_ldrs(a[i] / 2, size); | 1070 | arm64_ldrs(S, a[i] / 2, size); |
| 1077 | } | 1071 | } |
| 1078 | } | 1072 | } |
| 1079 | else | 1073 | else |
| 1080 | gv(RC_R(a[i] / 2)); | 1074 | gv(S, RC_R(a[i] / 2)); |
| 1081 | } | 1075 | } |
| 1082 | else if (a[i] < 16) | 1076 | else if (a[i] < 16) |
| 1083 | // struct replaced by pointer in register | 1077 | // struct replaced by pointer in register |
| 1084 | arm64_spoff(a[i] / 2, a1[i]); | 1078 | arm64_spoff(S, a[i] / 2, a1[i]); |
| 1085 | else if (a[i] < 32) { | 1079 | else if (a[i] < 32) { |
| 1086 | // value in floating-point registers | 1080 | // value in floating-point registers |
| 1087 | if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) { | 1081 | if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_STRUCT) { |
| 1088 | uint32_t j, sz, n = arm64_hfa(&vtop->type, &sz); | 1082 | uint32_t j, sz, n = arm64_hfa(&S->tccgen_vtop->type, &sz); |
| 1089 | vtop->type.t = VT_PTR; | 1083 | S->tccgen_vtop->type.t = VT_PTR; |
| 1090 | gaddrof(); | 1084 | gaddrof(S); |
| 1091 | gv(RC_R30); | 1085 | gv(S, RC_R30); |
| 1092 | for (j = 0; j < n; j++) | 1086 | for (j = 0; j < n; j++) |
| 1093 | o(0x3d4003c0 | | 1087 | o(S, 0x3d4003c0 | |
| 1094 | (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 | | 1088 | (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 | |
| 1095 | (a[i] / 2 - 8 + j) | | 1089 | (a[i] / 2 - 8 + j) | |
| 1096 | j << 10); // ldr ([sdq])(*),[x30,#(j * sz)] | 1090 | j << 10); // ldr ([sdq])(*),[x30,#(j * sz)] |
| 1097 | } | 1091 | } |
| 1098 | else | 1092 | else |
| 1099 | gv(RC_F(a[i] / 2 - 8)); | 1093 | gv(S, RC_F(a[i] / 2 - 8)); |
| 1100 | } | 1094 | } |
| 1101 | } | 1095 | } |
| 1102 | 1096 | ||
| 1103 | if ((return_type->t & VT_BTYPE) == VT_STRUCT) { | 1097 | if ((return_type->t & VT_BTYPE) == VT_STRUCT) { |
| 1104 | if (a[0] == 1) { | 1098 | if (a[0] == 1) { |
| 1105 | // indirect return: set x8 and discard the stack value | 1099 | // indirect return: set x8 and discard the stack value |
| 1106 | gv(RC_R(8)); | 1100 | gv(S, RC_R(8)); |
| 1107 | --vtop; | 1101 | --S->tccgen_vtop; |
| 1108 | } | 1102 | } |
| 1109 | else | 1103 | else |
| 1110 | // return in registers: keep the address for after the call | 1104 | // return in registers: keep the address for after the call |
| 1111 | vswap(); | 1105 | vswap(S); |
| 1112 | } | 1106 | } |
| 1113 | 1107 | ||
| 1114 | save_regs(0); | 1108 | save_regs(S, 0); |
| 1115 | arm64_gen_bl_or_b(0); | 1109 | arm64_gen_bl_or_b(S, 0); |
| 1116 | --vtop; | 1110 | --S->tccgen_vtop; |
| 1117 | if (stack & 0xfff) | 1111 | if (stack & 0xfff) |
| 1118 | o(0x910003ff | (stack & 0xfff) << 10); // add sp,sp,#(n) | 1112 | o(S, 0x910003ff | (stack & 0xfff) << 10); // add sp,sp,#(n) |
| 1119 | if (stack >> 12) | 1113 | if (stack >> 12) |
| 1120 | o(0x914003ff | (stack >> 12) << 10); | 1114 | o(S, 0x914003ff | (stack >> 12) << 10); |
| 1121 | 1115 | ||
| 1122 | { | 1116 | { |
| 1123 | int rt = return_type->t; | 1117 | int rt = return_type->t; |
| 1124 | int bt = rt & VT_BTYPE; | 1118 | int bt = rt & VT_BTYPE; |
| 1125 | if (bt == VT_STRUCT && !(a[0] & 1)) { | 1119 | if (bt == VT_STRUCT && !(a[0] & 1)) { |
| 1126 | // A struct was returned in registers, so write it out: | 1120 | // A struct was returned in registers, so write it out: |
| 1127 | gv(RC_R(8)); | 1121 | gv(S, RC_R(8)); |
| 1128 | --vtop; | 1122 | --S->tccgen_vtop; |
| 1129 | if (a[0] == 0) { | 1123 | if (a[0] == 0) { |
| 1130 | int align, size = type_size(return_type, &align); | 1124 | int align, size = type_size(return_type, &align); |
| 1131 | assert(size <= 16); | 1125 | assert(size <= 16); |
| 1132 | if (size > 8) | 1126 | if (size > 8) |
| 1133 | o(0xa9000500); // stp x0,x1,[x8] | 1127 | o(S, 0xa9000500); // stp x0,x1,[x8] |
| 1134 | else if (size) | 1128 | else if (size) |
| 1135 | arm64_strx(size > 4 ? 3 : size > 2 ? 2 : size > 1, 0, 8, 0); | 1129 | arm64_strx(S, size > 4 ? 3 : size > 2 ? 2 : size > 1, 0, 8, 0); |
| 1136 | 1130 | ||
| 1137 | } | 1131 | } |
| 1138 | else if (a[0] == 16) { | 1132 | else if (a[0] == 16) { |
| 1139 | uint32_t j, sz, n = arm64_hfa(return_type, &sz); | 1133 | uint32_t j, sz, n = arm64_hfa(return_type, &sz); |
| 1140 | for (j = 0; j < n; j++) | 1134 | for (j = 0; j < n; j++) |
| 1141 | o(0x3d000100 | | 1135 | o(S, 0x3d000100 | |
| 1142 | (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 | | 1136 | (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 | |
| 1143 | (a[i] / 2 - 8 + j) | | 1137 | (a[i] / 2 - 8 + j) | |
| 1144 | j << 10); // str ([sdq])(*),[x8,#(j * sz)] | 1138 | j << 10); // str ([sdq])(*),[x8,#(j * sz)] |
| @@ -1146,9 +1140,9 @@ ST_FUNC void gfunc_call(int nb_args) · 1 unmodified line | |||
| 1146 | } | 1140 | } |
| 1147 | } | 1141 | } |
| 1148 | 1142 | ||
| 1149 | tcc_free(a1); | 1143 | tcc_free(S, a1); |
| 1150 | tcc_free(a); | 1144 | tcc_free(S, a); |
| 1151 | tcc_free(t); | 1145 | tcc_free(S, t); |
| 1152 | } | 1146 | } |
| 1153 | 1147 | ||
| 1154 | static unsigned long arm64_func_va_list_stack; | 1148 | static unsigned long arm64_func_va_list_stack; |
| @@ -1156,7 +1150,7 @@ static int arm64_func_va_list_gr_offs; · 1 unmodified line | |||
| 1156 | static int arm64_func_va_list_vr_offs; | 1150 | static int arm64_func_va_list_vr_offs; |
| 1157 | static int arm64_func_sub_sp_offset; | 1151 | static int arm64_func_sub_sp_offset; |
| 1158 | 1152 | ||
| 1159 | ST_FUNC void gfunc_prolog(Sym *func_sym) | 1153 | ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym) |
| 1160 | { | 1154 | { |
| 1161 | CType *func_type = &func_sym->type; | 1155 | CType *func_type = &func_sym->type; |
| 1162 | int n = 0; | 1156 | int n = 0; |
| @@ -1165,28 +1159,28 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 2 unmodified lines | |||
| 1165 | CType **t; | 1159 | CType **t; |
| 1166 | unsigned long *a; | 1160 | unsigned long *a; |
| 1167 | 1161 | ||
| 1168 | func_vc = 144; // offset of where x8 is stored | 1162 | S->tccgen_func_vc = 144; // offset of where x8 is stored |
| 1169 | 1163 | ||
| 1170 | for (sym = func_type->ref; sym; sym = sym->next) | 1164 | for (sym = func_type->ref; sym; sym = sym->next) |
| 1171 | ++n; | 1165 | ++n; |
| 1172 | t = n ? tcc_malloc(n * sizeof(*t)) : NULL; | 1166 | t = n ? tcc_malloc(S, n * sizeof(*t)) : NULL; |
| 1173 | a = n ? tcc_malloc(n * sizeof(*a)) : NULL; | 1167 | a = n ? tcc_malloc(S, n * sizeof(*a)) : NULL; |
| 1174 | 1168 | ||
| 1175 | for (sym = func_type->ref; sym; sym = sym->next) | 1169 | for (sym = func_type->ref; sym; sym = sym->next) |
| 1176 | t[i++] = &sym->type; | 1170 | t[i++] = &sym->type; |
| 1177 | 1171 | ||
| 1178 | arm64_func_va_list_stack = arm64_pcs(n - 1, t, a); | 1172 | arm64_func_va_list_stack = arm64_pcs(n - 1, t, a); |
| 1179 | 1173 | ||
| 1180 | o(0xa9b27bfd); // stp x29,x30,[sp,#-224]! | 1174 | o(S, 0xa9b27bfd); // stp x29,x30,[sp,#-224]! |
| 1181 | o(0xad0087e0); // stp q0,q1,[sp,#16] | 1175 | o(S, 0xad0087e0); // stp q0,q1,[sp,#16] |
| 1182 | o(0xad018fe2); // stp q2,q3,[sp,#48] | 1176 | o(S, 0xad018fe2); // stp q2,q3,[sp,#48] |
| 1183 | o(0xad0297e4); // stp q4,q5,[sp,#80] | 1177 | o(S, 0xad0297e4); // stp q4,q5,[sp,#80] |
| 1184 | o(0xad039fe6); // stp q6,q7,[sp,#112] | 1178 | o(S, 0xad039fe6); // stp q6,q7,[sp,#112] |
| 1185 | o(0xa90923e8); // stp x8,x8,[sp,#144] | 1179 | o(S, 0xa90923e8); // stp x8,x8,[sp,#144] |
| 1186 | o(0xa90a07e0); // stp x0,x1,[sp,#160] | 1180 | o(S, 0xa90a07e0); // stp x0,x1,[sp,#160] |
| 1187 | o(0xa90b0fe2); // stp x2,x3,[sp,#176] | 1181 | o(S, 0xa90b0fe2); // stp x2,x3,[sp,#176] |
| 1188 | o(0xa90c17e4); // stp x4,x5,[sp,#192] | 1182 | o(S, 0xa90c17e4); // stp x4,x5,[sp,#192] |
| 1189 | o(0xa90d1fe6); // stp x6,x7,[sp,#208] | 1183 | o(S, 0xa90d1fe6); // stp x6,x7,[sp,#208] |
| 1190 | 1184 | ||
| 1191 | arm64_func_va_list_gr_offs = -64; | 1185 | arm64_func_va_list_gr_offs = -64; |
| 1192 | arm64_func_va_list_vr_offs = -128; | 1186 | arm64_func_va_list_vr_offs = -128; |
| @@ -1195,7 +1189,7 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 2 unmodified lines | |||
| 1195 | int off = (a[i] < 16 ? 160 + a[i] / 2 * 8 : | 1189 | int off = (a[i] < 16 ? 160 + a[i] / 2 * 8 : |
| 1196 | a[i] < 32 ? 16 + (a[i] - 16) / 2 * 16 : | 1190 | a[i] < 32 ? 16 + (a[i] - 16) / 2 * 16 : |
| 1197 | 224 + ((a[i] - 32) >> 1 << 1)); | 1191 | 224 + ((a[i] - 32) >> 1 << 1)); |
| 1198 | sym_push(sym->v & ~SYM_FIELD, &sym->type, | 1192 | sym_push(S, sym->v & ~SYM_FIELD, &sym->type, |
| 1199 | (a[i] & 1 ? VT_LLOCAL : VT_LOCAL) | VT_LVAL, | 1193 | (a[i] & 1 ? VT_LLOCAL : VT_LOCAL) | VT_LVAL, |
| 1200 | off); | 1194 | off); |
| 1201 | 1195 | ||
| @@ -1215,65 +1209,65 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 13 unmodified lines | |||
| 1215 | uint32_t j, sz, k = arm64_hfa(&sym->type, &sz); | 1209 | uint32_t j, sz, k = arm64_hfa(&sym->type, &sz); |
| 1216 | if (sz < 16) | 1210 | if (sz < 16) |
| 1217 | for (j = 0; j < k; j++) { | 1211 | for (j = 0; j < k; j++) { |
| 1218 | o(0x3d0003e0 | -(sz & 8) << 27 | (sz & 4) << 29 | | 1212 | o(S, 0x3d0003e0 | -(sz & 8) << 27 | (sz & 4) << 29 | |
| 1219 | ((a[i] - 16) / 2 + j) | (off / sz + j) << 10); | 1213 | ((a[i] - 16) / 2 + j) | (off / sz + j) << 10); |
| 1220 | // str ([sdq])(*),[sp,#(j * sz)] | 1214 | // str ([sdq])(*),[sp,#(j * sz)] |
| 1221 | } | 1215 | } |
| 1222 | } | 1216 | } |
| 1223 | } | 1217 | } |
| 1224 | 1218 | ||
| 1225 | tcc_free(a); | 1219 | tcc_free(S, a); |
| 1226 | tcc_free(t); | 1220 | tcc_free(S, t); |
| 1227 | 1221 | ||
| 1228 | o(0x910003fd); // mov x29,sp | 1222 | o(S, 0x910003fd); // mov x29,sp |
| 1229 | arm64_func_sub_sp_offset = ind; | 1223 | arm64_func_sub_sp_offset = S->tccgen_ind; |
| 1230 | // In gfunc_epilog these will be replaced with code to decrement SP: | 1224 | // In gfunc_epilog these will be replaced with code to decrement SP: |
| 1231 | o(0xd503201f); // nop | 1225 | o(S, 0xd503201f); // nop |
| 1232 | o(0xd503201f); // nop | 1226 | o(S, 0xd503201f); // nop |
| 1233 | loc = 0; | 1227 | S->tccgen_loc = 0; |
| 1234 | #ifdef CONFIG_TCC_BCHECK | 1228 | #ifdef CONFIG_TCC_BCHECK |
| 1235 | if (tcc_state->do_bounds_check) | 1229 | if (S->do_bounds_check) |
| 1236 | gen_bounds_prolog(); | 1230 | gen_bounds_prolog(S); |
| 1237 | #endif | 1231 | #endif |
| 1238 | } | 1232 | } |
| 1239 | 1233 | ||
| 1240 | ST_FUNC void gen_va_start(void) | 1234 | ST_FUNC void gen_va_start(TCCState *S) |
| 1241 | { | 1235 | { |
| 1242 | int r; | 1236 | int r; |
| 1243 | --vtop; // we don't need the "arg" | 1237 | --S->tccgen_vtop; // we don't need the "arg" |
| 1244 | gaddrof(); | 1238 | gaddrof(S); |
| 1245 | r = intr(gv(RC_INT)); | 1239 | r = intr(S, gv(S, RC_INT)); |
| 1246 | 1240 | ||
| 1247 | if (arm64_func_va_list_stack) { | 1241 | if (arm64_func_va_list_stack) { |
| 1248 | //xx could use add (immediate) here | 1242 | //xx could use add (immediate) here |
| 1249 | arm64_movimm(30, arm64_func_va_list_stack + 224); | 1243 | arm64_movimm(S, 30, arm64_func_va_list_stack + 224); |
| 1250 | o(0x8b1e03be); // add x30,x29,x30 | 1244 | o(S, 0x8b1e03be); // add x30,x29,x30 |
| 1251 | } | 1245 | } |
| 1252 | else | 1246 | else |
| 1253 | o(0x910383be); // add x30,x29,#224 | 1247 | o(S, 0x910383be); // add x30,x29,#224 |
| 1254 | o(0xf900001e | r << 5); // str x30,[x(r)] | 1248 | o(S, 0xf900001e | r << 5); // str x30,[x(r)] |
| 1255 | 1249 | ||
| 1256 | if (arm64_func_va_list_gr_offs) { | 1250 | if (arm64_func_va_list_gr_offs) { |
| 1257 | if (arm64_func_va_list_stack) | 1251 | if (arm64_func_va_list_stack) |
| 1258 | o(0x910383be); // add x30,x29,#224 | 1252 | o(S, 0x910383be); // add x30,x29,#224 |
| 1259 | o(0xf900041e | r << 5); // str x30,[x(r),#8] | 1253 | o(S, 0xf900041e | r << 5); // str x30,[x(r),#8] |
| 1260 | } | 1254 | } |
| 1261 | 1255 | ||
| 1262 | if (arm64_func_va_list_vr_offs) { | 1256 | if (arm64_func_va_list_vr_offs) { |
| 1263 | o(0x910243be); // add x30,x29,#144 | 1257 | o(S, 0x910243be); // add x30,x29,#144 |
| 1264 | o(0xf900081e | r << 5); // str x30,[x(r),#16] | 1258 | o(S, 0xf900081e | r << 5); // str x30,[x(r),#16] |
| 1265 | } | 1259 | } |
| 1266 | 1260 | ||
| 1267 | arm64_movimm(30, arm64_func_va_list_gr_offs); | 1261 | arm64_movimm(S, 30, arm64_func_va_list_gr_offs); |
| 1268 | o(0xb900181e | r << 5); // str w30,[x(r),#24] | 1262 | o(S, 0xb900181e | r << 5); // str w30,[x(r),#24] |
| 1269 | 1263 | ||
| 1270 | arm64_movimm(30, arm64_func_va_list_vr_offs); | 1264 | arm64_movimm(S, 30, arm64_func_va_list_vr_offs); |
| 1271 | o(0xb9001c1e | r << 5); // str w30,[x(r),#28] | 1265 | o(S, 0xb9001c1e | r << 5); // str w30,[x(r),#28] |
| 1272 | 1266 | ||
| 1273 | --vtop; | 1267 | --S->tccgen_vtop; |
| 1274 | } | 1268 | } |
| 1275 | 1269 | ||
| 1276 | ST_FUNC void gen_va_arg(CType *t) | 1270 | ST_FUNC void gen_va_arg(TCCState *S, CType *t) |
| 1277 | { | 1271 | { |
| 1278 | int align, size = type_size(t, &align); | 1272 | int align, size = type_size(t, &align); |
| 1279 | unsigned fsize, hfa = arm64_hfa(t, &fsize); | 1273 | unsigned fsize, hfa = arm64_hfa(t, &fsize); |
| @@ -1284,69 +1278,69 @@ ST_FUNC void gen_va_arg(CType *t) · 4 unmodified lines | |||
| 1284 | fsize = size; | 1278 | fsize = size; |
| 1285 | } | 1279 | } |
| 1286 | 1280 | ||
| 1287 | gaddrof(); | 1281 | gaddrof(S); |
| 1288 | r0 = intr(gv(RC_INT)); | 1282 | r0 = intr(S, gv(S, RC_INT)); |
| 1289 | r1 = get_reg(RC_INT); | 1283 | r1 = get_reg(S, RC_INT); |
| 1290 | vtop[0].r = r1 | VT_LVAL; | 1284 | S->tccgen_vtop[0].r = r1 | VT_LVAL; |
| 1291 | r1 = intr(r1); | 1285 | r1 = intr(S, r1); |
| 1292 | 1286 | ||
| 1293 | if (!hfa) { | 1287 | if (!hfa) { |
| 1294 | uint32_t n = size > 16 ? 8 : (size + 7) & -8; | 1288 | uint32_t n = size > 16 ? 8 : (size + 7) & -8; |
| 1295 | o(0xb940181e | r0 << 5); // ldr w30,[x(r0),#24] // __gr_offs | 1289 | o(S, 0xb940181e | r0 << 5); // ldr w30,[x(r0),#24] // __gr_offs |
| 1296 | if (align == 16) { | 1290 | if (align == 16) { |
| 1297 | assert(0); // this path untested but needed for __uint128_t | 1291 | assert(0); // this path untested but needed for __uint128_t |
| 1298 | o(0x11003fde); // add w30,w30,#15 | 1292 | o(S, 0x11003fde); // add w30,w30,#15 |
| 1299 | o(0x121c6fde); // and w30,w30,#-16 | 1293 | o(S, 0x121c6fde); // and w30,w30,#-16 |
| 1300 | } | 1294 | } |
| 1301 | o(0x310003c0 | r1 | n << 10); // adds w(r1),w30,#(n) | 1295 | o(S, 0x310003c0 | r1 | n << 10); // adds w(r1),w30,#(n) |
| 1302 | o(0x540000ad); // b.le .+20 | 1296 | o(S, 0x540000ad); // b.le .+20 |
| 1303 | o(0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack | 1297 | o(S, 0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack |
| 1304 | o(0x9100001e | r1 << 5 | n << 10); // add x30,x(r1),#(n) | 1298 | o(S, 0x9100001e | r1 << 5 | n << 10); // add x30,x(r1),#(n) |
| 1305 | o(0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack | 1299 | o(S, 0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack |
| 1306 | o(0x14000004); // b .+16 | 1300 | o(S, 0x14000004); // b .+16 |
| 1307 | o(0xb9001800 | r1 | r0 << 5); // str w(r1),[x(r0),#24] // __gr_offs | 1301 | o(S, 0xb9001800 | r1 | r0 << 5); // str w(r1),[x(r0),#24] // __gr_offs |
| 1308 | o(0xf9400400 | r1 | r0 << 5); // ldr x(r1),[x(r0),#8] // __gr_top | 1302 | o(S, 0xf9400400 | r1 | r0 << 5); // ldr x(r1),[x(r0),#8] // __gr_top |
| 1309 | o(0x8b3ec000 | r1 | r1 << 5); // add x(r1),x(r1),w30,sxtw | 1303 | o(S, 0x8b3ec000 | r1 | r1 << 5); // add x(r1),x(r1),w30,sxtw |
| 1310 | if (size > 16) | 1304 | if (size > 16) |
| 1311 | o(0xf9400000 | r1 | r1 << 5); // ldr x(r1),[x(r1)] | 1305 | o(S, 0xf9400000 | r1 | r1 << 5); // ldr x(r1),[x(r1)] |
| 1312 | } | 1306 | } |
| 1313 | else { | 1307 | else { |
| 1314 | uint32_t rsz = hfa << 4; | 1308 | uint32_t rsz = hfa << 4; |
| 1315 | uint32_t ssz = (size + 7) & -(uint32_t)8; | 1309 | uint32_t ssz = (size + 7) & -(uint32_t)8; |
| 1316 | uint32_t b1, b2; | 1310 | uint32_t b1, b2; |
| 1317 | o(0xb9401c1e | r0 << 5); // ldr w30,[x(r0),#28] // __vr_offs | 1311 | o(S, 0xb9401c1e | r0 << 5); // ldr w30,[x(r0),#28] // __vr_offs |
| 1318 | o(0x310003c0 | r1 | rsz << 10); // adds w(r1),w30,#(rsz) | 1312 | o(S, 0x310003c0 | r1 | rsz << 10); // adds w(r1),w30,#(rsz) |
| 1319 | b1 = ind; o(0x5400000d); // b.le lab1 | 1313 | b1 = S->tccgen_ind; o(S, 0x5400000d); // b.le lab1 |
| 1320 | o(0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack | 1314 | o(S, 0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack |
| 1321 | if (fsize == 16) { | 1315 | if (fsize == 16) { |
| 1322 | o(0x91003c00 | r1 | r1 << 5); // add x(r1),x(r1),#15 | 1316 | o(S, 0x91003c00 | r1 | r1 << 5); // add x(r1),x(r1),#15 |
| 1323 | o(0x927cec00 | r1 | r1 << 5); // and x(r1),x(r1),#-16 | 1317 | o(S, 0x927cec00 | r1 | r1 << 5); // and x(r1),x(r1),#-16 |
| 1324 | } | 1318 | } |
| 1325 | o(0x9100001e | r1 << 5 | ssz << 10); // add x30,x(r1),#(ssz) | 1319 | o(S, 0x9100001e | r1 << 5 | ssz << 10); // add x30,x(r1),#(ssz) |
| 1326 | o(0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack | 1320 | o(S, 0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack |
| 1327 | b2 = ind; o(0x14000000); // b lab2 | 1321 | b2 = S->tccgen_ind; o(S, 0x14000000); // b lab2 |
| 1328 | // lab1: | 1322 | // lab1: |
| 1329 | write32le(cur_text_section->data + b1, 0x5400000d | (ind - b1) << 3); | 1323 | write32le(cur_text_section->data + b1, 0x5400000d | (S->tccgen_ind - b1) << 3); |
| 1330 | o(0xb9001c00 | r1 | r0 << 5); // str w(r1),[x(r0),#28] // __vr_offs | 1324 | o(S, 0xb9001c00 | r1 | r0 << 5); // str w(r1),[x(r0),#28] // __vr_offs |
| 1331 | o(0xf9400800 | r1 | r0 << 5); // ldr x(r1),[x(r0),#16] // __vr_top | 1325 | o(S, 0xf9400800 | r1 | r0 << 5); // ldr x(r1),[x(r0),#16] // __vr_top |
| 1332 | if (hfa == 1 || fsize == 16) | 1326 | if (hfa == 1 || fsize == 16) |
| 1333 | o(0x8b3ec000 | r1 | r1 << 5); // add x(r1),x(r1),w30,sxtw | 1327 | o(S, 0x8b3ec000 | r1 | r1 << 5); // add x(r1),x(r1),w30,sxtw |
| 1334 | else { | 1328 | else { |
| 1335 | // We need to change the layout of this HFA. | 1329 | // We need to change the layout of this HFA. |
| 1336 | // Get some space on the stack using global variable "loc": | 1330 | // Get some space on the stack using global variable "loc": |
| 1337 | loc = (loc - size) & -(uint32_t)align; | 1331 | S->tccgen_loc = (S->tccgen_loc - size) & -(uint32_t)align; |
| 1338 | o(0x8b3ec000 | 30 | r1 << 5); // add x30,x(r1),w30,sxtw | 1332 | o(S, 0x8b3ec000 | 30 | r1 << 5); // add x30,x(r1),w30,sxtw |
| 1339 | arm64_movimm(r1, loc); | 1333 | arm64_movimm(S, r1, S->tccgen_loc); |
| 1340 | o(0x8b0003a0 | r1 | r1 << 16); // add x(r1),x29,x(r1) | 1334 | o(S, 0x8b0003a0 | r1 | r1 << 16); // add x(r1),x29,x(r1) |
| 1341 | o(0x4c402bdc | (uint32_t)fsize << 7 | | 1335 | o(S, 0x4c402bdc | (uint32_t)fsize << 7 | |
| 1342 | (uint32_t)(hfa == 2) << 15 | | 1336 | (uint32_t)(hfa == 2) << 15 | |
| 1343 | (uint32_t)(hfa == 3) << 14); // ld1 {v28.(4s|2d),...},[x30] | 1337 | (uint32_t)(hfa == 3) << 14); // ld1 {v28.(4s|2d),...},[x30] |
| 1344 | o(0x0d00801c | r1 << 5 | (fsize == 8) << 10 | | 1338 | o(S, 0x0d00801c | r1 << 5 | (fsize == 8) << 10 | |
| 1345 | (uint32_t)(hfa != 2) << 13 | | 1339 | (uint32_t)(hfa != 2) << 13 | |
| 1346 | (uint32_t)(hfa != 3) << 21); // st(hfa) {v28.(s|d),...}[0],[x(r1)] | 1340 | (uint32_t)(hfa != 3) << 21); // st(hfa) {v28.(s|d),...}[0],[x(r1)] |
| 1347 | } | 1341 | } |
| 1348 | // lab2: | 1342 | // lab2: |
| 1349 | write32le(cur_text_section->data + b2, 0x14000000 | (ind - b2) >> 2); | 1343 | write32le(cur_text_section->data + b2, 0x14000000 | (S->tccgen_ind - b2) >> 2); |
| 1350 | } | 1344 | } |
| 1351 | } | 1345 | } |
| 1352 | 1346 | ||
| @@ -1356,7 +1350,7 @@ ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, · 3 unmodified lines | |||
| 1356 | return 0; | 1350 | return 0; |
| 1357 | } | 1351 | } |
| 1358 | 1352 | ||
| 1359 | ST_FUNC void gfunc_return(CType *func_type) | 1353 | ST_FUNC void gfunc_return(TCCState *S, CType *func_type) |
| 1360 | { | 1354 | { |
| 1361 | CType *t = func_type; | 1355 | CType *t = func_type; |
| 1362 | unsigned long a; | 1356 | unsigned long a; |
| @@ -1368,52 +1362,52 @@ ST_FUNC void gfunc_return(CType *func_type) · 5 unmodified lines | |||
| 1368 | case 0: | 1362 | case 0: |
| 1369 | if ((func_type->t & VT_BTYPE) == VT_STRUCT) { | 1363 | if ((func_type->t & VT_BTYPE) == VT_STRUCT) { |
| 1370 | int align, size = type_size(func_type, &align); | 1364 | int align, size = type_size(func_type, &align); |
| 1371 | gaddrof(); | 1365 | gaddrof(S); |
| 1372 | gv(RC_R(0)); | 1366 | gv(S, RC_R(0)); |
| 1373 | arm64_ldrs(0, size); | 1367 | arm64_ldrs(S, 0, size); |
| 1374 | } | 1368 | } |
| 1375 | else | 1369 | else |
| 1376 | gv(RC_IRET); | 1370 | gv(S, RC_IRET); |
| 1377 | break; | 1371 | break; |
| 1378 | case 1: { | 1372 | case 1: { |
| 1379 | CType type = *func_type; | 1373 | CType type = *func_type; |
| 1380 | mk_pointer(&type); | 1374 | mk_pointer(S, &type); |
| 1381 | vset(&type, VT_LOCAL | VT_LVAL, func_vc); | 1375 | vset(S, &type, VT_LOCAL | VT_LVAL, S->tccgen_func_vc); |
| 1382 | indir(); | 1376 | indir(S); |
| 1383 | vswap(); | 1377 | vswap(S); |
| 1384 | vstore(); | 1378 | vstore(S); |
| 1385 | break; | 1379 | break; |
| 1386 | } | 1380 | } |
| 1387 | case 16: | 1381 | case 16: |
| 1388 | if ((func_type->t & VT_BTYPE) == VT_STRUCT) { | 1382 | if ((func_type->t & VT_BTYPE) == VT_STRUCT) { |
| 1389 | uint32_t j, sz, n = arm64_hfa(&vtop->type, &sz); | 1383 | uint32_t j, sz, n = arm64_hfa(&S->tccgen_vtop->type, &sz); |
| 1390 | gaddrof(); | 1384 | gaddrof(S); |
| 1391 | gv(RC_R(0)); | 1385 | gv(S, RC_R(0)); |
| 1392 | for (j = 0; j < n; j++) | 1386 | for (j = 0; j < n; j++) |
| 1393 | o(0x3d400000 | | 1387 | o(S, 0x3d400000 | |
| 1394 | (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 | | 1388 | (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 | |
| 1395 | j | j << 10); // ldr ([sdq])(*),[x0,#(j * sz)] | 1389 | j | j << 10); // ldr ([sdq])(*),[x0,#(j * sz)] |
| 1396 | } | 1390 | } |
| 1397 | else | 1391 | else |
| 1398 | gv(RC_FRET); | 1392 | gv(S, RC_FRET); |
| 1399 | break; | 1393 | break; |
| 1400 | default: | 1394 | default: |
| 1401 | assert(0); | 1395 | assert(0); |
| 1402 | } | 1396 | } |
| 1403 | vtop--; | 1397 | S->tccgen_vtop--; |
| 1404 | } | 1398 | } |
| 1405 | 1399 | ||
| 1406 | ST_FUNC void gfunc_epilog(void) | 1400 | ST_FUNC void gfunc_epilog(TCCState *S) |
| 1407 | { | 1401 | { |
| 1408 | #ifdef CONFIG_TCC_BCHECK | 1402 | #ifdef CONFIG_TCC_BCHECK |
| 1409 | if (tcc_state->do_bounds_check) | 1403 | if (S->do_bounds_check) |
| 1410 | gen_bounds_epilog(); | 1404 | gen_bounds_epilog(S); |
| 1411 | #endif | 1405 | #endif |
| 1412 | 1406 | ||
| 1413 | if (loc) { | 1407 | if (S->tccgen_loc) { |
| 1414 | // Insert instructions to subtract size of stack frame from SP. | 1408 | // Insert instructions to subtract size of stack frame from SP. |
| 1415 | unsigned char *ptr = cur_text_section->data + arm64_func_sub_sp_offset; | 1409 | unsigned char *ptr = cur_text_section->data + arm64_func_sub_sp_offset; |
| 1416 | uint64_t diff = (-loc + 15) & ~15; | 1410 | uint64_t diff = (-S->tccgen_loc + 15) & ~15; |
| 1417 | if (!(diff >> 24)) { | 1411 | if (!(diff >> 24)) { |
| 1418 | if (diff & 0xfff) // sub sp,sp,#(diff & 0xfff) | 1412 | if (diff & 0xfff) // sub sp,sp,#(diff & 0xfff) |
| 1419 | write32le(ptr, 0xd10003ff | (diff & 0xfff) << 10); | 1413 | write32le(ptr, 0xd10003ff | (diff & 0xfff) << 10); |
| @@ -1439,40 +1433,40 @@ ST_FUNC void gfunc_epilog(void) · 19 unmodified lines | |||
| 1439 | // sub sp,sp,x16,lsl #(j) | 1433 | // sub sp,sp,x16,lsl #(j) |
| 1440 | } | 1434 | } |
| 1441 | } | 1435 | } |
| 1442 | o(0x910003bf); // mov sp,x29 | 1436 | o(S, 0x910003bf); // mov sp,x29 |
| 1443 | o(0xa8ce7bfd); // ldp x29,x30,[sp],#224 | 1437 | o(S, 0xa8ce7bfd); // ldp x29,x30,[sp],#224 |
| 1444 | 1438 | ||
| 1445 | o(0xd65f03c0); // ret | 1439 | o(S, 0xd65f03c0); // ret |
| 1446 | } | 1440 | } |
| 1447 | 1441 | ||
| 1448 | ST_FUNC void gen_fill_nops(int bytes) | 1442 | ST_FUNC void gen_fill_nops(TCCState *S, int bytes) |
| 1449 | { | 1443 | { |
| 1450 | if ((bytes & 3)) | 1444 | if ((bytes & 3)) |
| 1451 | tcc_error("alignment of code section not multiple of 4"); | 1445 | tcc_error(S, "alignment of code section not multiple of 4"); |
| 1452 | while (bytes > 0) { | 1446 | while (bytes > 0) { |
| 1453 | o(0xd503201f); // nop | 1447 | o(S, 0xd503201f); // nop |
| 1454 | bytes -= 4; | 1448 | bytes -= 4; |
| 1455 | } | 1449 | } |
| 1456 | } | 1450 | } |
| 1457 | 1451 | ||
| 1458 | // Generate forward branch to label: | 1452 | // Generate forward branch to label: |
| 1459 | ST_FUNC int gjmp(int t) | 1453 | ST_FUNC int gjmp(TCCState *S, int t) |
| 1460 | { | 1454 | { |
| 1461 | int r = ind; | 1455 | int r = S->tccgen_ind; |
| 1462 | if (nocode_wanted) | 1456 | if (S->tccgen_nocode_wanted) |
| 1463 | return t; | 1457 | return t; |
| 1464 | o(t); | 1458 | o(S, t); |
| 1465 | return r; | 1459 | return r; |
| 1466 | } | 1460 | } |
| 1467 | 1461 | ||
| 1468 | // Generate branch to known address: | 1462 | // Generate branch to known address: |
| 1469 | ST_FUNC void gjmp_addr(int a) | 1463 | ST_FUNC void gjmp_addr(TCCState *S, int a) |
| 1470 | { | 1464 | { |
| 1471 | assert(a - ind + 0x8000000 < 0x10000000); | 1465 | assert(a - S->tccgen_ind + 0x8000000 < 0x10000000); |
| 1472 | o(0x14000000 | ((a - ind) >> 2 & 0x3ffffff)); | 1466 | o(S, 0x14000000 | ((a - S->tccgen_ind) >> 2 & 0x3ffffff)); |
| 1473 | } | 1467 | } |
| 1474 | 1468 | ||
| 1475 | ST_FUNC int gjmp_append(int n, int t) | 1469 | ST_FUNC int gjmp_append(TCCState *S, int n, int t) |
| 1476 | { | 1470 | { |
| 1477 | void *p; | 1471 | void *p; |
| 1478 | /* insert vtop->c jump list in t */ | 1472 | /* insert vtop->c jump list in t */ |
| @@ -1486,61 +1480,61 @@ ST_FUNC int gjmp_append(int n, int t) · 7 unmodified lines | |||
| 1486 | return t; | 1480 | return t; |
| 1487 | } | 1481 | } |
| 1488 | 1482 | ||
| 1489 | void arm64_vset_VT_CMP(int op) | 1483 | void arm64_vset_VT_CMP(TCCState *S, int op) |
| 1490 | { | 1484 | { |
| 1491 | if (op >= TOK_ULT && op <= TOK_GT) { | 1485 | if (op >= TOK_ULT && op <= TOK_GT) { |
| 1492 | vtop->cmp_r = vtop->r; | 1486 | S->tccgen_vtop->cmp_r = S->tccgen_vtop->r; |
| 1493 | vset_VT_CMP(0x80); | 1487 | vset_VT_CMP(S, 0x80); |
| 1494 | } | 1488 | } |
| 1495 | } | 1489 | } |
| 1496 | 1490 | ||
| 1497 | static void arm64_gen_opil(int op, uint32_t l); | 1491 | static void arm64_gen_opil(TCCState *S, int op, uint32_t l); |
| 1498 | 1492 | ||
| 1499 | static void arm64_load_cmp(int r, SValue *sv) | 1493 | static void arm64_load_cmp(TCCState *S, int r, SValue *sv) |
| 1500 | { | 1494 | { |
| 1501 | sv->r = sv->cmp_r; | 1495 | sv->r = sv->cmp_r; |
| 1502 | if (sv->c.i & 1) { | 1496 | if (sv->c.i & 1) { |
| 1503 | vpushi(1); | 1497 | vpushi(S, 1); |
| 1504 | arm64_gen_opil('^', 0); | 1498 | arm64_gen_opil(S, '^', 0); |
| 1505 | } | 1499 | } |
| 1506 | if (r != sv->r) { | 1500 | if (r != sv->r) { |
| 1507 | load(r, sv); | 1501 | load(S, r, sv); |
| 1508 | sv->r = r; | 1502 | sv->r = r; |
| 1509 | } | 1503 | } |
| 1510 | } | 1504 | } |
| 1511 | 1505 | ||
| 1512 | ST_FUNC int gjmp_cond(int op, int t) | 1506 | ST_FUNC int gjmp_cond(TCCState *S, int op, int t) |
| 1513 | { | 1507 | { |
| 1514 | int bt = vtop->type.t & VT_BTYPE; | 1508 | int bt = S->tccgen_vtop->type.t & VT_BTYPE; |
| 1515 | 1509 | ||
| 1516 | int inv = op & 1; | 1510 | int inv = op & 1; |
| 1517 | vtop->r = vtop->cmp_r; | 1511 | S->tccgen_vtop->r = S->tccgen_vtop->cmp_r; |
| 1518 | 1512 | ||
| 1519 | if (bt == VT_LDOUBLE) { | 1513 | if (bt == VT_LDOUBLE) { |
| 1520 | uint32_t a, b, f = fltr(gv(RC_FLOAT)); | 1514 | uint32_t a, b, f = fltr(gv(S, RC_FLOAT)); |
| 1521 | a = get_reg(RC_INT); | 1515 | a = get_reg(S, RC_INT); |
| 1522 | vpushi(0); | 1516 | vpushi(S, 0); |
| 1523 | vtop[0].r = a; | 1517 | S->tccgen_vtop[0].r = a; |
| 1524 | b = get_reg(RC_INT); | 1518 | b = get_reg(S, RC_INT); |
| 1525 | a = intr(a); | 1519 | a = intr(S, a); |
| 1526 | b = intr(b); | 1520 | b = intr(S, b); |
| 1527 | o(0x4e083c00 | a | f << 5); // mov x(a),v(f).d[0] | 1521 | o(S, 0x4e083c00 | a | f << 5); // mov x(a),v(f).d[0] |
| 1528 | o(0x4e183c00 | b | f << 5); // mov x(b),v(f).d[1] | 1522 | o(S, 0x4e183c00 | b | f << 5); // mov x(b),v(f).d[1] |
| 1529 | o(0xaa000400 | a | a << 5 | b << 16); // orr x(a),x(a),x(b),lsl #1 | 1523 | o(S, 0xaa000400 | a | a << 5 | b << 16); // orr x(a),x(a),x(b),lsl #1 |
| 1530 | o(0xb4000040 | a | !!inv << 24); // cbz/cbnz x(a),.+8 | 1524 | o(S, 0xb4000040 | a | !!inv << 24); // cbz/cbnz x(a),.+8 |
| 1531 | --vtop; | 1525 | --S->tccgen_vtop; |
| 1532 | } | 1526 | } |
| 1533 | else if (bt == VT_FLOAT || bt == VT_DOUBLE) { | 1527 | else if (bt == VT_FLOAT || bt == VT_DOUBLE) { |
| 1534 | uint32_t a = fltr(gv(RC_FLOAT)); | 1528 | uint32_t a = fltr(gv(S, RC_FLOAT)); |
| 1535 | o(0x1e202008 | a << 5 | (bt != VT_FLOAT) << 22); // fcmp | 1529 | o(S, 0x1e202008 | a << 5 | (bt != VT_FLOAT) << 22); // fcmp |
| 1536 | o(0x54000040 | !!inv); // b.eq/b.ne .+8 | 1530 | o(S, 0x54000040 | !!inv); // b.eq/b.ne .+8 |
| 1537 | } | 1531 | } |
| 1538 | else { | 1532 | else { |
| 1539 | uint32_t ll = (bt == VT_PTR || bt == VT_LLONG); | 1533 | uint32_t ll = (bt == VT_PTR || bt == VT_LLONG); |
| 1540 | uint32_t a = intr(gv(RC_INT)); | 1534 | uint32_t a = intr(S, gv(S, RC_INT)); |
| 1541 | o(0x34000040 | a | !!inv << 24 | ll << 31); // cbz/cbnz wA,.+8 | 1535 | o(S, 0x34000040 | a | !!inv << 24 | ll << 31); // cbz/cbnz wA,.+8 |
| 1542 | } | 1536 | } |
| 1543 | return gjmp(t); | 1537 | return gjmp(S, t); |
| 1544 | } | 1538 | } |
| 1545 | 1539 | ||
| 1546 | static int arm64_iconst(uint64_t *val, SValue *sv) | 1540 | static int arm64_iconst(uint64_t *val, SValue *sv) |
| @@ -1557,7 +1551,7 @@ static int arm64_iconst(uint64_t *val, SValue *sv) · 10 unmodified lines | |||
| 1557 | return 1; | 1551 | return 1; |
| 1558 | } | 1552 | } |
| 1559 | 1553 | ||
| 1560 | static int arm64_gen_opic(int op, uint32_t l, int rev, uint64_t val, | 1554 | static int arm64_gen_opic(TCCState *S, int op, uint32_t l, int rev, uint64_t val, |
| 1561 | uint32_t x, uint32_t a) | 1555 | uint32_t x, uint32_t a) |
| 1562 | { | 1556 | { |
| 1563 | if (op == '-' && !rev) { | 1557 | if (op == '-' && !rev) { |
| @@ -1573,30 +1567,30 @@ static int arm64_gen_opic(int op, uint32_t l, int rev, uint64_t val, · 9 unmodified lines | |||
| 1573 | val = s ? -val : val; | 1567 | val = s ? -val : val; |
| 1574 | val = l ? val : (uint32_t)val; | 1568 | val = l ? val : (uint32_t)val; |
| 1575 | if (!(val & ~(uint64_t)0xfff)) | 1569 | if (!(val & ~(uint64_t)0xfff)) |
| 1576 | o(0x11000000 | l << 31 | s << 30 | x | a << 5 | val << 10); | 1570 | o(S, 0x11000000 | l << 31 | s << 30 | x | a << 5 | val << 10); |
| 1577 | else if (!(val & ~(uint64_t)0xfff000)) | 1571 | else if (!(val & ~(uint64_t)0xfff000)) |
| 1578 | o(0x11400000 | l << 31 | s << 30 | x | a << 5 | val >> 12 << 10); | 1572 | o(S, 0x11400000 | l << 31 | s << 30 | x | a << 5 | val >> 12 << 10); |
| 1579 | else { | 1573 | else { |
| 1580 | arm64_movimm(30, val); // use x30 | 1574 | arm64_movimm(S, 30, val); // use x30 |
| 1581 | o(0x0b1e0000 | l << 31 | s << 30 | x | a << 5); | 1575 | o(S, 0x0b1e0000 | l << 31 | s << 30 | x | a << 5); |
| 1582 | } | 1576 | } |
| 1583 | return 1; | 1577 | return 1; |
| 1584 | } | 1578 | } |
| 1585 | 1579 | ||
| 1586 | case '-': | 1580 | case '-': |
| 1587 | if (!val) | 1581 | if (!val) |
| 1588 | o(0x4b0003e0 | l << 31 | x | a << 16); // neg | 1582 | o(S, 0x4b0003e0 | l << 31 | x | a << 16); // neg |
| 1589 | else if (val == (l ? (uint64_t)-1 : (uint32_t)-1)) | 1583 | else if (val == (l ? (uint64_t)-1 : (uint32_t)-1)) |
| 1590 | o(0x2a2003e0 | l << 31 | x | a << 16); // mvn | 1584 | o(S, 0x2a2003e0 | l << 31 | x | a << 16); // mvn |
| 1591 | else { | 1585 | else { |
| 1592 | arm64_movimm(30, val); // use x30 | 1586 | arm64_movimm(S, 30, val); // use x30 |
| 1593 | o(0x4b0003c0 | l << 31 | x | a << 16); // sub | 1587 | o(S, 0x4b0003c0 | l << 31 | x | a << 16); // sub |
| 1594 | } | 1588 | } |
| 1595 | return 1; | 1589 | return 1; |
| 1596 | 1590 | ||
| 1597 | case '^': | 1591 | case '^': |
| 1598 | if (val == -1 || (val == 0xffffffff && !l)) { | 1592 | if (val == -1 || (val == 0xffffffff && !l)) { |
| 1599 | o(0x2a2003e0 | l << 31 | x | a << 16); // mvn | 1593 | o(S, 0x2a2003e0 | l << 31 | x | a << 16); // mvn |
| 1600 | return 1; | 1594 | return 1; |
| 1601 | } | 1595 | } |
| 1602 | // fall through | 1596 | // fall through |
| @@ -1605,7 +1599,7 @@ static int arm64_gen_opic(int op, uint32_t l, int rev, uint64_t val, · 2 unmodified lines | |||
| 1605 | int e = arm64_encode_bimm64(l ? val : val | val << 32); | 1599 | int e = arm64_encode_bimm64(l ? val : val | val << 32); |
| 1606 | if (e < 0) | 1600 | if (e < 0) |
| 1607 | return 0; | 1601 | return 0; |
| 1608 | o((op == '&' ? 0x12000000 : | 1602 | o(S, (op == '&' ? 0x12000000 : |
| 1609 | op == '|' ? 0x32000000 : 0x52000000) | | 1603 | op == '|' ? 0x32000000 : 0x52000000) | |
| 1610 | l << 31 | x | a << 5 | (uint32_t)e << 10); | 1604 | l << 31 | x | a << 5 | (uint32_t)e << 10); |
| 1611 | return 1; | 1605 | return 1; |
| @@ -1620,14 +1614,14 @@ static int arm64_gen_opic(int op, uint32_t l, int rev, uint64_t val, · 8 unmodified lines | |||
| 1620 | return 0; | 1614 | return 0; |
| 1621 | if (!val) { | 1615 | if (!val) { |
| 1622 | // tcc_warning("shift count >= width of type"); | 1616 | // tcc_warning("shift count >= width of type"); |
| 1623 | o(0x2a0003e0 | l << 31 | a << 16); | 1617 | o(S, 0x2a0003e0 | l << 31 | a << 16); |
| 1624 | return 1; | 1618 | return 1; |
| 1625 | } | 1619 | } |
| 1626 | else if (op == TOK_SHL) | 1620 | else if (op == TOK_SHL) |
| 1627 | o(0x53000000 | l << 31 | l << 22 | x | a << 5 | | 1621 | o(S, 0x53000000 | l << 31 | l << 22 | x | a << 5 | |
| 1628 | (n - val) << 16 | (n - 1 - val) << 10); // lsl | 1622 | (n - val) << 16 | (n - 1 - val) << 10); // lsl |
| 1629 | else | 1623 | else |
| 1630 | o(0x13000000 | (op == TOK_SHR) << 30 | l << 31 | l << 22 | | 1624 | o(S, 0x13000000 | (op == TOK_SHR) << 30 | l << 31 | l << 22 | |
| 1631 | x | a << 5 | val << 16 | (n - 1) << 10); // lsr/asr | 1625 | x | a << 5 | val << 16 | (n - 1) << 10); // lsr/asr |
| 1632 | return 1; | 1626 | return 1; |
| 1633 | } | 1627 | } |
| @@ -1636,7 +1630,7 @@ static int arm64_gen_opic(int op, uint32_t l, int rev, uint64_t val, · 2 unmodified lines | |||
| 1636 | return 0; | 1630 | return 0; |
| 1637 | } | 1631 | } |
| 1638 | 1632 | ||
| 1639 | static void arm64_gen_opil(int op, uint32_t l) | 1633 | static void arm64_gen_opil(TCCState *S, int op, uint32_t l) |
| 1640 | { | 1634 | { |
| 1641 | uint32_t x, a, b; | 1635 | uint32_t x, a, b; |
| 1642 | 1636 | ||
| @@ -1645,122 +1639,122 @@ static void arm64_gen_opil(int op, uint32_t l) · 2 unmodified lines | |||
| 1645 | uint64_t val; | 1639 | uint64_t val; |
| 1646 | int rev = 1; | 1640 | int rev = 1; |
| 1647 | 1641 | ||
| 1648 | if (arm64_iconst(0, &vtop[0])) { | 1642 | if (arm64_iconst(0, &S->tccgen_vtop[0])) { |
| 1649 | vswap(); | 1643 | vswap(S); |
| 1650 | rev = 0; | 1644 | rev = 0; |
| 1651 | } | 1645 | } |
| 1652 | if (arm64_iconst(&val, &vtop[-1])) { | 1646 | if (arm64_iconst(&val, &S->tccgen_vtop[-1])) { |
| 1653 | gv(RC_INT); | 1647 | gv(S, RC_INT); |
| 1654 | a = intr(vtop[0].r); | 1648 | a = intr(S, S->tccgen_vtop[0].r); |
| 1655 | --vtop; | 1649 | --S->tccgen_vtop; |
| 1656 | x = get_reg(RC_INT); | 1650 | x = get_reg(S, RC_INT); |
| 1657 | ++vtop; | 1651 | ++S->tccgen_vtop; |
| 1658 | if (arm64_gen_opic(op, l, rev, val, intr(x), a)) { | 1652 | if (arm64_gen_opic(S, op, l, rev, val, intr(S, x), a)) { |
| 1659 | vtop[0].r = x; | 1653 | S->tccgen_vtop[0].r = x; |
| 1660 | vswap(); | 1654 | vswap(S); |
| 1661 | --vtop; | 1655 | --S->tccgen_vtop; |
| 1662 | return; | 1656 | return; |
| 1663 | } | 1657 | } |
| 1664 | } | 1658 | } |
| 1665 | if (!rev) | 1659 | if (!rev) |
| 1666 | vswap(); | 1660 | vswap(S); |
| 1667 | } | 1661 | } |
| 1668 | 1662 | ||
| 1669 | gv2(RC_INT, RC_INT); | 1663 | gv2(S, RC_INT, RC_INT); |
| 1670 | assert(vtop[-1].r < VT_CONST && vtop[0].r < VT_CONST); | 1664 | assert(S->tccgen_vtop[-1].r < VT_CONST && S->tccgen_vtop[0].r < VT_CONST); |
| 1671 | a = intr(vtop[-1].r); | 1665 | a = intr(S, S->tccgen_vtop[-1].r); |
| 1672 | b = intr(vtop[0].r); | 1666 | b = intr(S, S->tccgen_vtop[0].r); |
| 1673 | vtop -= 2; | 1667 | S->tccgen_vtop -= 2; |
| 1674 | x = get_reg(RC_INT); | 1668 | x = get_reg(S, RC_INT); |
| 1675 | ++vtop; | 1669 | ++S->tccgen_vtop; |
| 1676 | vtop[0].r = x; | 1670 | S->tccgen_vtop[0].r = x; |
| 1677 | x = intr(x); | 1671 | x = intr(S, x); |
| 1678 | 1672 | ||
| 1679 | switch (op) { | 1673 | switch (op) { |
| 1680 | case '%': | 1674 | case '%': |
| 1681 | // Use x30 for quotient: | 1675 | // Use x30 for quotient: |
| 1682 | o(0x1ac00c00 | l << 31 | 30 | a << 5 | b << 16); // sdiv | 1676 | o(S, 0x1ac00c00 | l << 31 | 30 | a << 5 | b << 16); // sdiv |
| 1683 | o(0x1b008000 | l << 31 | x | (uint32_t)30 << 5 | | 1677 | o(S, 0x1b008000 | l << 31 | x | (uint32_t)30 << 5 | |
| 1684 | b << 16 | a << 10); // msub | 1678 | b << 16 | a << 10); // msub |
| 1685 | break; | 1679 | break; |
| 1686 | case '&': | 1680 | case '&': |
| 1687 | o(0x0a000000 | l << 31 | x | a << 5 | b << 16); // and | 1681 | o(S, 0x0a000000 | l << 31 | x | a << 5 | b << 16); // and |
| 1688 | break; | 1682 | break; |
| 1689 | case '*': | 1683 | case '*': |
| 1690 | o(0x1b007c00 | l << 31 | x | a << 5 | b << 16); // mul | 1684 | o(S, 0x1b007c00 | l << 31 | x | a << 5 | b << 16); // mul |
| 1691 | break; | 1685 | break; |
| 1692 | case '+': | 1686 | case '+': |
| 1693 | o(0x0b000000 | l << 31 | x | a << 5 | b << 16); // add | 1687 | o(S, 0x0b000000 | l << 31 | x | a << 5 | b << 16); // add |
| 1694 | break; | 1688 | break; |
| 1695 | case '-': | 1689 | case '-': |
| 1696 | o(0x4b000000 | l << 31 | x | a << 5 | b << 16); // sub | 1690 | o(S, 0x4b000000 | l << 31 | x | a << 5 | b << 16); // sub |
| 1697 | break; | 1691 | break; |
| 1698 | case '/': | 1692 | case '/': |
| 1699 | o(0x1ac00c00 | l << 31 | x | a << 5 | b << 16); // sdiv | 1693 | o(S, 0x1ac00c00 | l << 31 | x | a << 5 | b << 16); // sdiv |
| 1700 | break; | 1694 | break; |
| 1701 | case '^': | 1695 | case '^': |
| 1702 | o(0x4a000000 | l << 31 | x | a << 5 | b << 16); // eor | 1696 | o(S, 0x4a000000 | l << 31 | x | a << 5 | b << 16); // eor |
| 1703 | break; | 1697 | break; |
| 1704 | case '|': | 1698 | case '|': |
| 1705 | o(0x2a000000 | l << 31 | x | a << 5 | b << 16); // orr | 1699 | o(S, 0x2a000000 | l << 31 | x | a << 5 | b << 16); // orr |
| 1706 | break; | 1700 | break; |
| 1707 | case TOK_EQ: | 1701 | case TOK_EQ: |
| 1708 | o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp | 1702 | o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp |
| 1709 | o(0x1a9f17e0 | x); // cset wA,eq | 1703 | o(S, 0x1a9f17e0 | x); // cset wA,eq |
| 1710 | break; | 1704 | break; |
| 1711 | case TOK_GE: | 1705 | case TOK_GE: |
| 1712 | o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp | 1706 | o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp |
| 1713 | o(0x1a9fb7e0 | x); // cset wA,ge | 1707 | o(S, 0x1a9fb7e0 | x); // cset wA,ge |
| 1714 | break; | 1708 | break; |
| 1715 | case TOK_GT: | 1709 | case TOK_GT: |
| 1716 | o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp | 1710 | o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp |
| 1717 | o(0x1a9fd7e0 | x); // cset wA,gt | 1711 | o(S, 0x1a9fd7e0 | x); // cset wA,gt |
| 1718 | break; | 1712 | break; |
| 1719 | case TOK_LE: | 1713 | case TOK_LE: |
| 1720 | o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp | 1714 | o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp |
| 1721 | o(0x1a9fc7e0 | x); // cset wA,le | 1715 | o(S, 0x1a9fc7e0 | x); // cset wA,le |
| 1722 | break; | 1716 | break; |
| 1723 | case TOK_LT: | 1717 | case TOK_LT: |
| 1724 | o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp | 1718 | o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp |
| 1725 | o(0x1a9fa7e0 | x); // cset wA,lt | 1719 | o(S, 0x1a9fa7e0 | x); // cset wA,lt |
| 1726 | break; | 1720 | break; |
| 1727 | case TOK_NE: | 1721 | case TOK_NE: |
| 1728 | o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp | 1722 | o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp |
| 1729 | o(0x1a9f07e0 | x); // cset wA,ne | 1723 | o(S, 0x1a9f07e0 | x); // cset wA,ne |
| 1730 | break; | 1724 | break; |
| 1731 | case TOK_SAR: | 1725 | case TOK_SAR: |
| 1732 | o(0x1ac02800 | l << 31 | x | a << 5 | b << 16); // asr | 1726 | o(S, 0x1ac02800 | l << 31 | x | a << 5 | b << 16); // asr |
| 1733 | break; | 1727 | break; |
| 1734 | case TOK_SHL: | 1728 | case TOK_SHL: |
| 1735 | o(0x1ac02000 | l << 31 | x | a << 5 | b << 16); // lsl | 1729 | o(S, 0x1ac02000 | l << 31 | x | a << 5 | b << 16); // lsl |
| 1736 | break; | 1730 | break; |
| 1737 | case TOK_SHR: | 1731 | case TOK_SHR: |
| 1738 | o(0x1ac02400 | l << 31 | x | a << 5 | b << 16); // lsr | 1732 | o(S, 0x1ac02400 | l << 31 | x | a << 5 | b << 16); // lsr |
| 1739 | break; | 1733 | break; |
| 1740 | case TOK_UDIV: | 1734 | case TOK_UDIV: |
| 1741 | case TOK_PDIV: | 1735 | case TOK_PDIV: |
| 1742 | o(0x1ac00800 | l << 31 | x | a << 5 | b << 16); // udiv | 1736 | o(S, 0x1ac00800 | l << 31 | x | a << 5 | b << 16); // udiv |
| 1743 | break; | 1737 | break; |
| 1744 | case TOK_UGE: | 1738 | case TOK_UGE: |
| 1745 | o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp | 1739 | o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp |
| 1746 | o(0x1a9f37e0 | x); // cset wA,cs | 1740 | o(S, 0x1a9f37e0 | x); // cset wA,cs |
| 1747 | break; | 1741 | break; |
| 1748 | case TOK_UGT: | 1742 | case TOK_UGT: |
| 1749 | o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp | 1743 | o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp |
| 1750 | o(0x1a9f97e0 | x); // cset wA,hi | 1744 | o(S, 0x1a9f97e0 | x); // cset wA,hi |
| 1751 | break; | 1745 | break; |
| 1752 | case TOK_ULT: | 1746 | case TOK_ULT: |
| 1753 | o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp | 1747 | o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp |
| 1754 | o(0x1a9f27e0 | x); // cset wA,cc | 1748 | o(S, 0x1a9f27e0 | x); // cset wA,cc |
| 1755 | break; | 1749 | break; |
| 1756 | case TOK_ULE: | 1750 | case TOK_ULE: |
| 1757 | o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp | 1751 | o(S, 0x6b00001f | l << 31 | a << 5 | b << 16); // cmp |
| 1758 | o(0x1a9f87e0 | x); // cset wA,ls | 1752 | o(S, 0x1a9f87e0 | x); // cset wA,ls |
| 1759 | break; | 1753 | break; |
| 1760 | case TOK_UMOD: | 1754 | case TOK_UMOD: |
| 1761 | // Use x30 for quotient: | 1755 | // Use x30 for quotient: |
| 1762 | o(0x1ac00800 | l << 31 | 30 | a << 5 | b << 16); // udiv | 1756 | o(S, 0x1ac00800 | l << 31 | 30 | a << 5 | b << 16); // udiv |
| 1763 | o(0x1b008000 | l << 31 | x | (uint32_t)30 << 5 | | 1757 | o(S, 0x1b008000 | l << 31 | x | (uint32_t)30 << 5 | |
| 1764 | b << 16 | a << 10); // msub | 1758 | b << 16 | a << 10); // msub |
| 1765 | break; | 1759 | break; |
| 1766 | default: | 1760 | default: |
| @@ -1768,24 +1762,24 @@ static void arm64_gen_opil(int op, uint32_t l) · 1 unmodified line | |||
| 1768 | } | 1762 | } |
| 1769 | } | 1763 | } |
| 1770 | 1764 | ||
| 1771 | ST_FUNC void gen_opi(int op) | 1765 | ST_FUNC void gen_opi(TCCState *S, int op) |
| 1772 | { | 1766 | { |
| 1773 | arm64_gen_opil(op, 0); | 1767 | arm64_gen_opil(S, op, 0); |
| 1774 | arm64_vset_VT_CMP(op); | 1768 | arm64_vset_VT_CMP(S, op); |
| 1775 | } | 1769 | } |
| 1776 | 1770 | ||
| 1777 | ST_FUNC void gen_opl(int op) | 1771 | ST_FUNC void gen_opl(TCCState* S, int op) |
| 1778 | { | 1772 | { |
| 1779 | arm64_gen_opil(op, 1); | 1773 | arm64_gen_opil(S, op, 1); |
| 1780 | arm64_vset_VT_CMP(op); | 1774 | arm64_vset_VT_CMP(S, op); |
| 1781 | } | 1775 | } |
| 1782 | 1776 | ||
| 1783 | ST_FUNC void gen_opf(int op) | 1777 | ST_FUNC void gen_opf(TCCState *S, int op) |
| 1784 | { | 1778 | { |
| 1785 | uint32_t x, a, b, dbl; | 1779 | uint32_t x, a, b, dbl; |
| 1786 | 1780 | ||
| 1787 | if (vtop[0].type.t == VT_LDOUBLE) { | 1781 | if (S->tccgen_vtop[0].type.t == VT_LDOUBLE) { |
| 1788 | CType type = vtop[0].type; | 1782 | CType type = S->tccgen_vtop[0].type; |
| 1789 | int func = 0; | 1783 | int func = 0; |
| 1790 | int cond = -1; | 1784 | int cond = -1; |
| 1791 | switch (op) { | 1785 | switch (op) { |
| @@ -1801,162 +1795,162 @@ ST_FUNC void gen_opf(int op) · 9 unmodified lines | |||
| 1801 | case TOK_GT: func = TOK___gttf2; cond = 13; break; | 1795 | case TOK_GT: func = TOK___gttf2; cond = 13; break; |
| 1802 | default: assert(0); break; | 1796 | default: assert(0); break; |
| 1803 | } | 1797 | } |
| 1804 | vpush_helper_func(func); | 1798 | vpush_helper_func(S, func); |
| 1805 | vrott(3); | 1799 | vrott(S, 3); |
| 1806 | gfunc_call(2); | 1800 | gfunc_call(S, 2); |
| 1807 | vpushi(0); | 1801 | vpushi(S, 0); |
| 1808 | vtop->r = cond < 0 ? REG_FRET : REG_IRET; | 1802 | S->tccgen_vtop->r = cond < 0 ? REG_FRET : REG_IRET; |
| 1809 | if (cond < 0) | 1803 | if (cond < 0) |
| 1810 | vtop->type = type; | 1804 | S->tccgen_vtop->type = type; |
| 1811 | else { | 1805 | else { |
| 1812 | o(0x7100001f); // cmp w0,#0 | 1806 | o(S, 0x7100001f); // cmp w0,#0 |
| 1813 | o(0x1a9f07e0 | (uint32_t)cond << 12); // cset w0,(cond) | 1807 | o(S, 0x1a9f07e0 | (uint32_t)cond << 12); // cset w0,(cond) |
| 1814 | } | 1808 | } |
| 1815 | return; | 1809 | return; |
| 1816 | } | 1810 | } |
| 1817 | 1811 | ||
| 1818 | dbl = vtop[0].type.t != VT_FLOAT; | 1812 | dbl = S->tccgen_vtop[0].type.t != VT_FLOAT; |
| 1819 | gv2(RC_FLOAT, RC_FLOAT); | 1813 | gv2(S, RC_FLOAT, RC_FLOAT); |
| 1820 | assert(vtop[-1].r < VT_CONST && vtop[0].r < VT_CONST); | 1814 | assert(S->tccgen_vtop[-1].r < VT_CONST && S->tccgen_vtop[0].r < VT_CONST); |
| 1821 | a = fltr(vtop[-1].r); | 1815 | a = fltr(S->tccgen_vtop[-1].r); |
| 1822 | b = fltr(vtop[0].r); | 1816 | b = fltr(S->tccgen_vtop[0].r); |
| 1823 | vtop -= 2; | 1817 | S->tccgen_vtop -= 2; |
| 1824 | switch (op) { | 1818 | switch (op) { |
| 1825 | case TOK_EQ: case TOK_NE: | 1819 | case TOK_EQ: case TOK_NE: |
| 1826 | case TOK_LT: case TOK_GE: case TOK_LE: case TOK_GT: | 1820 | case TOK_LT: case TOK_GE: case TOK_LE: case TOK_GT: |
| 1827 | x = get_reg(RC_INT); | 1821 | x = get_reg(S, RC_INT); |
| 1828 | ++vtop; | 1822 | ++S->tccgen_vtop; |
| 1829 | vtop[0].r = x; | 1823 | S->tccgen_vtop[0].r = x; |
| 1830 | x = intr(x); | 1824 | x = intr(S, x); |
| 1831 | break; | 1825 | break; |
| 1832 | default: | 1826 | default: |
| 1833 | x = get_reg(RC_FLOAT); | 1827 | x = get_reg(S, RC_FLOAT); |
| 1834 | ++vtop; | 1828 | ++S->tccgen_vtop; |
| 1835 | vtop[0].r = x; | 1829 | S->tccgen_vtop[0].r = x; |
| 1836 | x = fltr(x); | 1830 | x = fltr(x); |
| 1837 | break; | 1831 | break; |
| 1838 | } | 1832 | } |
| 1839 | 1833 | ||
| 1840 | switch (op) { | 1834 | switch (op) { |
| 1841 | case '*': | 1835 | case '*': |
| 1842 | o(0x1e200800 | dbl << 22 | x | a << 5 | b << 16); // fmul | 1836 | o(S, 0x1e200800 | dbl << 22 | x | a << 5 | b << 16); // fmul |
| 1843 | break; | 1837 | break; |
| 1844 | case '+': | 1838 | case '+': |
| 1845 | o(0x1e202800 | dbl << 22 | x | a << 5 | b << 16); // fadd | 1839 | o(S, 0x1e202800 | dbl << 22 | x | a << 5 | b << 16); // fadd |
| 1846 | break; | 1840 | break; |
| 1847 | case '-': | 1841 | case '-': |
| 1848 | o(0x1e203800 | dbl << 22 | x | a << 5 | b << 16); // fsub | 1842 | o(S, 0x1e203800 | dbl << 22 | x | a << 5 | b << 16); // fsub |
| 1849 | break; | 1843 | break; |
| 1850 | case '/': | 1844 | case '/': |
| 1851 | o(0x1e201800 | dbl << 22 | x | a << 5 | b << 16); // fdiv | 1845 | o(S, 0x1e201800 | dbl << 22 | x | a << 5 | b << 16); // fdiv |
| 1852 | break; | 1846 | break; |
| 1853 | case TOK_EQ: | 1847 | case TOK_EQ: |
| 1854 | o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp | 1848 | o(S, 0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp |
| 1855 | o(0x1a9f17e0 | x); // cset w(x),eq | 1849 | o(S, 0x1a9f17e0 | x); // cset w(x),eq |
| 1856 | break; | 1850 | break; |
| 1857 | case TOK_GE: | 1851 | case TOK_GE: |
| 1858 | o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp | 1852 | o(S, 0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp |
| 1859 | o(0x1a9fb7e0 | x); // cset w(x),ge | 1853 | o(S, 0x1a9fb7e0 | x); // cset w(x),ge |
| 1860 | break; | 1854 | break; |
| 1861 | case TOK_GT: | 1855 | case TOK_GT: |
| 1862 | o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp | 1856 | o(S, 0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp |
| 1863 | o(0x1a9fd7e0 | x); // cset w(x),gt | 1857 | o(S, 0x1a9fd7e0 | x); // cset w(x),gt |
| 1864 | break; | 1858 | break; |
| 1865 | case TOK_LE: | 1859 | case TOK_LE: |
| 1866 | o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp | 1860 | o(S, 0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp |
| 1867 | o(0x1a9f87e0 | x); // cset w(x),ls | 1861 | o(S, 0x1a9f87e0 | x); // cset w(x),ls |
| 1868 | break; | 1862 | break; |
| 1869 | case TOK_LT: | 1863 | case TOK_LT: |
| 1870 | o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp | 1864 | o(S, 0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp |
| 1871 | o(0x1a9f57e0 | x); // cset w(x),mi | 1865 | o(S, 0x1a9f57e0 | x); // cset w(x),mi |
| 1872 | break; | 1866 | break; |
| 1873 | case TOK_NE: | 1867 | case TOK_NE: |
| 1874 | o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp | 1868 | o(S, 0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp |
| 1875 | o(0x1a9f07e0 | x); // cset w(x),ne | 1869 | o(S, 0x1a9f07e0 | x); // cset w(x),ne |
| 1876 | break; | 1870 | break; |
| 1877 | default: | 1871 | default: |
| 1878 | assert(0); | 1872 | assert(0); |
| 1879 | } | 1873 | } |
| 1880 | arm64_vset_VT_CMP(op); | 1874 | arm64_vset_VT_CMP(S, op); |
| 1881 | } | 1875 | } |
| 1882 | 1876 | ||
| 1883 | // Generate sign extension from 32 to 64 bits: | 1877 | // Generate sign extension from 32 to 64 bits: |
| 1884 | ST_FUNC void gen_cvt_sxtw(void) | 1878 | ST_FUNC void gen_cvt_sxtw(TCCState *S) |
| 1885 | { | 1879 | { |
| 1886 | uint32_t r = intr(gv(RC_INT)); | 1880 | uint32_t r = intr(S, gv(S, RC_INT)); |
| 1887 | o(0x93407c00 | r | r << 5); // sxtw x(r),w(r) | 1881 | o(S, 0x93407c00 | r | r << 5); // sxtw x(r),w(r) |
| 1888 | } | 1882 | } |
| 1889 | 1883 | ||
| 1890 | /* char/short to int conversion */ | 1884 | /* char/short to int conversion */ |
| 1891 | ST_FUNC void gen_cvt_csti(int t) | 1885 | ST_FUNC void gen_cvt_csti(TCCState *S, int t) |
| 1892 | { | 1886 | { |
| 1893 | int r = intr(gv(RC_INT)); | 1887 | int r = intr(S, gv(S, RC_INT)); |
| 1894 | o(0x13001c00 | 1888 | o(S, 0x13001c00 |
| 1895 | | ((t & VT_BTYPE) == VT_SHORT) << 13 | 1889 | | ((t & VT_BTYPE) == VT_SHORT) << 13 |
| 1896 | | (uint32_t)!!(t & VT_UNSIGNED) << 30 | 1890 | | (uint32_t)!!(t & VT_UNSIGNED) << 30 |
| 1897 | | r | r << 5); // [su]xt[bh] w(r),w(r) | 1891 | | r | r << 5); // [su]xt[bh] w(r),w(r) |
| 1898 | } | 1892 | } |
| 1899 | 1893 | ||
| 1900 | ST_FUNC void gen_cvt_itof(int t) | 1894 | ST_FUNC void gen_cvt_itof(TCCState *S, int t) |
| 1901 | { | 1895 | { |
| 1902 | if (t == VT_LDOUBLE) { | 1896 | if (t == VT_LDOUBLE) { |
| 1903 | int f = vtop->type.t; | 1897 | int f = S->tccgen_vtop->type.t; |
| 1904 | int func = (f & VT_BTYPE) == VT_LLONG ? | 1898 | int func = (f & VT_BTYPE) == VT_LLONG ? |
| 1905 | (f & VT_UNSIGNED ? TOK___floatunditf : TOK___floatditf) : | 1899 | (f & VT_UNSIGNED ? TOK___floatunditf : TOK___floatditf) : |
| 1906 | (f & VT_UNSIGNED ? TOK___floatunsitf : TOK___floatsitf); | 1900 | (f & VT_UNSIGNED ? TOK___floatunsitf : TOK___floatsitf); |
| 1907 | vpush_helper_func(func); | 1901 | vpush_helper_func(S, func); |
| 1908 | vrott(2); | 1902 | vrott(S, 2); |
| 1909 | gfunc_call(1); | 1903 | gfunc_call(S, 1); |
| 1910 | vpushi(0); | 1904 | vpushi(S, 0); |
| 1911 | vtop->type.t = t; | 1905 | S->tccgen_vtop->type.t = t; |
| 1912 | vtop->r = REG_FRET; | 1906 | S->tccgen_vtop->r = REG_FRET; |
| 1913 | return; | 1907 | return; |
| 1914 | } | 1908 | } |
| 1915 | else { | 1909 | else { |
| 1916 | int d, n = intr(gv(RC_INT)); | 1910 | int d, n = intr(S, gv(S, RC_INT)); |
| 1917 | int s = !(vtop->type.t & VT_UNSIGNED); | 1911 | int s = !(S->tccgen_vtop->type.t & VT_UNSIGNED); |
| 1918 | uint32_t l = ((vtop->type.t & VT_BTYPE) == VT_LLONG); | 1912 | uint32_t l = ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG); |
| 1919 | --vtop; | 1913 | --S->tccgen_vtop; |
| 1920 | d = get_reg(RC_FLOAT); | 1914 | d = get_reg(S, RC_FLOAT); |
| 1921 | ++vtop; | 1915 | ++S->tccgen_vtop; |
| 1922 | vtop[0].r = d; | 1916 | S->tccgen_vtop[0].r = d; |
| 1923 | o(0x1e220000 | (uint32_t)!s << 16 | | 1917 | o(S, 0x1e220000 | (uint32_t)!s << 16 | |
| 1924 | (uint32_t)(t != VT_FLOAT) << 22 | fltr(d) | | 1918 | (uint32_t)(t != VT_FLOAT) << 22 | fltr(d) | |
| 1925 | l << 31 | n << 5); // [us]cvtf [sd](d),[wx](n) | 1919 | l << 31 | n << 5); // [us]cvtf [sd](d),[wx](n) |
| 1926 | } | 1920 | } |
| 1927 | } | 1921 | } |
| 1928 | 1922 | ||
| 1929 | ST_FUNC void gen_cvt_ftoi(int t) | 1923 | ST_FUNC void gen_cvt_ftoi(TCCState *S, int t) |
| 1930 | { | 1924 | { |
| 1931 | if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { | 1925 | if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { |
| 1932 | int func = (t & VT_BTYPE) == VT_LLONG ? | 1926 | int func = (t & VT_BTYPE) == VT_LLONG ? |
| 1933 | (t & VT_UNSIGNED ? TOK___fixunstfdi : TOK___fixtfdi) : | 1927 | (t & VT_UNSIGNED ? TOK___fixunstfdi : TOK___fixtfdi) : |
| 1934 | (t & VT_UNSIGNED ? TOK___fixunstfsi : TOK___fixtfsi); | 1928 | (t & VT_UNSIGNED ? TOK___fixunstfsi : TOK___fixtfsi); |
| 1935 | vpush_helper_func(func); | 1929 | vpush_helper_func(S, func); |
| 1936 | vrott(2); | 1930 | vrott(S, 2); |
| 1937 | gfunc_call(1); | 1931 | gfunc_call(S, 1); |
| 1938 | vpushi(0); | 1932 | vpushi(S, 0); |
| 1939 | vtop->type.t = t; | 1933 | S->tccgen_vtop->type.t = t; |
| 1940 | vtop->r = REG_IRET; | 1934 | S->tccgen_vtop->r = REG_IRET; |
| 1941 | return; | 1935 | return; |
| 1942 | } | 1936 | } |
| 1943 | else { | 1937 | else { |
| 1944 | int d, n = fltr(gv(RC_FLOAT)); | 1938 | int d, n = fltr(gv(S, RC_FLOAT)); |
| 1945 | uint32_t l = ((vtop->type.t & VT_BTYPE) != VT_FLOAT); | 1939 | uint32_t l = ((S->tccgen_vtop->type.t & VT_BTYPE) != VT_FLOAT); |
| 1946 | --vtop; | 1940 | --S->tccgen_vtop; |
| 1947 | d = get_reg(RC_INT); | 1941 | d = get_reg(S, RC_INT); |
| 1948 | ++vtop; | 1942 | ++S->tccgen_vtop; |
| 1949 | vtop[0].r = d; | 1943 | S->tccgen_vtop[0].r = d; |
| 1950 | o(0x1e380000 | | 1944 | o(S, 0x1e380000 | |
| 1951 | (uint32_t)!!(t & VT_UNSIGNED) << 16 | | 1945 | (uint32_t)!!(t & VT_UNSIGNED) << 16 | |
| 1952 | (uint32_t)((t & VT_BTYPE) == VT_LLONG) << 31 | intr(d) | | 1946 | (uint32_t)((t & VT_BTYPE) == VT_LLONG) << 31 | intr(S, d) | |
| 1953 | l << 22 | n << 5); // fcvtz[su] [wx](d),[sd](n) | 1947 | l << 22 | n << 5); // fcvtz[su] [wx](d),[sd](n) |
| 1954 | } | 1948 | } |
| 1955 | } | 1949 | } |
| 1956 | 1950 | ||
| 1957 | ST_FUNC void gen_cvt_ftof(int t) | 1951 | ST_FUNC void gen_cvt_ftof(TCCState *S, int t) |
| 1958 | { | 1952 | { |
| 1959 | int f = vtop[0].type.t & VT_BTYPE; | 1953 | int f = S->tccgen_vtop[0].type.t & VT_BTYPE; |
| 1960 | assert(t == VT_FLOAT || t == VT_DOUBLE || t == VT_LDOUBLE); | 1954 | assert(t == VT_FLOAT || t == VT_DOUBLE || t == VT_LDOUBLE); |
| 1961 | assert(f == VT_FLOAT || f == VT_DOUBLE || f == VT_LDOUBLE); | 1955 | assert(f == VT_FLOAT || f == VT_DOUBLE || f == VT_LDOUBLE); |
| 1962 | if (t == f) | 1956 | if (t == f) |
| @@ -1966,142 +1960,142 @@ ST_FUNC void gen_cvt_ftof(int t) · 3 unmodified lines | |||
| 1966 | int func = (t == VT_LDOUBLE) ? | 1960 | int func = (t == VT_LDOUBLE) ? |
| 1967 | (f == VT_FLOAT ? TOK___extendsftf2 : TOK___extenddftf2) : | 1961 | (f == VT_FLOAT ? TOK___extendsftf2 : TOK___extenddftf2) : |
| 1968 | (t == VT_FLOAT ? TOK___trunctfsf2 : TOK___trunctfdf2); | 1962 | (t == VT_FLOAT ? TOK___trunctfsf2 : TOK___trunctfdf2); |
| 1969 | vpush_helper_func(func); | 1963 | vpush_helper_func(S, func); |
| 1970 | vrott(2); | 1964 | vrott(S, 2); |
| 1971 | gfunc_call(1); | 1965 | gfunc_call(S, 1); |
| 1972 | vpushi(0); | 1966 | vpushi(S, 0); |
| 1973 | vtop->type.t = t; | 1967 | S->tccgen_vtop->type.t = t; |
| 1974 | vtop->r = REG_FRET; | 1968 | S->tccgen_vtop->r = REG_FRET; |
| 1975 | } | 1969 | } |
| 1976 | else { | 1970 | else { |
| 1977 | int x, a; | 1971 | int x, a; |
| 1978 | gv(RC_FLOAT); | 1972 | gv(S, RC_FLOAT); |
| 1979 | assert(vtop[0].r < VT_CONST); | 1973 | assert(S->tccgen_vtop[0].r < VT_CONST); |
| 1980 | a = fltr(vtop[0].r); | 1974 | a = fltr(S->tccgen_vtop[0].r); |
| 1981 | --vtop; | 1975 | --S->tccgen_vtop; |
| 1982 | x = get_reg(RC_FLOAT); | 1976 | x = get_reg(S, RC_FLOAT); |
| 1983 | ++vtop; | 1977 | ++S->tccgen_vtop; |
| 1984 | vtop[0].r = x; | 1978 | S->tccgen_vtop[0].r = x; |
| 1985 | x = fltr(x); | 1979 | x = fltr(x); |
| 1986 | 1980 | ||
| 1987 | if (f == VT_FLOAT) | 1981 | if (f == VT_FLOAT) |
| 1988 | o(0x1e22c000 | x | a << 5); // fcvt d(x),s(a) | 1982 | o(S, 0x1e22c000 | x | a << 5); // fcvt d(x),s(a) |
| 1989 | else | 1983 | else |
| 1990 | o(0x1e624000 | x | a << 5); // fcvt s(x),d(a) | 1984 | o(S, 0x1e624000 | x | a << 5); // fcvt s(x),d(a) |
| 1991 | } | 1985 | } |
| 1992 | } | 1986 | } |
| 1993 | 1987 | ||
| 1994 | /* increment tcov counter */ | 1988 | /* increment tcov counter */ |
| 1995 | ST_FUNC void gen_increment_tcov (SValue *sv) | 1989 | ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv) |
| 1996 | { | 1990 | { |
| 1997 | int r1, r2; | 1991 | int r1, r2; |
| 1998 | 1992 | ||
| 1999 | vpushv(sv); | 1993 | vpushv(S, sv); |
| 2000 | vtop->r = r1 = get_reg(RC_INT); | 1994 | S->tccgen_vtop->r = r1 = get_reg(S, RC_INT); |
| 2001 | r2 = get_reg(RC_INT); | 1995 | r2 = get_reg(S, RC_INT); |
| 2002 | greloca(cur_text_section, sv->sym, ind, R_AARCH64_ADR_GOT_PAGE, 0); | 1996 | greloca(S, cur_text_section, sv->sym, S->tccgen_ind, R_AARCH64_ADR_GOT_PAGE, 0); |
| 2003 | o(0x90000000 | r1); // adrp r1, #sym | 1997 | o(S, 0x90000000 | r1); // adrp r1, #sym |
| 2004 | greloca(cur_text_section, sv->sym, ind, R_AARCH64_LD64_GOT_LO12_NC, 0); | 1998 | greloca(S, cur_text_section, sv->sym, S->tccgen_ind, R_AARCH64_LD64_GOT_LO12_NC, 0); |
| 2005 | o(0xf9400000 | r1 | (r1 << 5)); // ld xr,[xr, #sym] | 1999 | o(S, 0xf9400000 | r1 | (r1 << 5)); // ld xr,[xr, #sym] |
| 2006 | o(0xf9400000 | (intr(r1)<<5) | intr(r2)); // ldr r2, [r1] | 2000 | o(S, 0xf9400000 | (intr(S, r1)<<5) | intr(S, r2)); // ldr r2, [r1] |
| 2007 | o(0x91000400 | (intr(r2)<<5) | intr(r2)); // add r2, r2, #1 | 2001 | o(S, 0x91000400 | (intr(S, r2)<<5) | intr(S, r2)); // add r2, r2, #1 |
| 2008 | o(0xf9000000 | (intr(r1)<<5) | intr(r2)); // str r2, [r1] | 2002 | o(S, 0xf9000000 | (intr(S, r1)<<5) | intr(S, r2)); // str r2, [r1] |
| 2009 | vpop(); | 2003 | vpop(S); |
| 2010 | } | 2004 | } |
| 2011 | 2005 | ||
| 2012 | ST_FUNC void ggoto(void) | 2006 | ST_FUNC void ggoto(TCCState *S) |
| 2013 | { | 2007 | { |
| 2014 | arm64_gen_bl_or_b(1); | 2008 | arm64_gen_bl_or_b(S, 1); |
| 2015 | --vtop; | 2009 | --S->tccgen_vtop; |
| 2016 | } | 2010 | } |
| 2017 | 2011 | ||
| 2018 | ST_FUNC void gen_clear_cache(void) | 2012 | ST_FUNC void gen_clear_cache(TCCState *S) |
| 2019 | { | 2013 | { |
| 2020 | uint32_t beg, end, dsz, isz, p, lab1, b1; | 2014 | uint32_t beg, end, dsz, isz, p, lab1, b1; |
| 2021 | gv2(RC_INT, RC_INT); | 2015 | gv2(S, RC_INT, RC_INT); |
| 2022 | vpushi(0); | 2016 | vpushi(S, 0); |
| 2023 | vtop->r = get_reg(RC_INT); | 2017 | S->tccgen_vtop->r = get_reg(S, RC_INT); |
| 2024 | vpushi(0); | 2018 | vpushi(S, 0); |
| 2025 | vtop->r = get_reg(RC_INT); | 2019 | S->tccgen_vtop->r = get_reg(S, RC_INT); |
| 2026 | vpushi(0); | 2020 | vpushi(S, 0); |
| 2027 | vtop->r = get_reg(RC_INT); | 2021 | S->tccgen_vtop->r = get_reg(S, RC_INT); |
| 2028 | beg = intr(vtop[-4].r); // x0 | 2022 | beg = intr(S, S->tccgen_vtop[-4].r); // x0 |
| 2029 | end = intr(vtop[-3].r); // x1 | 2023 | end = intr(S, S->tccgen_vtop[-3].r); // x1 |
| 2030 | dsz = intr(vtop[-2].r); // x2 | 2024 | dsz = intr(S, S->tccgen_vtop[-2].r); // x2 |
| 2031 | isz = intr(vtop[-1].r); // x3 | 2025 | isz = intr(S, S->tccgen_vtop[-1].r); // x3 |
| 2032 | p = intr(vtop[0].r); // x4 | 2026 | p = intr(S, S->tccgen_vtop[0].r); // x4 |
| 2033 | vtop -= 5; | 2027 | S->tccgen_vtop -= 5; |
| 2034 | 2028 | ||
| 2035 | o(0xd53b0020 | isz); // mrs x(isz),ctr_el0 | 2029 | o(S, 0xd53b0020 | isz); // mrs x(isz),ctr_el0 |
| 2036 | o(0x52800080 | p); // mov w(p),#4 | 2030 | o(S, 0x52800080 | p); // mov w(p),#4 |
| 2037 | o(0x53104c00 | dsz | isz << 5); // ubfx w(dsz),w(isz),#16,#4 | 2031 | o(S, 0x53104c00 | dsz | isz << 5); // ubfx w(dsz),w(isz),#16,#4 |
| 2038 | o(0x1ac02000 | dsz | p << 5 | dsz << 16); // lsl w(dsz),w(p),w(dsz) | 2032 | o(S, 0x1ac02000 | dsz | p << 5 | dsz << 16); // lsl w(dsz),w(p),w(dsz) |
| 2039 | o(0x12000c00 | isz | isz << 5); // and w(isz),w(isz),#15 | 2033 | o(S, 0x12000c00 | isz | isz << 5); // and w(isz),w(isz),#15 |
| 2040 | o(0x1ac02000 | isz | p << 5 | isz << 16); // lsl w(isz),w(p),w(isz) | 2034 | o(S, 0x1ac02000 | isz | p << 5 | isz << 16); // lsl w(isz),w(p),w(isz) |
| 2041 | o(0x51000400 | p | dsz << 5); // sub w(p),w(dsz),#1 | 2035 | o(S, 0x51000400 | p | dsz << 5); // sub w(p),w(dsz),#1 |
| 2042 | o(0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p) | 2036 | o(S, 0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p) |
| 2043 | b1 = ind; o(0x14000000); // b | 2037 | b1 = S->tccgen_ind; o(S, 0x14000000); // b |
| 2044 | lab1 = ind; | 2038 | lab1 = S->tccgen_ind; |
| 2045 | o(0xd50b7b20 | p); // dc cvau,x(p) | 2039 | o(S, 0xd50b7b20 | p); // dc cvau,x(p) |
| 2046 | o(0x8b000000 | p | p << 5 | dsz << 16); // add x(p),x(p),x(dsz) | 2040 | o(S, 0x8b000000 | p | p << 5 | dsz << 16); // add x(p),x(p),x(dsz) |
| 2047 | write32le(cur_text_section->data + b1, 0x14000000 | (ind - b1) >> 2); | 2041 | write32le(cur_text_section->data + b1, 0x14000000 | (S->tccgen_ind - b1) >> 2); |
| 2048 | o(0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end) | 2042 | o(S, 0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end) |
| 2049 | o(0x54ffffa3 | ((lab1 - ind) << 3 & 0xffffe0)); // b.cc lab1 | 2043 | o(S, 0x54ffffa3 | ((lab1 - S->tccgen_ind) << 3 & 0xffffe0)); // b.cc lab1 |
| 2050 | o(0xd5033b9f); // dsb ish | 2044 | o(S, 0xd5033b9f); // dsb ish |
| 2051 | o(0x51000400 | p | isz << 5); // sub w(p),w(isz),#1 | 2045 | o(S, 0x51000400 | p | isz << 5); // sub w(p),w(isz),#1 |
| 2052 | o(0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p) | 2046 | o(S, 0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p) |
| 2053 | b1 = ind; o(0x14000000); // b | 2047 | b1 = S->tccgen_ind; o(S, 0x14000000); // b |
| 2054 | lab1 = ind; | 2048 | lab1 = S->tccgen_ind; |
| 2055 | o(0xd50b7520 | p); // ic ivau,x(p) | 2049 | o(S, 0xd50b7520 | p); // ic ivau,x(p) |
| 2056 | o(0x8b000000 | p | p << 5 | isz << 16); // add x(p),x(p),x(isz) | 2050 | o(S, 0x8b000000 | p | p << 5 | isz << 16); // add x(p),x(p),x(isz) |
| 2057 | write32le(cur_text_section->data + b1, 0x14000000 | (ind - b1) >> 2); | 2051 | write32le(cur_text_section->data + b1, 0x14000000 | (S->tccgen_ind - b1) >> 2); |
| 2058 | o(0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end) | 2052 | o(S, 0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end) |
| 2059 | o(0x54ffffa3 | ((lab1 - ind) << 3 & 0xffffe0)); // b.cc lab1 | 2053 | o(S, 0x54ffffa3 | ((lab1 - S->tccgen_ind) << 3 & 0xffffe0)); // b.cc lab1 |
| 2060 | o(0xd5033b9f); // dsb ish | 2054 | o(S, 0xd5033b9f); // dsb ish |
| 2061 | o(0xd5033fdf); // isb | 2055 | o(S, 0xd5033fdf); // isb |
| 2062 | } | 2056 | } |
| 2063 | 2057 | ||
| 2064 | ST_FUNC void gen_vla_sp_save(int addr) { | 2058 | ST_FUNC void gen_vla_sp_save(TCCState *S, int addr) { |
| 2065 | uint32_t r = intr(get_reg(RC_INT)); | 2059 | uint32_t r = intr(S, get_reg(S, RC_INT)); |
| 2066 | o(0x910003e0 | r); // mov x(r),sp | 2060 | o(S, 0x910003e0 | r); // mov x(r),sp |
| 2067 | arm64_strx(3, r, 29, addr); | 2061 | arm64_strx(S, 3, r, 29, addr); |
| 2068 | } | 2062 | } |
| 2069 | 2063 | ||
| 2070 | ST_FUNC void gen_vla_sp_restore(int addr) { | 2064 | ST_FUNC void gen_vla_sp_restore(TCCState *S, int addr) { |
| 2071 | // Use x30 because this function can be called when there | 2065 | // Use x30 because this function can be called when there |
| 2072 | // is a live return value in x0 but there is nothing on | 2066 | // is a live return value in x0 but there is nothing on |
| 2073 | // the value stack to prevent get_reg from returning x0. | 2067 | // the value stack to prevent get_reg from returning x0. |
| 2074 | uint32_t r = 30; | 2068 | uint32_t r = 30; |
| 2075 | arm64_ldrx(0, 3, r, 29, addr); | 2069 | arm64_ldrx(S, 0, 3, r, 29, addr); |
| 2076 | o(0x9100001f | r << 5); // mov sp,x(r) | 2070 | o(S, 0x9100001f | r << 5); // mov sp,x(r) |
| 2077 | } | 2071 | } |
| 2078 | 2072 | ||
| 2079 | ST_FUNC void gen_vla_alloc(CType *type, int align) { | 2073 | ST_FUNC void gen_vla_alloc(TCCState *S, CType *type, int align) { |
| 2080 | uint32_t r; | 2074 | uint32_t r; |
| 2081 | #if defined(CONFIG_TCC_BCHECK) | 2075 | #if defined(CONFIG_TCC_BCHECK) |
| 2082 | if (tcc_state->do_bounds_check) | 2076 | if (S->do_bounds_check) |
| 2083 | vpushv(vtop); | 2077 | vpushv(S, S->tccgen_vtop); |
| 2084 | #endif | 2078 | #endif |
| 2085 | r = intr(gv(RC_INT)); | 2079 | r = intr(S, gv(S, RC_INT)); |
| 2086 | #if defined(CONFIG_TCC_BCHECK) | 2080 | #if defined(CONFIG_TCC_BCHECK) |
| 2087 | if (tcc_state->do_bounds_check) | 2081 | if (S->do_bounds_check) |
| 2088 | o(0x91004000 | r | r << 5); // add x(r),x(r),#15+1 | 2082 | o(S, 0x91004000 | r | r << 5); // add x(r),x(r),#15+1 |
| 2089 | else | 2083 | else |
| 2090 | #endif | 2084 | #endif |
| 2091 | o(0x91003c00 | r | r << 5); // add x(r),x(r),#15 | 2085 | o(S, 0x91003c00 | r | r << 5); // add x(r),x(r),#15 |
| 2092 | o(0x927cec00 | r | r << 5); // bic x(r),x(r),#15 | 2086 | o(S, 0x927cec00 | r | r << 5); // bic x(r),x(r),#15 |
| 2093 | o(0xcb2063ff | r << 16); // sub sp,sp,x(r) | 2087 | o(S, 0xcb2063ff | r << 16); // sub sp,sp,x(r) |
| 2094 | vpop(); | 2088 | vpop(S); |
| 2095 | #if defined(CONFIG_TCC_BCHECK) | 2089 | #if defined(CONFIG_TCC_BCHECK) |
| 2096 | if (tcc_state->do_bounds_check) { | 2090 | if (S->do_bounds_check) { |
| 2097 | vpushi(0); | 2091 | vpushi(S, 0); |
| 2098 | vtop->r = TREG_R(0); | 2092 | S->tccgen_vtop->r = TREG_R(0); |
| 2099 | o(0x910003e0 | vtop->r); // mov r0,sp | 2093 | o(S, 0x910003e0 | S->tccgen_vtop->r); // mov r0,sp |
| 2100 | vswap(); | 2094 | vswap(S); |
| 2101 | vpush_helper_func(TOK___bound_new_region); | 2095 | vpush_helper_func(S, TOK___bound_new_region); |
| 2102 | vrott(3); | 2096 | vrott(S, 3); |
| 2103 | gfunc_call(2); | 2097 | gfunc_call(S, 2); |
| 2104 | func_bound_add_epilog = 1; | 2098 | S->func_bound_add_epilog = 1; |
| 2105 | } | 2099 | } |
| 2106 | #endif | 2100 | #endif |
| 2107 | } | 2101 | } |
| @@ -90,18 +90,18 @@ int gotplt_entry_type (int reloc_type) · 89 unmodified lines | |||
| 90 | return -1; | 90 | return -1; |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr) | 93 | ST_FUNC unsigned create_plt_entry(TCCState *S, unsigned got_offset, struct sym_attr *attr) |
| 94 | { | 94 | { |
| 95 | Section *plt = s1->plt; | 95 | Section *plt = S->plt; |
| 96 | uint8_t *p; | 96 | uint8_t *p; |
| 97 | unsigned plt_offset; | 97 | unsigned plt_offset; |
| 98 | 98 | ||
| 99 | if (plt->data_offset == 0) { | 99 | if (plt->data_offset == 0) { |
| 100 | section_ptr_add(plt, 32); | 100 | section_ptr_add(S, plt, 32); |
| 101 | } | 101 | } |
| 102 | plt_offset = plt->data_offset; | 102 | plt_offset = plt->data_offset; |
| 103 | 103 | ||
| 104 | p = section_ptr_add(plt, 16); | 104 | p = section_ptr_add(S, plt, 16); |
| 105 | write32le(p, got_offset); | 105 | write32le(p, got_offset); |
| 106 | write32le(p + 4, (uint64_t) got_offset >> 32); | 106 | write32le(p + 4, (uint64_t) got_offset >> 32); |
| 107 | return plt_offset; | 107 | return plt_offset; |
| @@ -109,22 +109,22 @@ ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_ · 1 unmodified line | |||
| 109 | 109 | ||
| 110 | /* relocate the PLT: compute addresses and offsets in the PLT now that final | 110 | /* relocate the PLT: compute addresses and offsets in the PLT now that final |
| 111 | address for PLT and GOT are known (see fill_program_header) */ | 111 | address for PLT and GOT are known (see fill_program_header) */ |
| 112 | ST_FUNC void relocate_plt(TCCState *s1) | 112 | ST_FUNC void relocate_plt(TCCState *S) |
| 113 | { | 113 | { |
| 114 | uint8_t *p, *p_end; | 114 | uint8_t *p, *p_end; |
| 115 | 115 | ||
| 116 | if (!s1->plt) | 116 | if (!S->plt) |
| 117 | return; | 117 | return; |
| 118 | 118 | ||
| 119 | p = s1->plt->data; | 119 | p = S->plt->data; |
| 120 | p_end = p + s1->plt->data_offset; | 120 | p_end = p + S->plt->data_offset; |
| 121 | 121 | ||
| 122 | if (p < p_end) { | 122 | if (p < p_end) { |
| 123 | uint64_t plt = s1->plt->sh_addr; | 123 | uint64_t plt = S->plt->sh_addr; |
| 124 | uint64_t got = s1->got->sh_addr + 16; | 124 | uint64_t got = S->got->sh_addr + 16; |
| 125 | uint64_t off = (got >> 12) - (plt >> 12); | 125 | uint64_t off = (got >> 12) - (plt >> 12); |
| 126 | if ((off + ((uint32_t)1 << 20)) >> 21) | 126 | if ((off + ((uint32_t)1 << 20)) >> 21) |
| 127 | tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt); | 127 | tcc_error(S, "Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt); |
| 128 | write32le(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]! | 128 | write32le(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]! |
| 129 | write32le(p + 4, (0x90000010 | // adrp x16,... | 129 | write32le(p + 4, (0x90000010 | // adrp x16,... |
| 130 | (off & 0x1ffffc) << 3 | (off & 3) << 29)); | 130 | (off & 0x1ffffc) << 3 | (off & 3) << 29)); |
| @@ -137,13 +137,13 @@ ST_FUNC void relocate_plt(TCCState *s1) · 6 unmodified lines | |||
| 137 | write32le(p + 24, 0xd503201f); // nop | 137 | write32le(p + 24, 0xd503201f); // nop |
| 138 | write32le(p + 28, 0xd503201f); // nop | 138 | write32le(p + 28, 0xd503201f); // nop |
| 139 | p += 32; | 139 | p += 32; |
| 140 | got = s1->got->sh_addr; | 140 | got = S->got->sh_addr; |
| 141 | while (p < p_end) { | 141 | while (p < p_end) { |
| 142 | uint64_t pc = plt + (p - s1->plt->data); | 142 | uint64_t pc = plt + (p - S->plt->data); |
| 143 | uint64_t addr = got + read64le(p); | 143 | uint64_t addr = got + read64le(p); |
| 144 | uint64_t off = (addr >> 12) - (pc >> 12); | 144 | uint64_t off = (addr >> 12) - (pc >> 12); |
| 145 | if ((off + ((uint32_t)1 << 20)) >> 21) | 145 | if ((off + ((uint32_t)1 << 20)) >> 21) |
| 146 | tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc); | 146 | tcc_error(S, "Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc); |
| 147 | write32le(p, (0x90000010 | // adrp x16,... | 147 | write32le(p, (0x90000010 | // adrp x16,... |
| 148 | (off & 0x1ffffc) << 3 | (off & 3) << 29)); | 148 | (off & 0x1ffffc) << 3 | (off & 3) << 29)); |
| 149 | write32le(p + 4, (0xf9400211 | // ldr x17,[x16,#...] | 149 | write32le(p + 4, (0xf9400211 | // ldr x17,[x16,#...] |
| @@ -155,16 +155,16 @@ ST_FUNC void relocate_plt(TCCState *s1) · 5 unmodified lines | |||
| 155 | } | 155 | } |
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | if (s1->plt->reloc) { | 158 | if (S->plt->reloc) { |
| 159 | ElfW_Rel *rel; | 159 | ElfW_Rel *rel; |
| 160 | p = s1->got->data; | 160 | p = S->got->data; |
| 161 | for_each_elem(s1->plt->reloc, 0, rel, ElfW_Rel) { | 161 | for_each_elem(S->plt->reloc, 0, rel, ElfW_Rel) { |
| 162 | write64le(p + rel->r_offset, s1->plt->sh_addr); | 162 | write64le(p + rel->r_offset, S->plt->sh_addr); |
| 163 | } | 163 | } |
| 164 | } | 164 | } |
| 165 | } | 165 | } |
| 166 | 166 | ||
| 167 | void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val) | 167 | void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val) |
| 168 | { | 168 | { |
| 169 | int sym_index = ELFW(R_SYM)(rel->r_info), esym_index; | 169 | int sym_index = ELFW(R_SYM)(rel->r_info), esym_index; |
| 170 | #ifdef DEBUG_RELOC | 170 | #ifdef DEBUG_RELOC |
| @@ -173,8 +173,8 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 2 unmodified lines | |||
| 173 | 173 | ||
| 174 | switch(type) { | 174 | switch(type) { |
| 175 | case R_AARCH64_ABS64: | 175 | case R_AARCH64_ABS64: |
| 176 | if (s1->output_type == TCC_OUTPUT_DLL) { | 176 | if (S->output_type == TCC_OUTPUT_DLL) { |
| 177 | esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index; | 177 | esym_index = get_sym_attr(S, sym_index, 0)->dyn_index; |
| 178 | qrel->r_offset = rel->r_offset; | 178 | qrel->r_offset = rel->r_offset; |
| 179 | if (esym_index) { | 179 | if (esym_index) { |
| 180 | qrel->r_info = ELFW(R_INFO)(esym_index, R_AARCH64_ABS64); | 180 | qrel->r_info = ELFW(R_INFO)(esym_index, R_AARCH64_ABS64); |
| @@ -190,7 +190,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 9 unmodified lines | |||
| 190 | add64le(ptr, val); | 190 | add64le(ptr, val); |
| 191 | return; | 191 | return; |
| 192 | case R_AARCH64_ABS32: | 192 | case R_AARCH64_ABS32: |
| 193 | if (s1->output_type == TCC_OUTPUT_DLL) { | 193 | if (S->output_type == TCC_OUTPUT_DLL) { |
| 194 | /* XXX: this logic may depend on TCC's codegen | 194 | /* XXX: this logic may depend on TCC's codegen |
| 195 | now TCC uses R_AARCH64_RELATIVE even for a 64bit pointer */ | 195 | now TCC uses R_AARCH64_RELATIVE even for a 64bit pointer */ |
| 196 | qrel->r_offset = rel->r_offset; | 196 | qrel->r_offset = rel->r_offset; |
| @@ -202,9 +202,9 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 5 unmodified lines | |||
| 202 | add32le(ptr, val); | 202 | add32le(ptr, val); |
| 203 | return; | 203 | return; |
| 204 | case R_AARCH64_PREL32: | 204 | case R_AARCH64_PREL32: |
| 205 | if (s1->output_type == TCC_OUTPUT_DLL) { | 205 | if (S->output_type == TCC_OUTPUT_DLL) { |
| 206 | /* DLL relocation */ | 206 | /* DLL relocation */ |
| 207 | esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index; | 207 | esym_index = get_sym_attr(S, sym_index, 0)->dyn_index; |
| 208 | if (esym_index) { | 208 | if (esym_index) { |
| 209 | qrel->r_offset = rel->r_offset; | 209 | qrel->r_offset = rel->r_offset; |
| 210 | qrel->r_info = ELFW(R_INFO)(esym_index, R_AARCH64_PREL32); | 210 | qrel->r_info = ELFW(R_INFO)(esym_index, R_AARCH64_PREL32); |
| @@ -235,7 +235,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 24 unmodified lines | |||
| 235 | case R_AARCH64_ADR_PREL_PG_HI21: { | 235 | case R_AARCH64_ADR_PREL_PG_HI21: { |
| 236 | uint64_t off = (val >> 12) - (addr >> 12); | 236 | uint64_t off = (val >> 12) - (addr >> 12); |
| 237 | if ((off + ((uint64_t)1 << 20)) >> 21) | 237 | if ((off + ((uint64_t)1 << 20)) >> 21) |
| 238 | tcc_error("R_AARCH64_ADR_PREL_PG_HI21 relocation failed"); | 238 | tcc_error(S, "R_AARCH64_ADR_PREL_PG_HI21 relocation failed"); |
| 239 | write32le(ptr, ((read32le(ptr) & 0x9f00001f) | | 239 | write32le(ptr, ((read32le(ptr) & 0x9f00001f) | |
| 240 | (off & 0x1ffffc) << 3 | (off & 3) << 29)); | 240 | (off & 0x1ffffc) << 3 | (off & 3) << 29)); |
| 241 | return; | 241 | return; |
| @@ -268,7 +268,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 26 unmodified lines | |||
| 268 | (char *) symtab_section->link->data + sym->st_name); | 268 | (char *) symtab_section->link->data + sym->st_name); |
| 269 | #endif | 269 | #endif |
| 270 | if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc) | 270 | if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc) |
| 271 | tcc_error("R_AARCH64_(JUMP|CALL)26 relocation failed" | 271 | tcc_error(S, "R_AARCH64_(JUMP|CALL)26 relocation failed" |
| 272 | " (val=%lx, addr=%lx)", (long)val, (long)addr); | 272 | " (val=%lx, addr=%lx)", (long)val, (long)addr); |
| 273 | write32le(ptr, (0x14000000 | | 273 | write32le(ptr, (0x14000000 | |
| 274 | (uint32_t)(type == R_AARCH64_CALL26) << 31 | | 274 | (uint32_t)(type == R_AARCH64_CALL26) << 31 | |
| @@ -276,10 +276,10 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 1 unmodified line | |||
| 276 | return; | 276 | return; |
| 277 | case R_AARCH64_ADR_GOT_PAGE: { | 277 | case R_AARCH64_ADR_GOT_PAGE: { |
| 278 | uint64_t off = | 278 | uint64_t off = |
| 279 | (((s1->got->sh_addr + | 279 | (((S->got->sh_addr + |
| 280 | get_sym_attr(s1, sym_index, 0)->got_offset) >> 12) - (addr >> 12)); | 280 | get_sym_attr(S, sym_index, 0)->got_offset) >> 12) - (addr >> 12)); |
| 281 | if ((off + ((uint64_t)1 << 20)) >> 21) | 281 | if ((off + ((uint64_t)1 << 20)) >> 21) |
| 282 | tcc_error("R_AARCH64_ADR_GOT_PAGE relocation failed"); | 282 | tcc_error(S, "R_AARCH64_ADR_GOT_PAGE relocation failed"); |
| 283 | write32le(ptr, ((read32le(ptr) & 0x9f00001f) | | 283 | write32le(ptr, ((read32le(ptr) & 0x9f00001f) | |
| 284 | (off & 0x1ffffc) << 3 | (off & 3) << 29)); | 284 | (off & 0x1ffffc) << 3 | (off & 3) << 29)); |
| 285 | return; | 285 | return; |
| @@ -287,8 +287,8 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 1 unmodified line | |||
| 287 | case R_AARCH64_LD64_GOT_LO12_NC: | 287 | case R_AARCH64_LD64_GOT_LO12_NC: |
| 288 | write32le(ptr, | 288 | write32le(ptr, |
| 289 | ((read32le(ptr) & 0xfff803ff) | | 289 | ((read32le(ptr) & 0xfff803ff) | |
| 290 | ((s1->got->sh_addr + | 290 | ((S->got->sh_addr + |
| 291 | get_sym_attr(s1, sym_index, 0)->got_offset) & 0xff8) << 7)); | 291 | get_sym_attr(S, sym_index, 0)->got_offset) & 0xff8) << 7)); |
| 292 | return; | 292 | return; |
| 293 | case R_AARCH64_COPY: | 293 | case R_AARCH64_COPY: |
| 294 | return; | 294 | return; |
| @@ -304,7 +304,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 9 unmodified lines | |||
| 304 | return; | 304 | return; |
| 305 | case R_AARCH64_RELATIVE: | 305 | case R_AARCH64_RELATIVE: |
| 306 | #ifdef TCC_TARGET_PE | 306 | #ifdef TCC_TARGET_PE |
| 307 | add32le(ptr, val - s1->pe_imagebase); | 307 | add32le(ptr, val - S->pe_imagebase); |
| 308 | #endif | 308 | #endif |
| 309 | /* do nothing */ | 309 | /* do nothing */ |
| 310 | return; | 310 | return; |
| @@ -172,7 +172,7 @@ int TotalBytesPushedOnStack; · 171 unmodified lines | |||
| 172 | #define ALWAYS_ASSERT(x) \ | 172 | #define ALWAYS_ASSERT(x) \ |
| 173 | do {\ | 173 | do {\ |
| 174 | if (!(x))\ | 174 | if (!(x))\ |
| 175 | tcc_error("internal compiler error file at %s:%d", __FILE__, __LINE__);\ | 175 | tcc_error(S, "internal compiler error file at %s:%d", __FILE__, __LINE__);\ |
| 176 | } while (0) | 176 | } while (0) |
| 177 | 177 | ||
| 178 | /******************************************************/ | 178 | /******************************************************/ |
| @@ -186,27 +186,27 @@ static int C67_compare_reg; · 7 unmodified lines | |||
| 186 | FILE *f = NULL; | 186 | FILE *f = NULL; |
| 187 | #endif | 187 | #endif |
| 188 | 188 | ||
| 189 | void C67_g(int c) | 189 | void C67_g(TCCState* S, int c) |
| 190 | { | 190 | { |
| 191 | int ind1; | 191 | int ind1; |
| 192 | if (nocode_wanted) | 192 | if (S->tccgen_nocode_wanted) |
| 193 | return; | 193 | return; |
| 194 | #ifdef ASSEMBLY_LISTING_C67 | 194 | #ifdef ASSEMBLY_LISTING_C67 |
| 195 | fprintf(f, " %08X", c); | 195 | fprintf(f, " %08X", c); |
| 196 | #endif | 196 | #endif |
| 197 | ind1 = ind + 4; | 197 | ind1 = S->tccgen_ind + 4; |
| 198 | if (ind1 > (int) cur_text_section->data_allocated) | 198 | if (ind1 > (int) cur_text_section->data_allocated) |
| 199 | section_realloc(cur_text_section, ind1); | 199 | section_realloc(S, cur_text_section, ind1); |
| 200 | cur_text_section->data[ind] = c & 0xff; | 200 | cur_text_section->data[S->tccgen_ind] = c & 0xff; |
| 201 | cur_text_section->data[ind + 1] = (c >> 8) & 0xff; | 201 | cur_text_section->data[S->tccgen_ind + 1] = (c >> 8) & 0xff; |
| 202 | cur_text_section->data[ind + 2] = (c >> 16) & 0xff; | 202 | cur_text_section->data[S->tccgen_ind + 2] = (c >> 16) & 0xff; |
| 203 | cur_text_section->data[ind + 3] = (c >> 24) & 0xff; | 203 | cur_text_section->data[S->tccgen_ind + 3] = (c >> 24) & 0xff; |
| 204 | ind = ind1; | 204 | S->tccgen_ind = ind1; |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | 207 | ||
| 208 | /* output a symbol and patch all calls to it */ | 208 | /* output a symbol and patch all calls to it */ |
| 209 | void gsym_addr(int t, int a) | 209 | void gsym_addr(TCCState* S, int t, int a) |
| 210 | { | 210 | { |
| 211 | int n, *ptr; | 211 | int n, *ptr; |
| 212 | while (t) { | 212 | while (t) { |
| @@ -220,9 +220,9 @@ void gsym_addr(int t, int a) · 7 unmodified lines | |||
| 220 | 220 | ||
| 221 | // define a label that will be relocated | 221 | // define a label that will be relocated |
| 222 | 222 | ||
| 223 | sym = get_sym_ref(&char_pointer_type, cur_text_section, a, 0); | 223 | sym = get_sym_ref(S, &S->tccgen_char_pointer_type, cur_text_section, a, 0); |
| 224 | greloc(cur_text_section, sym, t, R_C60LO16); | 224 | greloc(S, cur_text_section, sym, t, R_C60LO16); |
| 225 | greloc(cur_text_section, sym, t + 4, R_C60HI16); | 225 | greloc(S, cur_text_section, sym, t + 4, R_C60HI16); |
| 226 | 226 | ||
| 227 | // clear out where the pointer was | 227 | // clear out where the pointer was |
| 228 | 228 | ||
| @@ -255,7 +255,7 @@ int ConvertRegToRegClass(int r) · 26 unmodified lines | |||
| 255 | 255 | ||
| 256 | // map TCC reg to C67 reg number | 256 | // map TCC reg to C67 reg number |
| 257 | 257 | ||
| 258 | int C67_map_regn(int r) | 258 | int C67_map_regn(TCCState* S, int r) |
| 259 | { | 259 | { |
| 260 | if (r == 0) // normal tcc regs | 260 | if (r == 0) // normal tcc regs |
| 261 | return 0x2; // A2 | 261 | return 0x2; // A2 |
| @@ -296,7 +296,7 @@ int C67_map_regn(int r) · 34 unmodified lines | |||
| 296 | // tcc reg 1 -> A3 -> X | 296 | // tcc reg 1 -> A3 -> X |
| 297 | // tcc reg B2 -> 3 | 297 | // tcc reg B2 -> 3 |
| 298 | 298 | ||
| 299 | int C67_map_regc(int r) | 299 | int C67_map_regc(TCCState* S, int r) |
| 300 | { | 300 | { |
| 301 | if (r == 0) // normal tcc regs | 301 | if (r == 0) // normal tcc regs |
| 302 | return 0x5; | 302 | return 0x5; |
| @@ -317,7 +317,7 @@ int C67_map_regc(int r) · 14 unmodified lines | |||
| 317 | 317 | ||
| 318 | // map TCC reg to C67 reg side A or B | 318 | // map TCC reg to C67 reg side A or B |
| 319 | 319 | ||
| 320 | int C67_map_regs(int r) | 320 | int C67_map_regs(TCCState* S, int r) |
| 321 | { | 321 | { |
| 322 | if (r == 0) // normal tcc regs | 322 | if (r == 0) // normal tcc regs |
| 323 | return 0x0; | 323 | return 0x0; |
| @@ -345,7 +345,7 @@ int C67_map_regs(int r) · 21 unmodified lines | |||
| 345 | return 0; | 345 | return 0; |
| 346 | } | 346 | } |
| 347 | 347 | ||
| 348 | int C67_map_S12(char *s) | 348 | int C67_map_S12(TCCState* S, char *s) |
| 349 | { | 349 | { |
| 350 | if (strstr(s, ".S1") != NULL) | 350 | if (strstr(s, ".S1") != NULL) |
| 351 | return 0; | 351 | return 0; |
| @@ -357,7 +357,7 @@ int C67_map_S12(char *s) · 5 unmodified lines | |||
| 357 | return 0; | 357 | return 0; |
| 358 | } | 358 | } |
| 359 | 359 | ||
| 360 | int C67_map_D12(char *s) | 360 | int C67_map_D12(TCCState* S, char *s) |
| 361 | { | 361 | { |
| 362 | if (strstr(s, ".D1") != NULL) | 362 | if (strstr(s, ".D1") != NULL) |
| 363 | return 0; | 363 | return 0; |
| @@ -371,7 +371,7 @@ int C67_map_D12(char *s) · 7 unmodified lines | |||
| 371 | 371 | ||
| 372 | 372 | ||
| 373 | 373 | ||
| 374 | void C67_asm(const char *s, int a, int b, int c) | 374 | void C67_asm(TCCState* S, const char *s, int a, int b, int c) |
| 375 | { | 375 | { |
| 376 | BOOL xpath; | 376 | BOOL xpath; |
| 377 | 377 | ||
| @@ -383,14 +383,14 @@ void C67_asm(const char *s, int a, int b, int c) · 5 unmodified lines | |||
| 383 | #endif | 383 | #endif |
| 384 | 384 | ||
| 385 | if (strstr(s, "MVKL") == s) { | 385 | if (strstr(s, "MVKL") == s) { |
| 386 | C67_g((C67_map_regn(b) << 23) | | 386 | C67_g(S, (C67_map_regn(S, b) << 23) | |
| 387 | ((a & 0xffff) << 7) | (0x0a << 2) | (C67_map_regs(b) << 1)); | 387 | ((a & 0xffff) << 7) | (0x0a << 2) | (C67_map_regs(S, b) << 1)); |
| 388 | } else if (strstr(s, "MVKH") == s) { | 388 | } else if (strstr(s, "MVKH") == s) { |
| 389 | C67_g((C67_map_regn(b) << 23) | | 389 | C67_g(S, (C67_map_regn(S, b) << 23) | |
| 390 | (((a >> 16) & 0xffff) << 7) | | 390 | (((a >> 16) & 0xffff) << 7) | |
| 391 | (0x1a << 2) | (C67_map_regs(b) << 1)); | 391 | (0x1a << 2) | (C67_map_regs(S, b) << 1)); |
| 392 | } else if (strstr(s, "STW.D SP POST DEC") == s) { | 392 | } else if (strstr(s, "STW.D SP POST DEC") == s) { |
| 393 | C67_g((C67_map_regn(a) << 23) | //src | 393 | C67_g(S, (C67_map_regn(S, a) << 23) | //src |
| 394 | (15 << 18) | //SP B15 | 394 | (15 << 18) | //SP B15 |
| 395 | (2 << 13) | //ucst5 (must keep 8 byte boundary !!) | 395 | (2 << 13) | //ucst5 (must keep 8 byte boundary !!) |
| 396 | (0xa << 9) | //mode a = post dec ucst | 396 | (0xa << 9) | //mode a = post dec ucst |
| @@ -398,10 +398,10 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line | |||
| 398 | (1 << 7) | //y D1/D2 use B side | 398 | (1 << 7) | //y D1/D2 use B side |
| 399 | (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU | 399 | (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU |
| 400 | (1 << 2) | //opcode | 400 | (1 << 2) | //opcode |
| 401 | (C67_map_regs(a) << 1) | //side of src | 401 | (C67_map_regs(S, a) << 1) | //side of src |
| 402 | (0 << 0)); //parallel | 402 | (0 << 0)); //parallel |
| 403 | } else if (strstr(s, "STB.D *+SP[A0]") == s) { | 403 | } else if (strstr(s, "STB.D *+SP[A0]") == s) { |
| 404 | C67_g((C67_map_regn(a) << 23) | //src | 404 | C67_g(S, (C67_map_regn(S, a) << 23) | //src |
| 405 | (15 << 18) | //base reg A15 | 405 | (15 << 18) | //base reg A15 |
| 406 | (0 << 13) | //offset reg A0 | 406 | (0 << 13) | //offset reg A0 |
| 407 | (5 << 9) | //mode 5 = pos offset, base reg + off reg | 407 | (5 << 9) | //mode 5 = pos offset, base reg + off reg |
| @@ -409,10 +409,10 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line | |||
| 409 | (0 << 7) | //y D1/D2 A side | 409 | (0 << 7) | //y D1/D2 A side |
| 410 | (3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU | 410 | (3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU |
| 411 | (1 << 2) | //opcode | 411 | (1 << 2) | //opcode |
| 412 | (C67_map_regs(a) << 1) | //side of src | 412 | (C67_map_regs(S, a) << 1) | //side of src |
| 413 | (0 << 0)); //parallel | 413 | (0 << 0)); //parallel |
| 414 | } else if (strstr(s, "STH.D *+SP[A0]") == s) { | 414 | } else if (strstr(s, "STH.D *+SP[A0]") == s) { |
| 415 | C67_g((C67_map_regn(a) << 23) | //src | 415 | C67_g(S, (C67_map_regn(S, a) << 23) | //src |
| 416 | (15 << 18) | //base reg A15 | 416 | (15 << 18) | //base reg A15 |
| 417 | (0 << 13) | //offset reg A0 | 417 | (0 << 13) | //offset reg A0 |
| 418 | (5 << 9) | //mode 5 = pos offset, base reg + off reg | 418 | (5 << 9) | //mode 5 = pos offset, base reg + off reg |
| @@ -420,10 +420,10 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line | |||
| 420 | (0 << 7) | //y D1/D2 A side | 420 | (0 << 7) | //y D1/D2 A side |
| 421 | (5 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU | 421 | (5 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU |
| 422 | (1 << 2) | //opcode | 422 | (1 << 2) | //opcode |
| 423 | (C67_map_regs(a) << 1) | //side of src | 423 | (C67_map_regs(S, a) << 1) | //side of src |
| 424 | (0 << 0)); //parallel | 424 | (0 << 0)); //parallel |
| 425 | } else if (strstr(s, "STB.D *+SP[A0]") == s) { | 425 | } else if (strstr(s, "STB.D *+SP[A0]") == s) { |
| 426 | C67_g((C67_map_regn(a) << 23) | //src | 426 | C67_g(S, (C67_map_regn(S, a) << 23) | //src |
| 427 | (15 << 18) | //base reg A15 | 427 | (15 << 18) | //base reg A15 |
| 428 | (0 << 13) | //offset reg A0 | 428 | (0 << 13) | //offset reg A0 |
| 429 | (5 << 9) | //mode 5 = pos offset, base reg + off reg | 429 | (5 << 9) | //mode 5 = pos offset, base reg + off reg |
| @@ -431,10 +431,10 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line | |||
| 431 | (0 << 7) | //y D1/D2 A side | 431 | (0 << 7) | //y D1/D2 A side |
| 432 | (3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU | 432 | (3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU |
| 433 | (1 << 2) | //opcode | 433 | (1 << 2) | //opcode |
| 434 | (C67_map_regs(a) << 1) | //side of src | 434 | (C67_map_regs(S, a) << 1) | //side of src |
| 435 | (0 << 0)); //parallel | 435 | (0 << 0)); //parallel |
| 436 | } else if (strstr(s, "STH.D *+SP[A0]") == s) { | 436 | } else if (strstr(s, "STH.D *+SP[A0]") == s) { |
| 437 | C67_g((C67_map_regn(a) << 23) | //src | 437 | C67_g(S, (C67_map_regn(S, a) << 23) | //src |
| 438 | (15 << 18) | //base reg A15 | 438 | (15 << 18) | //base reg A15 |
| 439 | (0 << 13) | //offset reg A0 | 439 | (0 << 13) | //offset reg A0 |
| 440 | (5 << 9) | //mode 5 = pos offset, base reg + off reg | 440 | (5 << 9) | //mode 5 = pos offset, base reg + off reg |
| @@ -442,10 +442,10 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line | |||
| 442 | (0 << 7) | //y D1/D2 A side | 442 | (0 << 7) | //y D1/D2 A side |
| 443 | (5 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU | 443 | (5 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU |
| 444 | (1 << 2) | //opcode | 444 | (1 << 2) | //opcode |
| 445 | (C67_map_regs(a) << 1) | //side of src | 445 | (C67_map_regs(S, a) << 1) | //side of src |
| 446 | (0 << 0)); //parallel | 446 | (0 << 0)); //parallel |
| 447 | } else if (strstr(s, "STW.D *+SP[A0]") == s) { | 447 | } else if (strstr(s, "STW.D *+SP[A0]") == s) { |
| 448 | C67_g((C67_map_regn(a) << 23) | //src | 448 | C67_g(S, (C67_map_regn(S, a) << 23) | //src |
| 449 | (15 << 18) | //base reg A15 | 449 | (15 << 18) | //base reg A15 |
| 450 | (0 << 13) | //offset reg A0 | 450 | (0 << 13) | //offset reg A0 |
| 451 | (5 << 9) | //mode 5 = pos offset, base reg + off reg | 451 | (5 << 9) | //mode 5 = pos offset, base reg + off reg |
| @@ -453,55 +453,55 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line | |||
| 453 | (0 << 7) | //y D1/D2 A side | 453 | (0 << 7) | //y D1/D2 A side |
| 454 | (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU | 454 | (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU |
| 455 | (1 << 2) | //opcode | 455 | (1 << 2) | //opcode |
| 456 | (C67_map_regs(a) << 1) | //side of src | 456 | (C67_map_regs(S, a) << 1) | //side of src |
| 457 | (0 << 0)); //parallel | 457 | (0 << 0)); //parallel |
| 458 | } else if (strstr(s, "STW.D *") == s) { | 458 | } else if (strstr(s, "STW.D *") == s) { |
| 459 | C67_g((C67_map_regn(a) << 23) | //src | 459 | C67_g(S, (C67_map_regn(S, a) << 23) | //src |
| 460 | (C67_map_regn(b) << 18) | //base reg A0 | 460 | (C67_map_regn(S, b) << 18) | //base reg A0 |
| 461 | (0 << 13) | //cst5 | 461 | (0 << 13) | //cst5 |
| 462 | (1 << 9) | //mode 1 = pos cst offset | 462 | (1 << 9) | //mode 1 = pos cst offset |
| 463 | (0 << 8) | //r (LDDW bit 0) | 463 | (0 << 8) | //r (LDDW bit 0) |
| 464 | (C67_map_regs(b) << 7) | //y D1/D2 base reg side | 464 | (C67_map_regs(S, b) << 7) | //y D1/D2 base reg side |
| 465 | (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU | 465 | (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU |
| 466 | (1 << 2) | //opcode | 466 | (1 << 2) | //opcode |
| 467 | (C67_map_regs(a) << 1) | //side of src | 467 | (C67_map_regs(S, a) << 1) | //side of src |
| 468 | (0 << 0)); //parallel | 468 | (0 << 0)); //parallel |
| 469 | } else if (strstr(s, "STH.D *") == s) { | 469 | } else if (strstr(s, "STH.D *") == s) { |
| 470 | C67_g((C67_map_regn(a) << 23) | //src | 470 | C67_g(S, (C67_map_regn(S, a) << 23) | //src |
| 471 | (C67_map_regn(b) << 18) | //base reg A0 | 471 | (C67_map_regn(S, b) << 18) | //base reg A0 |
| 472 | (0 << 13) | //cst5 | 472 | (0 << 13) | //cst5 |
| 473 | (1 << 9) | //mode 1 = pos cst offset | 473 | (1 << 9) | //mode 1 = pos cst offset |
| 474 | (0 << 8) | //r (LDDW bit 0) | 474 | (0 << 8) | //r (LDDW bit 0) |
| 475 | (C67_map_regs(b) << 7) | //y D1/D2 base reg side | 475 | (C67_map_regs(S, b) << 7) | //y D1/D2 base reg side |
| 476 | (5 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU | 476 | (5 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU |
| 477 | (1 << 2) | //opcode | 477 | (1 << 2) | //opcode |
| 478 | (C67_map_regs(a) << 1) | //side of src | 478 | (C67_map_regs(S, a) << 1) | //side of src |
| 479 | (0 << 0)); //parallel | 479 | (0 << 0)); //parallel |
| 480 | } else if (strstr(s, "STB.D *") == s) { | 480 | } else if (strstr(s, "STB.D *") == s) { |
| 481 | C67_g((C67_map_regn(a) << 23) | //src | 481 | C67_g(S, (C67_map_regn(S, a) << 23) | //src |
| 482 | (C67_map_regn(b) << 18) | //base reg A0 | 482 | (C67_map_regn(S, b) << 18) | //base reg A0 |
| 483 | (0 << 13) | //cst5 | 483 | (0 << 13) | //cst5 |
| 484 | (1 << 9) | //mode 1 = pos cst offset | 484 | (1 << 9) | //mode 1 = pos cst offset |
| 485 | (0 << 8) | //r (LDDW bit 0) | 485 | (0 << 8) | //r (LDDW bit 0) |
| 486 | (C67_map_regs(b) << 7) | //y D1/D2 base reg side | 486 | (C67_map_regs(S, b) << 7) | //y D1/D2 base reg side |
| 487 | (3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU | 487 | (3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU |
| 488 | (1 << 2) | //opcode | 488 | (1 << 2) | //opcode |
| 489 | (C67_map_regs(a) << 1) | //side of src | 489 | (C67_map_regs(S, a) << 1) | //side of src |
| 490 | (0 << 0)); //parallel | 490 | (0 << 0)); //parallel |
| 491 | } else if (strstr(s, "STW.D +*") == s) { | 491 | } else if (strstr(s, "STW.D +*") == s) { |
| 492 | ALWAYS_ASSERT(c < 32); | 492 | ALWAYS_ASSERT(c < 32); |
| 493 | C67_g((C67_map_regn(a) << 23) | //src | 493 | C67_g(S, (C67_map_regn(S, a) << 23) | //src |
| 494 | (C67_map_regn(b) << 18) | //base reg A0 | 494 | (C67_map_regn(S, b) << 18) | //base reg A0 |
| 495 | (c << 13) | //cst5 | 495 | (c << 13) | //cst5 |
| 496 | (1 << 9) | //mode 1 = pos cst offset | 496 | (1 << 9) | //mode 1 = pos cst offset |
| 497 | (0 << 8) | //r (LDDW bit 0) | 497 | (0 << 8) | //r (LDDW bit 0) |
| 498 | (C67_map_regs(b) << 7) | //y D1/D2 base reg side | 498 | (C67_map_regs(S, b) << 7) | //y D1/D2 base reg side |
| 499 | (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU | 499 | (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU |
| 500 | (1 << 2) | //opcode | 500 | (1 << 2) | //opcode |
| 501 | (C67_map_regs(a) << 1) | //side of src | 501 | (C67_map_regs(S, a) << 1) | //side of src |
| 502 | (0 << 0)); //parallel | 502 | (0 << 0)); //parallel |
| 503 | } else if (strstr(s, "LDW.D SP PRE INC") == s) { | 503 | } else if (strstr(s, "LDW.D SP PRE INC") == s) { |
| 504 | C67_g((C67_map_regn(a) << 23) | //dst | 504 | C67_g(S, (C67_map_regn(S, a) << 23) | //dst |
| 505 | (15 << 18) | //base reg B15 | 505 | (15 << 18) | //base reg B15 |
| 506 | (2 << 13) | //ucst5 (must keep 8 byte boundary) | 506 | (2 << 13) | //ucst5 (must keep 8 byte boundary) |
| 507 | (9 << 9) | //mode 9 = pre inc ucst5 | 507 | (9 << 9) | //mode 9 = pre inc ucst5 |
| @@ -509,10 +509,10 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line | |||
| 509 | (1 << 7) | //y D1/D2 B side | 509 | (1 << 7) | //y D1/D2 B side |
| 510 | (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU | 510 | (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU |
| 511 | (1 << 2) | //opcode | 511 | (1 << 2) | //opcode |
| 512 | (C67_map_regs(a) << 1) | //side of dst | 512 | (C67_map_regs(S, a) << 1) | //side of dst |
| 513 | (0 << 0)); //parallel | 513 | (0 << 0)); //parallel |
| 514 | } else if (strstr(s, "LDDW.D SP PRE INC") == s) { | 514 | } else if (strstr(s, "LDDW.D SP PRE INC") == s) { |
| 515 | C67_g((C67_map_regn(a) << 23) | //dst | 515 | C67_g(S, (C67_map_regn(S, a) << 23) | //dst |
| 516 | (15 << 18) | //base reg B15 | 516 | (15 << 18) | //base reg B15 |
| 517 | (1 << 13) | //ucst5 (must keep 8 byte boundary) | 517 | (1 << 13) | //ucst5 (must keep 8 byte boundary) |
| 518 | (9 << 9) | //mode 9 = pre inc ucst5 | 518 | (9 << 9) | //mode 9 = pre inc ucst5 |
| @@ -520,10 +520,10 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line | |||
| 520 | (1 << 7) | //y D1/D2 B side | 520 | (1 << 7) | //y D1/D2 B side |
| 521 | (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU | 521 | (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU |
| 522 | (1 << 2) | //opcode | 522 | (1 << 2) | //opcode |
| 523 | (C67_map_regs(a) << 1) | //side of dst | 523 | (C67_map_regs(S, a) << 1) | //side of dst |
| 524 | (0 << 0)); //parallel | 524 | (0 << 0)); //parallel |
| 525 | } else if (strstr(s, "LDW.D *+SP[A0]") == s) { | 525 | } else if (strstr(s, "LDW.D *+SP[A0]") == s) { |
| 526 | C67_g((C67_map_regn(a) << 23) | //dst | 526 | C67_g(S, (C67_map_regn(S, a) << 23) | //dst |
| 527 | (15 << 18) | //base reg A15 | 527 | (15 << 18) | //base reg A15 |
| 528 | (0 << 13) | //offset reg A0 | 528 | (0 << 13) | //offset reg A0 |
| 529 | (5 << 9) | //mode 5 = pos offset, base reg + off reg | 529 | (5 << 9) | //mode 5 = pos offset, base reg + off reg |
| @@ -531,10 +531,10 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line | |||
| 531 | (0 << 7) | //y D1/D2 A side | 531 | (0 << 7) | //y D1/D2 A side |
| 532 | (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU | 532 | (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU |
| 533 | (1 << 2) | //opcode | 533 | (1 << 2) | //opcode |
| 534 | (C67_map_regs(a) << 1) | //side of dst | 534 | (C67_map_regs(S, a) << 1) | //side of dst |
| 535 | (0 << 0)); //parallel | 535 | (0 << 0)); //parallel |
| 536 | } else if (strstr(s, "LDDW.D *+SP[A0]") == s) { | 536 | } else if (strstr(s, "LDDW.D *+SP[A0]") == s) { |
| 537 | C67_g((C67_map_regn(a) << 23) | //dst | 537 | C67_g(S, (C67_map_regn(S, a) << 23) | //dst |
| 538 | (15 << 18) | //base reg A15 | 538 | (15 << 18) | //base reg A15 |
| 539 | (0 << 13) | //offset reg A0 | 539 | (0 << 13) | //offset reg A0 |
| 540 | (5 << 9) | //mode 5 = pos offset, base reg + off reg | 540 | (5 << 9) | //mode 5 = pos offset, base reg + off reg |
| @@ -542,10 +542,10 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line | |||
| 542 | (0 << 7) | //y D1/D2 A side | 542 | (0 << 7) | //y D1/D2 A side |
| 543 | (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU | 543 | (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU |
| 544 | (1 << 2) | //opcode | 544 | (1 << 2) | //opcode |
| 545 | (C67_map_regs(a) << 1) | //side of dst | 545 | (C67_map_regs(S, a) << 1) | //side of dst |
| 546 | (0 << 0)); //parallel | 546 | (0 << 0)); //parallel |
| 547 | } else if (strstr(s, "LDH.D *+SP[A0]") == s) { | 547 | } else if (strstr(s, "LDH.D *+SP[A0]") == s) { |
| 548 | C67_g((C67_map_regn(a) << 23) | //dst | 548 | C67_g(S, (C67_map_regn(S, a) << 23) | //dst |
| 549 | (15 << 18) | //base reg A15 | 549 | (15 << 18) | //base reg A15 |
| 550 | (0 << 13) | //offset reg A0 | 550 | (0 << 13) | //offset reg A0 |
| 551 | (5 << 9) | //mode 5 = pos offset, base reg + off reg | 551 | (5 << 9) | //mode 5 = pos offset, base reg + off reg |
| @@ -553,10 +553,10 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line | |||
| 553 | (0 << 7) | //y D1/D2 A side | 553 | (0 << 7) | //y D1/D2 A side |
| 554 | (4 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU | 554 | (4 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU |
| 555 | (1 << 2) | //opcode | 555 | (1 << 2) | //opcode |
| 556 | (C67_map_regs(a) << 1) | //side of dst | 556 | (C67_map_regs(S, a) << 1) | //side of dst |
| 557 | (0 << 0)); //parallel | 557 | (0 << 0)); //parallel |
| 558 | } else if (strstr(s, "LDB.D *+SP[A0]") == s) { | 558 | } else if (strstr(s, "LDB.D *+SP[A0]") == s) { |
| 559 | C67_g((C67_map_regn(a) << 23) | //dst | 559 | C67_g(S, (C67_map_regn(S, a) << 23) | //dst |
| 560 | (15 << 18) | //base reg A15 | 560 | (15 << 18) | //base reg A15 |
| 561 | (0 << 13) | //offset reg A0 | 561 | (0 << 13) | //offset reg A0 |
| 562 | (5 << 9) | //mode 5 = pos offset, base reg + off reg | 562 | (5 << 9) | //mode 5 = pos offset, base reg + off reg |
| @@ -564,10 +564,10 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line | |||
| 564 | (0 << 7) | //y D1/D2 A side | 564 | (0 << 7) | //y D1/D2 A side |
| 565 | (2 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU | 565 | (2 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU |
| 566 | (1 << 2) | //opcode | 566 | (1 << 2) | //opcode |
| 567 | (C67_map_regs(a) << 1) | //side of dst | 567 | (C67_map_regs(S, a) << 1) | //side of dst |
| 568 | (0 << 0)); //parallel | 568 | (0 << 0)); //parallel |
| 569 | } else if (strstr(s, "LDHU.D *+SP[A0]") == s) { | 569 | } else if (strstr(s, "LDHU.D *+SP[A0]") == s) { |
| 570 | C67_g((C67_map_regn(a) << 23) | //dst | 570 | C67_g(S, (C67_map_regn(S, a) << 23) | //dst |
| 571 | (15 << 18) | //base reg A15 | 571 | (15 << 18) | //base reg A15 |
| 572 | (0 << 13) | //offset reg A0 | 572 | (0 << 13) | //offset reg A0 |
| 573 | (5 << 9) | //mode 5 = pos offset, base reg + off reg | 573 | (5 << 9) | //mode 5 = pos offset, base reg + off reg |
| @@ -575,10 +575,10 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line | |||
| 575 | (0 << 7) | //y D1/D2 A side | 575 | (0 << 7) | //y D1/D2 A side |
| 576 | (0 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU | 576 | (0 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU |
| 577 | (1 << 2) | //opcode | 577 | (1 << 2) | //opcode |
| 578 | (C67_map_regs(a) << 1) | //side of dst | 578 | (C67_map_regs(S, a) << 1) | //side of dst |
| 579 | (0 << 0)); //parallel | 579 | (0 << 0)); //parallel |
| 580 | } else if (strstr(s, "LDBU.D *+SP[A0]") == s) { | 580 | } else if (strstr(s, "LDBU.D *+SP[A0]") == s) { |
| 581 | C67_g((C67_map_regn(a) << 23) | //dst | 581 | C67_g(S, (C67_map_regn(S, a) << 23) | //dst |
| 582 | (15 << 18) | //base reg A15 | 582 | (15 << 18) | //base reg A15 |
| 583 | (0 << 13) | //offset reg A0 | 583 | (0 << 13) | //offset reg A0 |
| 584 | (5 << 9) | //mode 5 = pos offset, base reg + off reg | 584 | (5 << 9) | //mode 5 = pos offset, base reg + off reg |
| @@ -586,233 +586,233 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line | |||
| 586 | (0 << 7) | //y D1/D2 A side | 586 | (0 << 7) | //y D1/D2 A side |
| 587 | (1 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU | 587 | (1 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU |
| 588 | (1 << 2) | //opcode | 588 | (1 << 2) | //opcode |
| 589 | (C67_map_regs(a) << 1) | //side of dst | 589 | (C67_map_regs(S, a) << 1) | //side of dst |
| 590 | (0 << 0)); //parallel | 590 | (0 << 0)); //parallel |
| 591 | } else if (strstr(s, "LDW.D *") == s) { | 591 | } else if (strstr(s, "LDW.D *") == s) { |
| 592 | C67_g((C67_map_regn(b) << 23) | //dst | 592 | C67_g(S, (C67_map_regn(S, b) << 23) | //dst |
| 593 | (C67_map_regn(a) << 18) | //base reg A15 | 593 | (C67_map_regn(S, a) << 18) | //base reg A15 |
| 594 | (0 << 13) | //cst5 | 594 | (0 << 13) | //cst5 |
| 595 | (1 << 9) | //mode 1 = pos cst offset | 595 | (1 << 9) | //mode 1 = pos cst offset |
| 596 | (0 << 8) | //r (LDDW bit 0) | 596 | (0 << 8) | //r (LDDW bit 0) |
| 597 | (C67_map_regs(a) << 7) | //y D1/D2 src side | 597 | (C67_map_regs(S, a) << 7) | //y D1/D2 src side |
| 598 | (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU | 598 | (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU |
| 599 | (1 << 2) | //opcode | 599 | (1 << 2) | //opcode |
| 600 | (C67_map_regs(b) << 1) | //side of dst | 600 | (C67_map_regs(S, b) << 1) | //side of dst |
| 601 | (0 << 0)); //parallel | 601 | (0 << 0)); //parallel |
| 602 | } else if (strstr(s, "LDDW.D *") == s) { | 602 | } else if (strstr(s, "LDDW.D *") == s) { |
| 603 | C67_g((C67_map_regn(b) << 23) | //dst | 603 | C67_g(S, (C67_map_regn(S, b) << 23) | //dst |
| 604 | (C67_map_regn(a) << 18) | //base reg A15 | 604 | (C67_map_regn(S, a) << 18) | //base reg A15 |
| 605 | (0 << 13) | //cst5 | 605 | (0 << 13) | //cst5 |
| 606 | (1 << 9) | //mode 1 = pos cst offset | 606 | (1 << 9) | //mode 1 = pos cst offset |
| 607 | (1 << 8) | //r (LDDW bit 1) | 607 | (1 << 8) | //r (LDDW bit 1) |
| 608 | (C67_map_regs(a) << 7) | //y D1/D2 src side | 608 | (C67_map_regs(S, a) << 7) | //y D1/D2 src side |
| 609 | (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU | 609 | (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU |
| 610 | (1 << 2) | //opcode | 610 | (1 << 2) | //opcode |
| 611 | (C67_map_regs(b) << 1) | //side of dst | 611 | (C67_map_regs(S, b) << 1) | //side of dst |
| 612 | (0 << 0)); //parallel | 612 | (0 << 0)); //parallel |
| 613 | } else if (strstr(s, "LDH.D *") == s) { | 613 | } else if (strstr(s, "LDH.D *") == s) { |
| 614 | C67_g((C67_map_regn(b) << 23) | //dst | 614 | C67_g(S, (C67_map_regn(S, b) << 23) | //dst |
| 615 | (C67_map_regn(a) << 18) | //base reg A15 | 615 | (C67_map_regn(S, a) << 18) | //base reg A15 |
| 616 | (0 << 13) | //cst5 | 616 | (0 << 13) | //cst5 |
| 617 | (1 << 9) | //mode 1 = pos cst offset | 617 | (1 << 9) | //mode 1 = pos cst offset |
| 618 | (0 << 8) | //r (LDDW bit 0) | 618 | (0 << 8) | //r (LDDW bit 0) |
| 619 | (C67_map_regs(a) << 7) | //y D1/D2 src side | 619 | (C67_map_regs(S, a) << 7) | //y D1/D2 src side |
| 620 | (4 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU | 620 | (4 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU |
| 621 | (1 << 2) | //opcode | 621 | (1 << 2) | //opcode |
| 622 | (C67_map_regs(b) << 1) | //side of dst | 622 | (C67_map_regs(S, b) << 1) | //side of dst |
| 623 | (0 << 0)); //parallel | 623 | (0 << 0)); //parallel |
| 624 | } else if (strstr(s, "LDB.D *") == s) { | 624 | } else if (strstr(s, "LDB.D *") == s) { |
| 625 | C67_g((C67_map_regn(b) << 23) | //dst | 625 | C67_g(S, (C67_map_regn(S, b) << 23) | //dst |
| 626 | (C67_map_regn(a) << 18) | //base reg A15 | 626 | (C67_map_regn(S, a) << 18) | //base reg A15 |
| 627 | (0 << 13) | //cst5 | 627 | (0 << 13) | //cst5 |
| 628 | (1 << 9) | //mode 1 = pos cst offset | 628 | (1 << 9) | //mode 1 = pos cst offset |
| 629 | (0 << 8) | //r (LDDW bit 0) | 629 | (0 << 8) | //r (LDDW bit 0) |
| 630 | (C67_map_regs(a) << 7) | //y D1/D2 src side | 630 | (C67_map_regs(S, a) << 7) | //y D1/D2 src side |
| 631 | (2 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU | 631 | (2 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU |
| 632 | (1 << 2) | //opcode | 632 | (1 << 2) | //opcode |
| 633 | (C67_map_regs(b) << 1) | //side of dst | 633 | (C67_map_regs(S, b) << 1) | //side of dst |
| 634 | (0 << 0)); //parallel | 634 | (0 << 0)); //parallel |
| 635 | } else if (strstr(s, "LDHU.D *") == s) { | 635 | } else if (strstr(s, "LDHU.D *") == s) { |
| 636 | C67_g((C67_map_regn(b) << 23) | //dst | 636 | C67_g(S, (C67_map_regn(S, b) << 23) | //dst |
| 637 | (C67_map_regn(a) << 18) | //base reg A15 | 637 | (C67_map_regn(S, a) << 18) | //base reg A15 |
| 638 | (0 << 13) | //cst5 | 638 | (0 << 13) | //cst5 |
| 639 | (1 << 9) | //mode 1 = pos cst offset | 639 | (1 << 9) | //mode 1 = pos cst offset |
| 640 | (0 << 8) | //r (LDDW bit 0) | 640 | (0 << 8) | //r (LDDW bit 0) |
| 641 | (C67_map_regs(a) << 7) | //y D1/D2 src side | 641 | (C67_map_regs(S, a) << 7) | //y D1/D2 src side |
| 642 | (0 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU | 642 | (0 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU |
| 643 | (1 << 2) | //opcode | 643 | (1 << 2) | //opcode |
| 644 | (C67_map_regs(b) << 1) | //side of dst | 644 | (C67_map_regs(S, b) << 1) | //side of dst |
| 645 | (0 << 0)); //parallel | 645 | (0 << 0)); //parallel |
| 646 | } else if (strstr(s, "LDBU.D *") == s) { | 646 | } else if (strstr(s, "LDBU.D *") == s) { |
| 647 | C67_g((C67_map_regn(b) << 23) | //dst | 647 | C67_g(S, (C67_map_regn(S, b) << 23) | //dst |
| 648 | (C67_map_regn(a) << 18) | //base reg A15 | 648 | (C67_map_regn(S, a) << 18) | //base reg A15 |
| 649 | (0 << 13) | //cst5 | 649 | (0 << 13) | //cst5 |
| 650 | (1 << 9) | //mode 1 = pos cst offset | 650 | (1 << 9) | //mode 1 = pos cst offset |
| 651 | (0 << 8) | //r (LDDW bit 0) | 651 | (0 << 8) | //r (LDDW bit 0) |
| 652 | (C67_map_regs(a) << 7) | //y D1/D2 src side | 652 | (C67_map_regs(S, a) << 7) | //y D1/D2 src side |
| 653 | (1 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU | 653 | (1 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU |
| 654 | (1 << 2) | //opcode | 654 | (1 << 2) | //opcode |
| 655 | (C67_map_regs(b) << 1) | //side of dst | 655 | (C67_map_regs(S, b) << 1) | //side of dst |
| 656 | (0 << 0)); //parallel | 656 | (0 << 0)); //parallel |
| 657 | } else if (strstr(s, "LDW.D +*") == s) { | 657 | } else if (strstr(s, "LDW.D +*") == s) { |
| 658 | C67_g((C67_map_regn(b) << 23) | //dst | 658 | C67_g(S, (C67_map_regn(S, b) << 23) | //dst |
| 659 | (C67_map_regn(a) << 18) | //base reg A15 | 659 | (C67_map_regn(S, a) << 18) | //base reg A15 |
| 660 | (1 << 13) | //cst5 | 660 | (1 << 13) | //cst5 |
| 661 | (1 << 9) | //mode 1 = pos cst offset | 661 | (1 << 9) | //mode 1 = pos cst offset |
| 662 | (0 << 8) | //r (LDDW bit 0) | 662 | (0 << 8) | //r (LDDW bit 0) |
| 663 | (C67_map_regs(a) << 7) | //y D1/D2 src side | 663 | (C67_map_regs(S, a) << 7) | //y D1/D2 src side |
| 664 | (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU | 664 | (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU |
| 665 | (1 << 2) | //opcode | 665 | (1 << 2) | //opcode |
| 666 | (C67_map_regs(b) << 1) | //side of dst | 666 | (C67_map_regs(S, b) << 1) | //side of dst |
| 667 | (0 << 0)); //parallel | 667 | (0 << 0)); //parallel |
| 668 | } else if (strstr(s, "CMPLTSP") == s) { | 668 | } else if (strstr(s, "CMPLTSP") == s) { |
| 669 | xpath = C67_map_regs(a) ^ C67_map_regs(b); | 669 | xpath = C67_map_regs(S, a) ^ C67_map_regs(S, b); |
| 670 | ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a)); | 670 | ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a)); |
| 671 | 671 | ||
| 672 | C67_g((C67_map_regn(c) << 23) | //dst | 672 | C67_g(S, (C67_map_regn(S, c) << 23) | //dst |
| 673 | (C67_map_regn(b) << 18) | //src2 | 673 | (C67_map_regn(S, b) << 18) | //src2 |
| 674 | (C67_map_regn(a) << 13) | //src1 | 674 | (C67_map_regn(S, a) << 13) | //src1 |
| 675 | (xpath << 12) | //x use cross path for src2 | 675 | (xpath << 12) | //x use cross path for src2 |
| 676 | (0x3a << 6) | //opcode | 676 | (0x3a << 6) | //opcode |
| 677 | (0x8 << 2) | //opcode fixed | 677 | (0x8 << 2) | //opcode fixed |
| 678 | (C67_map_regs(c) << 1) | //side for reg c | 678 | (C67_map_regs(S, c) << 1) | //side for reg c |
| 679 | (0 << 0)); //parallel | 679 | (0 << 0)); //parallel |
| 680 | } else if (strstr(s, "CMPGTSP") == s) { | 680 | } else if (strstr(s, "CMPGTSP") == s) { |
| 681 | xpath = C67_map_regs(a) ^ C67_map_regs(b); | 681 | xpath = C67_map_regs(S, a) ^ C67_map_regs(S, b); |
| 682 | ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a)); | 682 | ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a)); |
| 683 | 683 | ||
| 684 | C67_g((C67_map_regn(c) << 23) | //dst | 684 | C67_g(S, (C67_map_regn(S, c) << 23) | //dst |
| 685 | (C67_map_regn(b) << 18) | //src2 | 685 | (C67_map_regn(S, b) << 18) | //src2 |
| 686 | (C67_map_regn(a) << 13) | //src1 | 686 | (C67_map_regn(S, a) << 13) | //src1 |
| 687 | (xpath << 12) | //x use cross path for src2 | 687 | (xpath << 12) | //x use cross path for src2 |
| 688 | (0x39 << 6) | //opcode | 688 | (0x39 << 6) | //opcode |
| 689 | (0x8 << 2) | //opcode fixed | 689 | (0x8 << 2) | //opcode fixed |
| 690 | (C67_map_regs(c) << 1) | //side for reg c | 690 | (C67_map_regs(S, c) << 1) | //side for reg c |
| 691 | (0 << 0)); //parallel | 691 | (0 << 0)); //parallel |
| 692 | } else if (strstr(s, "CMPEQSP") == s) { | 692 | } else if (strstr(s, "CMPEQSP") == s) { |
| 693 | xpath = C67_map_regs(a) ^ C67_map_regs(b); | 693 | xpath = C67_map_regs(S, a) ^ C67_map_regs(S, b); |
| 694 | ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a)); | 694 | ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a)); |
| 695 | 695 | ||
| 696 | C67_g((C67_map_regn(c) << 23) | //dst | 696 | C67_g(S, (C67_map_regn(S, c) << 23) | //dst |
| 697 | (C67_map_regn(b) << 18) | //src2 | 697 | (C67_map_regn(S, b) << 18) | //src2 |
| 698 | (C67_map_regn(a) << 13) | //src1 | 698 | (C67_map_regn(S, a) << 13) | //src1 |
| 699 | (xpath << 12) | //x use cross path for src2 | 699 | (xpath << 12) | //x use cross path for src2 |
| 700 | (0x38 << 6) | //opcode | 700 | (0x38 << 6) | //opcode |
| 701 | (0x8 << 2) | //opcode fixed | 701 | (0x8 << 2) | //opcode fixed |
| 702 | (C67_map_regs(c) << 1) | //side for reg c | 702 | (C67_map_regs(S, c) << 1) | //side for reg c |
| 703 | (0 << 0)); //parallel | 703 | (0 << 0)); //parallel |
| 704 | } | 704 | } |
| 705 | 705 | ||
| 706 | else if (strstr(s, "CMPLTDP") == s) { | 706 | else if (strstr(s, "CMPLTDP") == s) { |
| 707 | xpath = C67_map_regs(a) ^ C67_map_regs(b); | 707 | xpath = C67_map_regs(S, a) ^ C67_map_regs(S, b); |
| 708 | ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a)); | 708 | ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a)); |
| 709 | 709 | ||
| 710 | C67_g((C67_map_regn(c) << 23) | //dst | 710 | C67_g(S, (C67_map_regn(S, c) << 23) | //dst |
| 711 | (C67_map_regn(b) << 18) | //src2 | 711 | (C67_map_regn(S, b) << 18) | //src2 |
| 712 | (C67_map_regn(a) << 13) | //src1 | 712 | (C67_map_regn(S, a) << 13) | //src1 |
| 713 | (xpath << 12) | //x use cross path for src2 | 713 | (xpath << 12) | //x use cross path for src2 |
| 714 | (0x2a << 6) | //opcode | 714 | (0x2a << 6) | //opcode |
| 715 | (0x8 << 2) | //opcode fixed | 715 | (0x8 << 2) | //opcode fixed |
| 716 | (C67_map_regs(c) << 1) | //side for reg c | 716 | (C67_map_regs(S, c) << 1) | //side for reg c |
| 717 | (0 << 0)); //parallel | 717 | (0 << 0)); //parallel |
| 718 | } else if (strstr(s, "CMPGTDP") == s) { | 718 | } else if (strstr(s, "CMPGTDP") == s) { |
| 719 | xpath = C67_map_regs(a) ^ C67_map_regs(b); | 719 | xpath = C67_map_regs(S, a) ^ C67_map_regs(S, b); |
| 720 | ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a)); | 720 | ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a)); |
| 721 | 721 | ||
| 722 | C67_g((C67_map_regn(c) << 23) | //dst | 722 | C67_g(S, (C67_map_regn(S, c) << 23) | //dst |
| 723 | (C67_map_regn(b) << 18) | //src2 | 723 | (C67_map_regn(S, b) << 18) | //src2 |
| 724 | (C67_map_regn(a) << 13) | //src1 | 724 | (C67_map_regn(S, a) << 13) | //src1 |
| 725 | (xpath << 12) | //x use cross path for src2 | 725 | (xpath << 12) | //x use cross path for src2 |
| 726 | (0x29 << 6) | //opcode | 726 | (0x29 << 6) | //opcode |
| 727 | (0x8 << 2) | //opcode fixed | 727 | (0x8 << 2) | //opcode fixed |
| 728 | (C67_map_regs(c) << 1) | //side for reg c | 728 | (C67_map_regs(S, c) << 1) | //side for reg c |
| 729 | (0 << 0)); //parallel | 729 | (0 << 0)); //parallel |
| 730 | } else if (strstr(s, "CMPEQDP") == s) { | 730 | } else if (strstr(s, "CMPEQDP") == s) { |
| 731 | xpath = C67_map_regs(a) ^ C67_map_regs(b); | 731 | xpath = C67_map_regs(S, a) ^ C67_map_regs(S, b); |
| 732 | ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a)); | 732 | ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a)); |
| 733 | 733 | ||
| 734 | C67_g((C67_map_regn(c) << 23) | //dst | 734 | C67_g(S, (C67_map_regn(S, c) << 23) | //dst |
| 735 | (C67_map_regn(b) << 18) | //src2 | 735 | (C67_map_regn(S, b) << 18) | //src2 |
| 736 | (C67_map_regn(a) << 13) | //src1 | 736 | (C67_map_regn(S, a) << 13) | //src1 |
| 737 | (xpath << 12) | //x use cross path for src2 | 737 | (xpath << 12) | //x use cross path for src2 |
| 738 | (0x28 << 6) | //opcode | 738 | (0x28 << 6) | //opcode |
| 739 | (0x8 << 2) | //opcode fixed | 739 | (0x8 << 2) | //opcode fixed |
| 740 | (C67_map_regs(c) << 1) | //side for reg c | 740 | (C67_map_regs(S, c) << 1) | //side for reg c |
| 741 | (0 << 0)); //parallel | 741 | (0 << 0)); //parallel |
| 742 | } else if (strstr(s, "CMPLT") == s) { | 742 | } else if (strstr(s, "CMPLT") == s) { |
| 743 | xpath = C67_map_regs(a) ^ C67_map_regs(b); | 743 | xpath = C67_map_regs(S, a) ^ C67_map_regs(S, b); |
| 744 | ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a)); | 744 | ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a)); |
| 745 | 745 | ||
| 746 | C67_g((C67_map_regn(c) << 23) | //dst | 746 | C67_g(S, (C67_map_regn(S, c) << 23) | //dst |
| 747 | (C67_map_regn(b) << 18) | //src2 | 747 | (C67_map_regn(S, b) << 18) | //src2 |
| 748 | (C67_map_regn(a) << 13) | //src1 | 748 | (C67_map_regn(S, a) << 13) | //src1 |
| 749 | (xpath << 12) | //x use cross path for src2 | 749 | (xpath << 12) | //x use cross path for src2 |
| 750 | (0x57 << 5) | //opcode | 750 | (0x57 << 5) | //opcode |
| 751 | (0x6 << 2) | //opcode fixed | 751 | (0x6 << 2) | //opcode fixed |
| 752 | (C67_map_regs(c) << 1) | //side for reg c | 752 | (C67_map_regs(S, c) << 1) | //side for reg c |
| 753 | (0 << 0)); //parallel | 753 | (0 << 0)); //parallel |
| 754 | } else if (strstr(s, "CMPGT") == s) { | 754 | } else if (strstr(s, "CMPGT") == s) { |
| 755 | xpath = C67_map_regs(a) ^ C67_map_regs(b); | 755 | xpath = C67_map_regs(S, a) ^ C67_map_regs(S, b); |
| 756 | ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a)); | 756 | ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a)); |
| 757 | 757 | ||
| 758 | C67_g((C67_map_regn(c) << 23) | //dst | 758 | C67_g(S, (C67_map_regn(S, c) << 23) | //dst |
| 759 | (C67_map_regn(b) << 18) | //src2 | 759 | (C67_map_regn(S, b) << 18) | //src2 |
| 760 | (C67_map_regn(a) << 13) | //src1 | 760 | (C67_map_regn(S, a) << 13) | //src1 |
| 761 | (xpath << 12) | //x use cross path for src2 | 761 | (xpath << 12) | //x use cross path for src2 |
| 762 | (0x47 << 5) | //opcode | 762 | (0x47 << 5) | //opcode |
| 763 | (0x6 << 2) | //opcode fixed | 763 | (0x6 << 2) | //opcode fixed |
| 764 | (C67_map_regs(c) << 1) | //side for reg c | 764 | (C67_map_regs(S, c) << 1) | //side for reg c |
| 765 | (0 << 0)); //parallel | 765 | (0 << 0)); //parallel |
| 766 | } else if (strstr(s, "CMPEQ") == s) { | 766 | } else if (strstr(s, "CMPEQ") == s) { |
| 767 | xpath = C67_map_regs(a) ^ C67_map_regs(b); | 767 | xpath = C67_map_regs(S, a) ^ C67_map_regs(S, b); |
| 768 | ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a)); | 768 | ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a)); |
| 769 | 769 | ||
| 770 | C67_g((C67_map_regn(c) << 23) | //dst | 770 | C67_g(S, (C67_map_regn(S, c) << 23) | //dst |
| 771 | (C67_map_regn(b) << 18) | //src2 | 771 | (C67_map_regn(S, b) << 18) | //src2 |
| 772 | (C67_map_regn(a) << 13) | //src1 | 772 | (C67_map_regn(S, a) << 13) | //src1 |
| 773 | (xpath << 12) | //x use cross path for src2 | 773 | (xpath << 12) | //x use cross path for src2 |
| 774 | (0x53 << 5) | //opcode | 774 | (0x53 << 5) | //opcode |
| 775 | (0x6 << 2) | //opcode fixed | 775 | (0x6 << 2) | //opcode fixed |
| 776 | (C67_map_regs(c) << 1) | //side for reg c | 776 | (C67_map_regs(S, c) << 1) | //side for reg c |
| 777 | (0 << 0)); //parallel | 777 | (0 << 0)); //parallel |
| 778 | } else if (strstr(s, "CMPLTU") == s) { | 778 | } else if (strstr(s, "CMPLTU") == s) { |
| 779 | xpath = C67_map_regs(a) ^ C67_map_regs(b); | 779 | xpath = C67_map_regs(S, a) ^ C67_map_regs(S, b); |
| 780 | ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a)); | 780 | ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a)); |
| 781 | 781 | ||
| 782 | C67_g((C67_map_regn(c) << 23) | //dst | 782 | C67_g(S, (C67_map_regn(S, c) << 23) | //dst |
| 783 | (C67_map_regn(b) << 18) | //src2 | 783 | (C67_map_regn(S, b) << 18) | //src2 |
| 784 | (C67_map_regn(a) << 13) | //src1 | 784 | (C67_map_regn(S, a) << 13) | //src1 |
| 785 | (xpath << 12) | //x use cross path for src2 | 785 | (xpath << 12) | //x use cross path for src2 |
| 786 | (0x5f << 5) | //opcode | 786 | (0x5f << 5) | //opcode |
| 787 | (0x6 << 2) | //opcode fixed | 787 | (0x6 << 2) | //opcode fixed |
| 788 | (C67_map_regs(c) << 1) | //side for reg c | 788 | (C67_map_regs(S, c) << 1) | //side for reg c |
| 789 | (0 << 0)); //parallel | 789 | (0 << 0)); //parallel |
| 790 | } else if (strstr(s, "CMPGTU") == s) { | 790 | } else if (strstr(s, "CMPGTU") == s) { |
| 791 | xpath = C67_map_regs(a) ^ C67_map_regs(b); | 791 | xpath = C67_map_regs(S, a) ^ C67_map_regs(S, b); |
| 792 | ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a)); | 792 | ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a)); |
| 793 | 793 | ||
| 794 | C67_g((C67_map_regn(c) << 23) | //dst | 794 | C67_g(S, (C67_map_regn(S, c) << 23) | //dst |
| 795 | (C67_map_regn(b) << 18) | //src2 | 795 | (C67_map_regn(S, b) << 18) | //src2 |
| 796 | (C67_map_regn(a) << 13) | //src1 | 796 | (C67_map_regn(S, a) << 13) | //src1 |
| 797 | (xpath << 12) | //x use cross path for src2 | 797 | (xpath << 12) | //x use cross path for src2 |
| 798 | (0x4f << 5) | //opcode | 798 | (0x4f << 5) | //opcode |
| 799 | (0x6 << 2) | //opcode fixed | 799 | (0x6 << 2) | //opcode fixed |
| 800 | (C67_map_regs(c) << 1) | //side for reg c | 800 | (C67_map_regs(S, c) << 1) | //side for reg c |
| 801 | (0 << 0)); //parallel | 801 | (0 << 0)); //parallel |
| 802 | } else if (strstr(s, "B DISP") == s) { | 802 | } else if (strstr(s, "B DISP") == s) { |
| 803 | C67_g((0 << 29) | //creg | 803 | C67_g(S, (0 << 29) | //creg |
| 804 | (0 << 28) | //z | 804 | (0 << 28) | //z |
| 805 | (a << 7) | //cnst | 805 | (a << 7) | //cnst |
| 806 | (0x4 << 2) | //opcode fixed | 806 | (0x4 << 2) | //opcode fixed |
| 807 | (0 << 1) | //S0/S1 | 807 | (0 << 1) | //S0/S1 |
| 808 | (0 << 0)); //parallel | 808 | (0 << 0)); //parallel |
| 809 | } else if (strstr(s, "B.") == s) { | 809 | } else if (strstr(s, "B.") == s) { |
| 810 | xpath = C67_map_regs(c) ^ 1; | 810 | xpath = C67_map_regs(S, c) ^ 1; |
| 811 | 811 | ||
| 812 | C67_g((C67_map_regc(b) << 29) | //creg | 812 | C67_g(S, (C67_map_regc(S, b) << 29) | //creg |
| 813 | (a << 28) | //inv | 813 | (a << 28) | //inv |
| 814 | (0 << 23) | //dst | 814 | (0 << 23) | //dst |
| 815 | (C67_map_regn(c) << 18) | //src2 | 815 | (C67_map_regn(S, c) << 18) | //src2 |
| 816 | (0 << 13) | // | 816 | (0 << 13) | // |
| 817 | (xpath << 12) | //x cross path if !B side | 817 | (xpath << 12) | //x cross path if !B side |
| 818 | (0xd << 6) | //opcode | 818 | (0xd << 6) | //opcode |
| @@ -820,369 +820,369 @@ void C67_asm(const char *s, int a, int b, int c) · 1 unmodified line | |||
| 820 | (1 << 1) | //must be S2 | 820 | (1 << 1) | //must be S2 |
| 821 | (0 << 0)); //parallel | 821 | (0 << 0)); //parallel |
| 822 | } else if (strstr(s, "MV.L") == s) { | 822 | } else if (strstr(s, "MV.L") == s) { |
| 823 | xpath = C67_map_regs(b) ^ C67_map_regs(c); | 823 | xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c); |
| 824 | 824 | ||
| 825 | C67_g((0 << 29) | //creg | 825 | C67_g(S, (0 << 29) | //creg |
| 826 | (0 << 28) | //inv | 826 | (0 << 28) | //inv |
| 827 | (C67_map_regn(c) << 23) | //dst | 827 | (C67_map_regn(S, c) << 23) | //dst |
| 828 | (C67_map_regn(b) << 18) | //src2 | 828 | (C67_map_regn(S, b) << 18) | //src2 |
| 829 | (0 << 13) | //src1 (cst5) | 829 | (0 << 13) | //src1 (cst5) |
| 830 | (xpath << 12) | //x cross path if opposite sides | 830 | (xpath << 12) | //x cross path if opposite sides |
| 831 | (0x2 << 5) | //opcode | 831 | (0x2 << 5) | //opcode |
| 832 | (0x6 << 2) | //opcode fixed | 832 | (0x6 << 2) | //opcode fixed |
| 833 | (C67_map_regs(c) << 1) | //side of dest | 833 | (C67_map_regs(S, c) << 1) | //side of dest |
| 834 | (0 << 0)); //parallel | 834 | (0 << 0)); //parallel |
| 835 | } else if (strstr(s, "SPTRUNC.L") == s) { | 835 | } else if (strstr(s, "SPTRUNC.L") == s) { |
| 836 | xpath = C67_map_regs(b) ^ C67_map_regs(c); | 836 | xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c); |
| 837 | 837 | ||
| 838 | C67_g((0 << 29) | //creg | 838 | C67_g(S, (0 << 29) | //creg |
| 839 | (0 << 28) | //inv | 839 | (0 << 28) | //inv |
| 840 | (C67_map_regn(c) << 23) | //dst | 840 | (C67_map_regn(S, c) << 23) | //dst |
| 841 | (C67_map_regn(b) << 18) | //src2 | 841 | (C67_map_regn(S, b) << 18) | //src2 |
| 842 | (0 << 13) | //src1 NA | 842 | (0 << 13) | //src1 NA |
| 843 | (xpath << 12) | //x cross path if opposite sides | 843 | (xpath << 12) | //x cross path if opposite sides |
| 844 | (0xb << 5) | //opcode | 844 | (0xb << 5) | //opcode |
| 845 | (0x6 << 2) | //opcode fixed | 845 | (0x6 << 2) | //opcode fixed |
| 846 | (C67_map_regs(c) << 1) | //side of dest | 846 | (C67_map_regs(S, c) << 1) | //side of dest |
| 847 | (0 << 0)); //parallel | 847 | (0 << 0)); //parallel |
| 848 | } else if (strstr(s, "DPTRUNC.L") == s) { | 848 | } else if (strstr(s, "DPTRUNC.L") == s) { |
| 849 | xpath = C67_map_regs(b) ^ C67_map_regs(c); | 849 | xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c); |
| 850 | 850 | ||
| 851 | C67_g((0 << 29) | //creg | 851 | C67_g(S, (0 << 29) | //creg |
| 852 | (0 << 28) | //inv | 852 | (0 << 28) | //inv |
| 853 | (C67_map_regn(c) << 23) | //dst | 853 | (C67_map_regn(S, c) << 23) | //dst |
| 854 | ((C67_map_regn(b) + 1) << 18) | //src2 WEIRD CPU must specify odd reg for some reason | 854 | ((C67_map_regn(S, b) + 1) << 18) | //src2 WEIRD CPU must specify odd reg for some reason |
| 855 | (0 << 13) | //src1 NA | 855 | (0 << 13) | //src1 NA |
| 856 | (xpath << 12) | //x cross path if opposite sides | 856 | (xpath << 12) | //x cross path if opposite sides |
| 857 | (0x1 << 5) | //opcode | 857 | (0x1 << 5) | //opcode |
| 858 | (0x6 << 2) | //opcode fixed | 858 | (0x6 << 2) | //opcode fixed |
| 859 | (C67_map_regs(c) << 1) | //side of dest | 859 | (C67_map_regs(S, c) << 1) | //side of dest |
| 860 | (0 << 0)); //parallel | 860 | (0 << 0)); //parallel |
| 861 | } else if (strstr(s, "INTSP.L") == s) { | 861 | } else if (strstr(s, "INTSP.L") == s) { |
| 862 | xpath = C67_map_regs(b) ^ C67_map_regs(c); | 862 | xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c); |
| 863 | 863 | ||
| 864 | C67_g((0 << 29) | //creg | 864 | C67_g(S, (0 << 29) | //creg |
| 865 | (0 << 28) | //inv | 865 | (0 << 28) | //inv |
| 866 | (C67_map_regn(c) << 23) | //dst | 866 | (C67_map_regn(S, c) << 23) | //dst |
| 867 | (C67_map_regn(b) << 18) | //src2 | 867 | (C67_map_regn(S, b) << 18) | //src2 |
| 868 | (0 << 13) | //src1 NA | 868 | (0 << 13) | //src1 NA |
| 869 | (xpath << 12) | //x cross path if opposite sides | 869 | (xpath << 12) | //x cross path if opposite sides |
| 870 | (0x4a << 5) | //opcode | 870 | (0x4a << 5) | //opcode |
| 871 | (0x6 << 2) | //opcode fixed | 871 | (0x6 << 2) | //opcode fixed |
| 872 | (C67_map_regs(c) << 1) | //side of dest | 872 | (C67_map_regs(S, c) << 1) | //side of dest |
| 873 | (0 << 0)); //parallel | 873 | (0 << 0)); //parallel |
| 874 | } else if (strstr(s, "INTSPU.L") == s) { | 874 | } else if (strstr(s, "INTSPU.L") == s) { |
| 875 | xpath = C67_map_regs(b) ^ C67_map_regs(c); | 875 | xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c); |
| 876 | 876 | ||
| 877 | C67_g((0 << 29) | //creg | 877 | C67_g(S, (0 << 29) | //creg |
| 878 | (0 << 28) | //inv | 878 | (0 << 28) | //inv |
| 879 | (C67_map_regn(c) << 23) | //dst | 879 | (C67_map_regn(S, c) << 23) | //dst |
| 880 | (C67_map_regn(b) << 18) | //src2 | 880 | (C67_map_regn(S, b) << 18) | //src2 |
| 881 | (0 << 13) | //src1 NA | 881 | (0 << 13) | //src1 NA |
| 882 | (xpath << 12) | //x cross path if opposite sides | 882 | (xpath << 12) | //x cross path if opposite sides |
| 883 | (0x49 << 5) | //opcode | 883 | (0x49 << 5) | //opcode |
| 884 | (0x6 << 2) | //opcode fixed | 884 | (0x6 << 2) | //opcode fixed |
| 885 | (C67_map_regs(c) << 1) | //side of dest | 885 | (C67_map_regs(S, c) << 1) | //side of dest |
| 886 | (0 << 0)); //parallel | 886 | (0 << 0)); //parallel |
| 887 | } else if (strstr(s, "INTDP.L") == s) { | 887 | } else if (strstr(s, "INTDP.L") == s) { |
| 888 | xpath = C67_map_regs(b) ^ C67_map_regs(c); | 888 | xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c); |
| 889 | 889 | ||
| 890 | C67_g((0 << 29) | //creg | 890 | C67_g(S, (0 << 29) | //creg |
| 891 | (0 << 28) | //inv | 891 | (0 << 28) | //inv |
| 892 | (C67_map_regn(c) << 23) | //dst | 892 | (C67_map_regn(S, c) << 23) | //dst |
| 893 | (C67_map_regn(b) << 18) | //src2 | 893 | (C67_map_regn(S, b) << 18) | //src2 |
| 894 | (0 << 13) | //src1 NA | 894 | (0 << 13) | //src1 NA |
| 895 | (xpath << 12) | //x cross path if opposite sides | 895 | (xpath << 12) | //x cross path if opposite sides |
| 896 | (0x39 << 5) | //opcode | 896 | (0x39 << 5) | //opcode |
| 897 | (0x6 << 2) | //opcode fixed | 897 | (0x6 << 2) | //opcode fixed |
| 898 | (C67_map_regs(c) << 1) | //side of dest | 898 | (C67_map_regs(S, c) << 1) | //side of dest |
| 899 | (0 << 0)); //parallel | 899 | (0 << 0)); //parallel |
| 900 | } else if (strstr(s, "INTDPU.L") == s) { | 900 | } else if (strstr(s, "INTDPU.L") == s) { |
| 901 | xpath = C67_map_regs(b) ^ C67_map_regs(c); | 901 | xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c); |
| 902 | 902 | ||
| 903 | C67_g((0 << 29) | //creg | 903 | C67_g(S, (0 << 29) | //creg |
| 904 | (0 << 28) | //inv | 904 | (0 << 28) | //inv |
| 905 | (C67_map_regn(c) << 23) | //dst | 905 | (C67_map_regn(S, c) << 23) | //dst |
| 906 | ((C67_map_regn(b) + 1) << 18) | //src2 WEIRD CPU must specify odd reg for some reason | 906 | ((C67_map_regn(S, b) + 1) << 18) | //src2 WEIRD CPU must specify odd reg for some reason |
| 907 | (0 << 13) | //src1 NA | 907 | (0 << 13) | //src1 NA |
| 908 | (xpath << 12) | //x cross path if opposite sides | 908 | (xpath << 12) | //x cross path if opposite sides |
| 909 | (0x3b << 5) | //opcode | 909 | (0x3b << 5) | //opcode |
| 910 | (0x6 << 2) | //opcode fixed | 910 | (0x6 << 2) | //opcode fixed |
| 911 | (C67_map_regs(c) << 1) | //side of dest | 911 | (C67_map_regs(S, c) << 1) | //side of dest |
| 912 | (0 << 0)); //parallel | 912 | (0 << 0)); //parallel |
| 913 | } else if (strstr(s, "SPDP.L") == s) { | 913 | } else if (strstr(s, "SPDP.L") == s) { |
| 914 | xpath = C67_map_regs(b) ^ C67_map_regs(c); | 914 | xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c); |
| 915 | 915 | ||
| 916 | C67_g((0 << 29) | //creg | 916 | C67_g(S, (0 << 29) | //creg |
| 917 | (0 << 28) | //inv | 917 | (0 << 28) | //inv |
| 918 | (C67_map_regn(c) << 23) | //dst | 918 | (C67_map_regn(S, c) << 23) | //dst |
| 919 | (C67_map_regn(b) << 18) | //src2 | 919 | (C67_map_regn(S, b) << 18) | //src2 |
| 920 | (0 << 13) | //src1 NA | 920 | (0 << 13) | //src1 NA |
| 921 | (xpath << 12) | //x cross path if opposite sides | 921 | (xpath << 12) | //x cross path if opposite sides |
| 922 | (0x2 << 6) | //opcode | 922 | (0x2 << 6) | //opcode |
| 923 | (0x8 << 2) | //opcode fixed | 923 | (0x8 << 2) | //opcode fixed |
| 924 | (C67_map_regs(c) << 1) | //side of dest | 924 | (C67_map_regs(S, c) << 1) | //side of dest |
| 925 | (0 << 0)); //parallel | 925 | (0 << 0)); //parallel |
| 926 | } else if (strstr(s, "DPSP.L") == s) { | 926 | } else if (strstr(s, "DPSP.L") == s) { |
| 927 | ALWAYS_ASSERT(C67_map_regs(b) == C67_map_regs(c)); | 927 | ALWAYS_ASSERT(C67_map_regs(S, b) == C67_map_regs(S, c)); |
| 928 | 928 | ||
| 929 | C67_g((0 << 29) | //creg | 929 | C67_g(S, (0 << 29) | //creg |
| 930 | (0 << 28) | //inv | 930 | (0 << 28) | //inv |
| 931 | (C67_map_regn(c) << 23) | //dst | 931 | (C67_map_regn(S, c) << 23) | //dst |
| 932 | ((C67_map_regn(b) + 1) << 18) | //src2 WEIRD CPU must specify odd reg for some reason | 932 | ((C67_map_regn(S, b) + 1) << 18) | //src2 WEIRD CPU must specify odd reg for some reason |
| 933 | (0 << 13) | //src1 NA | 933 | (0 << 13) | //src1 NA |
| 934 | (0 << 12) | //x cross path if opposite sides | 934 | (0 << 12) | //x cross path if opposite sides |
| 935 | (0x9 << 5) | //opcode | 935 | (0x9 << 5) | //opcode |
| 936 | (0x6 << 2) | //opcode fixed | 936 | (0x6 << 2) | //opcode fixed |
| 937 | (C67_map_regs(c) << 1) | //side of dest | 937 | (C67_map_regs(S, c) << 1) | //side of dest |
| 938 | (0 << 0)); //parallel | 938 | (0 << 0)); //parallel |
| 939 | } else if (strstr(s, "ADD.L") == s) { | 939 | } else if (strstr(s, "ADD.L") == s) { |
| 940 | xpath = C67_map_regs(b) ^ C67_map_regs(c); | 940 | xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c); |
| 941 | 941 | ||
| 942 | ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c)); | 942 | ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c)); |
| 943 | 943 | ||
| 944 | C67_g((0 << 29) | //creg | 944 | C67_g(S, (0 << 29) | //creg |
| 945 | (0 << 28) | //inv | 945 | (0 << 28) | //inv |
| 946 | (C67_map_regn(c) << 23) | //dst | 946 | (C67_map_regn(S, c) << 23) | //dst |
| 947 | (C67_map_regn(b) << 18) | //src2 (possible x path) | 947 | (C67_map_regn(S, b) << 18) | //src2 (possible x path) |
| 948 | (C67_map_regn(a) << 13) | //src1 | 948 | (C67_map_regn(S, a) << 13) | //src1 |
| 949 | (xpath << 12) | //x cross path if opposite sides | 949 | (xpath << 12) | //x cross path if opposite sides |
| 950 | (0x3 << 5) | //opcode | 950 | (0x3 << 5) | //opcode |
| 951 | (0x6 << 2) | //opcode fixed | 951 | (0x6 << 2) | //opcode fixed |
| 952 | (C67_map_regs(c) << 1) | //side of dest | 952 | (C67_map_regs(S, c) << 1) | //side of dest |
| 953 | (0 << 0)); //parallel | 953 | (0 << 0)); //parallel |
| 954 | } else if (strstr(s, "SUB.L") == s) { | 954 | } else if (strstr(s, "SUB.L") == s) { |
| 955 | xpath = C67_map_regs(b) ^ C67_map_regs(c); | 955 | xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c); |
| 956 | 956 | ||
| 957 | ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c)); | 957 | ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c)); |
| 958 | 958 | ||
| 959 | C67_g((0 << 29) | //creg | 959 | C67_g(S, (0 << 29) | //creg |
| 960 | (0 << 28) | //inv | 960 | (0 << 28) | //inv |
| 961 | (C67_map_regn(c) << 23) | //dst | 961 | (C67_map_regn(S, c) << 23) | //dst |
| 962 | (C67_map_regn(b) << 18) | //src2 (possible x path) | 962 | (C67_map_regn(S, b) << 18) | //src2 (possible x path) |
| 963 | (C67_map_regn(a) << 13) | //src1 | 963 | (C67_map_regn(S, a) << 13) | //src1 |
| 964 | (xpath << 12) | //x cross path if opposite sides | 964 | (xpath << 12) | //x cross path if opposite sides |
| 965 | (0x7 << 5) | //opcode | 965 | (0x7 << 5) | //opcode |
| 966 | (0x6 << 2) | //opcode fixed | 966 | (0x6 << 2) | //opcode fixed |
| 967 | (C67_map_regs(c) << 1) | //side of dest | 967 | (C67_map_regs(S, c) << 1) | //side of dest |
| 968 | (0 << 0)); //parallel | 968 | (0 << 0)); //parallel |
| 969 | } else if (strstr(s, "OR.L") == s) { | 969 | } else if (strstr(s, "OR.L") == s) { |
| 970 | xpath = C67_map_regs(b) ^ C67_map_regs(c); | 970 | xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c); |
| 971 | 971 | ||
| 972 | ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c)); | 972 | ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c)); |
| 973 | 973 | ||
| 974 | C67_g((0 << 29) | //creg | 974 | C67_g(S, (0 << 29) | //creg |
| 975 | (0 << 28) | //inv | 975 | (0 << 28) | //inv |
| 976 | (C67_map_regn(c) << 23) | //dst | 976 | (C67_map_regn(S, c) << 23) | //dst |
| 977 | (C67_map_regn(b) << 18) | //src2 (possible x path) | 977 | (C67_map_regn(S, b) << 18) | //src2 (possible x path) |
| 978 | (C67_map_regn(a) << 13) | //src1 | 978 | (C67_map_regn(S, a) << 13) | //src1 |
| 979 | (xpath << 12) | //x cross path if opposite sides | 979 | (xpath << 12) | //x cross path if opposite sides |
| 980 | (0x7f << 5) | //opcode | 980 | (0x7f << 5) | //opcode |
| 981 | (0x6 << 2) | //opcode fixed | 981 | (0x6 << 2) | //opcode fixed |
| 982 | (C67_map_regs(c) << 1) | //side of dest | 982 | (C67_map_regs(S, c) << 1) | //side of dest |
| 983 | (0 << 0)); //parallel | 983 | (0 << 0)); //parallel |
| 984 | } else if (strstr(s, "AND.L") == s) { | 984 | } else if (strstr(s, "AND.L") == s) { |
| 985 | xpath = C67_map_regs(b) ^ C67_map_regs(c); | 985 | xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c); |
| 986 | 986 | ||
| 987 | ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c)); | 987 | ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c)); |
| 988 | 988 | ||
| 989 | C67_g((0 << 29) | //creg | 989 | C67_g(S, (0 << 29) | //creg |
| 990 | (0 << 28) | //inv | 990 | (0 << 28) | //inv |
| 991 | (C67_map_regn(c) << 23) | //dst | 991 | (C67_map_regn(S, c) << 23) | //dst |
| 992 | (C67_map_regn(b) << 18) | //src2 (possible x path) | 992 | (C67_map_regn(S, b) << 18) | //src2 (possible x path) |
| 993 | (C67_map_regn(a) << 13) | //src1 | 993 | (C67_map_regn(S, a) << 13) | //src1 |
| 994 | (xpath << 12) | //x cross path if opposite sides | 994 | (xpath << 12) | //x cross path if opposite sides |
| 995 | (0x7b << 5) | //opcode | 995 | (0x7b << 5) | //opcode |
| 996 | (0x6 << 2) | //opcode fixed | 996 | (0x6 << 2) | //opcode fixed |
| 997 | (C67_map_regs(c) << 1) | //side of dest | 997 | (C67_map_regs(S, c) << 1) | //side of dest |
| 998 | (0 << 0)); //parallel | 998 | (0 << 0)); //parallel |
| 999 | } else if (strstr(s, "XOR.L") == s) { | 999 | } else if (strstr(s, "XOR.L") == s) { |
| 1000 | xpath = C67_map_regs(b) ^ C67_map_regs(c); | 1000 | xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c); |
| 1001 | 1001 | ||
| 1002 | ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c)); | 1002 | ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c)); |
| 1003 | 1003 | ||
| 1004 | C67_g((0 << 29) | //creg | 1004 | C67_g(S, (0 << 29) | //creg |
| 1005 | (0 << 28) | //inv | 1005 | (0 << 28) | //inv |
| 1006 | (C67_map_regn(c) << 23) | //dst | 1006 | (C67_map_regn(S, c) << 23) | //dst |
| 1007 | (C67_map_regn(b) << 18) | //src2 (possible x path) | 1007 | (C67_map_regn(S, b) << 18) | //src2 (possible x path) |
| 1008 | (C67_map_regn(a) << 13) | //src1 | 1008 | (C67_map_regn(S, a) << 13) | //src1 |
| 1009 | (xpath << 12) | //x cross path if opposite sides | 1009 | (xpath << 12) | //x cross path if opposite sides |
| 1010 | (0x6f << 5) | //opcode | 1010 | (0x6f << 5) | //opcode |
| 1011 | (0x6 << 2) | //opcode fixed | 1011 | (0x6 << 2) | //opcode fixed |
| 1012 | (C67_map_regs(c) << 1) | //side of dest | 1012 | (C67_map_regs(S, c) << 1) | //side of dest |
| 1013 | (0 << 0)); //parallel | 1013 | (0 << 0)); //parallel |
| 1014 | } else if (strstr(s, "ADDSP.L") == s) { | 1014 | } else if (strstr(s, "ADDSP.L") == s) { |
| 1015 | xpath = C67_map_regs(b) ^ C67_map_regs(c); | 1015 | xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c); |
| 1016 | 1016 | ||
| 1017 | ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c)); | 1017 | ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c)); |
| 1018 | 1018 | ||
| 1019 | C67_g((0 << 29) | //creg | 1019 | C67_g(S, (0 << 29) | //creg |
| 1020 | (0 << 28) | //inv | 1020 | (0 << 28) | //inv |
| 1021 | (C67_map_regn(c) << 23) | //dst | 1021 | (C67_map_regn(S, c) << 23) | //dst |
| 1022 | (C67_map_regn(b) << 18) | //src2 (possible x path) | 1022 | (C67_map_regn(S, b) << 18) | //src2 (possible x path) |
| 1023 | (C67_map_regn(a) << 13) | //src1 | 1023 | (C67_map_regn(S, a) << 13) | //src1 |
| 1024 | (xpath << 12) | //x cross path if opposite sides | 1024 | (xpath << 12) | //x cross path if opposite sides |
| 1025 | (0x10 << 5) | //opcode | 1025 | (0x10 << 5) | //opcode |
| 1026 | (0x6 << 2) | //opcode fixed | 1026 | (0x6 << 2) | //opcode fixed |
| 1027 | (C67_map_regs(c) << 1) | //side of dest | 1027 | (C67_map_regs(S, c) << 1) | //side of dest |
| 1028 | (0 << 0)); //parallel | 1028 | (0 << 0)); //parallel |
| 1029 | } else if (strstr(s, "ADDDP.L") == s) { | 1029 | } else if (strstr(s, "ADDDP.L") == s) { |
| 1030 | xpath = C67_map_regs(b) ^ C67_map_regs(c); | 1030 | xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c); |
| 1031 | 1031 | ||
| 1032 | ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c)); | 1032 | ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c)); |
| 1033 | 1033 | ||
| 1034 | C67_g((0 << 29) | //creg | 1034 | C67_g(S, (0 << 29) | //creg |
| 1035 | (0 << 28) | //inv | 1035 | (0 << 28) | //inv |
| 1036 | (C67_map_regn(c) << 23) | //dst | 1036 | (C67_map_regn(S, c) << 23) | //dst |
| 1037 | (C67_map_regn(b) << 18) | //src2 (possible x path) | 1037 | (C67_map_regn(S, b) << 18) | //src2 (possible x path) |
| 1038 | (C67_map_regn(a) << 13) | //src1 | 1038 | (C67_map_regn(S, a) << 13) | //src1 |
| 1039 | (xpath << 12) | //x cross path if opposite sides | 1039 | (xpath << 12) | //x cross path if opposite sides |
| 1040 | (0x18 << 5) | //opcode | 1040 | (0x18 << 5) | //opcode |
| 1041 | (0x6 << 2) | //opcode fixed | 1041 | (0x6 << 2) | //opcode fixed |
| 1042 | (C67_map_regs(c) << 1) | //side of dest | 1042 | (C67_map_regs(S, c) << 1) | //side of dest |
| 1043 | (0 << 0)); //parallel | 1043 | (0 << 0)); //parallel |
| 1044 | } else if (strstr(s, "SUBSP.L") == s) { | 1044 | } else if (strstr(s, "SUBSP.L") == s) { |
| 1045 | xpath = C67_map_regs(b) ^ C67_map_regs(c); | 1045 | xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c); |
| 1046 | 1046 | ||
| 1047 | ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c)); | 1047 | ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c)); |
| 1048 | 1048 | ||
| 1049 | C67_g((0 << 29) | //creg | 1049 | C67_g(S, (0 << 29) | //creg |
| 1050 | (0 << 28) | //inv | 1050 | (0 << 28) | //inv |
| 1051 | (C67_map_regn(c) << 23) | //dst | 1051 | (C67_map_regn(S, c) << 23) | //dst |
| 1052 | (C67_map_regn(b) << 18) | //src2 (possible x path) | 1052 | (C67_map_regn(S, b) << 18) | //src2 (possible x path) |
| 1053 | (C67_map_regn(a) << 13) | //src1 | 1053 | (C67_map_regn(S, a) << 13) | //src1 |
| 1054 | (xpath << 12) | //x cross path if opposite sides | 1054 | (xpath << 12) | //x cross path if opposite sides |
| 1055 | (0x11 << 5) | //opcode | 1055 | (0x11 << 5) | //opcode |
| 1056 | (0x6 << 2) | //opcode fixed | 1056 | (0x6 << 2) | //opcode fixed |
| 1057 | (C67_map_regs(c) << 1) | //side of dest | 1057 | (C67_map_regs(S, c) << 1) | //side of dest |
| 1058 | (0 << 0)); //parallel | 1058 | (0 << 0)); //parallel |
| 1059 | } else if (strstr(s, "SUBDP.L") == s) { | 1059 | } else if (strstr(s, "SUBDP.L") == s) { |
| 1060 | xpath = C67_map_regs(b) ^ C67_map_regs(c); | 1060 | xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c); |
| 1061 | 1061 | ||
| 1062 | ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c)); | 1062 | ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c)); |
| 1063 | 1063 | ||
| 1064 | C67_g((0 << 29) | //creg | 1064 | C67_g(S, (0 << 29) | //creg |
| 1065 | (0 << 28) | //inv | 1065 | (0 << 28) | //inv |
| 1066 | (C67_map_regn(c) << 23) | //dst | 1066 | (C67_map_regn(S, c) << 23) | //dst |
| 1067 | (C67_map_regn(b) << 18) | //src2 (possible x path) | 1067 | (C67_map_regn(S, b) << 18) | //src2 (possible x path) |
| 1068 | (C67_map_regn(a) << 13) | //src1 | 1068 | (C67_map_regn(S, a) << 13) | //src1 |
| 1069 | (xpath << 12) | //x cross path if opposite sides | 1069 | (xpath << 12) | //x cross path if opposite sides |
| 1070 | (0x19 << 5) | //opcode | 1070 | (0x19 << 5) | //opcode |
| 1071 | (0x6 << 2) | //opcode fixed | 1071 | (0x6 << 2) | //opcode fixed |
| 1072 | (C67_map_regs(c) << 1) | //side of dest | 1072 | (C67_map_regs(S, c) << 1) | //side of dest |
| 1073 | (0 << 0)); //parallel | 1073 | (0 << 0)); //parallel |
| 1074 | } else if (strstr(s, "MPYSP.M") == s) { | 1074 | } else if (strstr(s, "MPYSP.M") == s) { |
| 1075 | xpath = C67_map_regs(b) ^ C67_map_regs(c); | 1075 | xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c); |
| 1076 | 1076 | ||
| 1077 | ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c)); | 1077 | ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c)); |
| 1078 | 1078 | ||
| 1079 | C67_g((0 << 29) | //creg | 1079 | C67_g(S, (0 << 29) | //creg |
| 1080 | (0 << 28) | //inv | 1080 | (0 << 28) | //inv |
| 1081 | (C67_map_regn(c) << 23) | //dst | 1081 | (C67_map_regn(S, c) << 23) | //dst |
| 1082 | (C67_map_regn(b) << 18) | //src2 (possible x path) | 1082 | (C67_map_regn(S, b) << 18) | //src2 (possible x path) |
| 1083 | (C67_map_regn(a) << 13) | //src1 | 1083 | (C67_map_regn(S, a) << 13) | //src1 |
| 1084 | (xpath << 12) | //x cross path if opposite sides | 1084 | (xpath << 12) | //x cross path if opposite sides |
| 1085 | (0x1c << 7) | //opcode | 1085 | (0x1c << 7) | //opcode |
| 1086 | (0x0 << 2) | //opcode fixed | 1086 | (0x0 << 2) | //opcode fixed |
| 1087 | (C67_map_regs(c) << 1) | //side of dest | 1087 | (C67_map_regs(S, c) << 1) | //side of dest |
| 1088 | (0 << 0)); //parallel | 1088 | (0 << 0)); //parallel |
| 1089 | } else if (strstr(s, "MPYDP.M") == s) { | 1089 | } else if (strstr(s, "MPYDP.M") == s) { |
| 1090 | xpath = C67_map_regs(b) ^ C67_map_regs(c); | 1090 | xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c); |
| 1091 | 1091 | ||
| 1092 | ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c)); | 1092 | ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c)); |
| 1093 | 1093 | ||
| 1094 | C67_g((0 << 29) | //creg | 1094 | C67_g(S, (0 << 29) | //creg |
| 1095 | (0 << 28) | //inv | 1095 | (0 << 28) | //inv |
| 1096 | (C67_map_regn(c) << 23) | //dst | 1096 | (C67_map_regn(S, c) << 23) | //dst |
| 1097 | (C67_map_regn(b) << 18) | //src2 (possible x path) | 1097 | (C67_map_regn(S, b) << 18) | //src2 (possible x path) |
| 1098 | (C67_map_regn(a) << 13) | //src1 | 1098 | (C67_map_regn(S, a) << 13) | //src1 |
| 1099 | (xpath << 12) | //x cross path if opposite sides | 1099 | (xpath << 12) | //x cross path if opposite sides |
| 1100 | (0x0e << 7) | //opcode | 1100 | (0x0e << 7) | //opcode |
| 1101 | (0x0 << 2) | //opcode fixed | 1101 | (0x0 << 2) | //opcode fixed |
| 1102 | (C67_map_regs(c) << 1) | //side of dest | 1102 | (C67_map_regs(S, c) << 1) | //side of dest |
| 1103 | (0 << 0)); //parallel | 1103 | (0 << 0)); //parallel |
| 1104 | } else if (strstr(s, "MPYI.M") == s) { | 1104 | } else if (strstr(s, "MPYI.M") == s) { |
| 1105 | xpath = C67_map_regs(b) ^ C67_map_regs(c); | 1105 | xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c); |
| 1106 | 1106 | ||
| 1107 | ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c)); | 1107 | ALWAYS_ASSERT(C67_map_regs(S, a) == C67_map_regs(S, c)); |
| 1108 | 1108 | ||
| 1109 | C67_g((0 << 29) | //creg | 1109 | C67_g(S, (0 << 29) | //creg |
| 1110 | (0 << 28) | //inv | 1110 | (0 << 28) | //inv |
| 1111 | (C67_map_regn(c) << 23) | //dst | 1111 | (C67_map_regn(S, c) << 23) | //dst |
| 1112 | (C67_map_regn(b) << 18) | //src2 | 1112 | (C67_map_regn(S, b) << 18) | //src2 |
| 1113 | (C67_map_regn(a) << 13) | //src1 (cst5) | 1113 | (C67_map_regn(S, a) << 13) | //src1 (cst5) |
| 1114 | (xpath << 12) | //x cross path if opposite sides | 1114 | (xpath << 12) | //x cross path if opposite sides |
| 1115 | (0x4 << 7) | //opcode | 1115 | (0x4 << 7) | //opcode |
| 1116 | (0x0 << 2) | //opcode fixed | 1116 | (0x0 << 2) | //opcode fixed |
| 1117 | (C67_map_regs(c) << 1) | //side of dest | 1117 | (C67_map_regs(S, c) << 1) | //side of dest |
| 1118 | (0 << 0)); //parallel | 1118 | (0 << 0)); //parallel |
| 1119 | } else if (strstr(s, "SHR.S") == s) { | 1119 | } else if (strstr(s, "SHR.S") == s) { |
| 1120 | xpath = C67_map_regs(b) ^ C67_map_regs(c); | 1120 | xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c); |
| 1121 | 1121 | ||
| 1122 | ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a)); | 1122 | ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a)); |
| 1123 | 1123 | ||
| 1124 | C67_g((0 << 29) | //creg | 1124 | C67_g(S, (0 << 29) | //creg |
| 1125 | (0 << 28) | //inv | 1125 | (0 << 28) | //inv |
| 1126 | (C67_map_regn(c) << 23) | //dst | 1126 | (C67_map_regn(S, c) << 23) | //dst |
| 1127 | (C67_map_regn(b) << 18) | //src2 | 1127 | (C67_map_regn(S, b) << 18) | //src2 |
| 1128 | (C67_map_regn(a) << 13) | //src1 | 1128 | (C67_map_regn(S, a) << 13) | //src1 |
| 1129 | (xpath << 12) | //x cross path if opposite sides | 1129 | (xpath << 12) | //x cross path if opposite sides |
| 1130 | (0x37 << 6) | //opcode | 1130 | (0x37 << 6) | //opcode |
| 1131 | (0x8 << 2) | //opcode fixed | 1131 | (0x8 << 2) | //opcode fixed |
| 1132 | (C67_map_regs(c) << 1) | //side of dest | 1132 | (C67_map_regs(S, c) << 1) | //side of dest |
| 1133 | (0 << 0)); //parallel | 1133 | (0 << 0)); //parallel |
| 1134 | } else if (strstr(s, "SHRU.S") == s) { | 1134 | } else if (strstr(s, "SHRU.S") == s) { |
| 1135 | xpath = C67_map_regs(b) ^ C67_map_regs(c); | 1135 | xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c); |
| 1136 | 1136 | ||
| 1137 | ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a)); | 1137 | ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a)); |
| 1138 | 1138 | ||
| 1139 | C67_g((0 << 29) | //creg | 1139 | C67_g(S, (0 << 29) | //creg |
| 1140 | (0 << 28) | //inv | 1140 | (0 << 28) | //inv |
| 1141 | (C67_map_regn(c) << 23) | //dst | 1141 | (C67_map_regn(S, c) << 23) | //dst |
| 1142 | (C67_map_regn(b) << 18) | //src2 | 1142 | (C67_map_regn(S, b) << 18) | //src2 |
| 1143 | (C67_map_regn(a) << 13) | //src1 | 1143 | (C67_map_regn(S, a) << 13) | //src1 |
| 1144 | (xpath << 12) | //x cross path if opposite sides | 1144 | (xpath << 12) | //x cross path if opposite sides |
| 1145 | (0x27 << 6) | //opcode | 1145 | (0x27 << 6) | //opcode |
| 1146 | (0x8 << 2) | //opcode fixed | 1146 | (0x8 << 2) | //opcode fixed |
| 1147 | (C67_map_regs(c) << 1) | //side of dest | 1147 | (C67_map_regs(S, c) << 1) | //side of dest |
| 1148 | (0 << 0)); //parallel | 1148 | (0 << 0)); //parallel |
| 1149 | } else if (strstr(s, "SHL.S") == s) { | 1149 | } else if (strstr(s, "SHL.S") == s) { |
| 1150 | xpath = C67_map_regs(b) ^ C67_map_regs(c); | 1150 | xpath = C67_map_regs(S, b) ^ C67_map_regs(S, c); |
| 1151 | 1151 | ||
| 1152 | ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a)); | 1152 | ALWAYS_ASSERT(C67_map_regs(S, c) == C67_map_regs(S, a)); |
| 1153 | 1153 | ||
| 1154 | C67_g((0 << 29) | //creg | 1154 | C67_g(S, (0 << 29) | //creg |
| 1155 | (0 << 28) | //inv | 1155 | (0 << 28) | //inv |
| 1156 | (C67_map_regn(c) << 23) | //dst | 1156 | (C67_map_regn(S, c) << 23) | //dst |
| 1157 | (C67_map_regn(b) << 18) | //src2 | 1157 | (C67_map_regn(S, b) << 18) | //src2 |
| 1158 | (C67_map_regn(a) << 13) | //src1 | 1158 | (C67_map_regn(S, a) << 13) | //src1 |
| 1159 | (xpath << 12) | //x cross path if opposite sides | 1159 | (xpath << 12) | //x cross path if opposite sides |
| 1160 | (0x33 << 6) | //opcode | 1160 | (0x33 << 6) | //opcode |
| 1161 | (0x8 << 2) | //opcode fixed | 1161 | (0x8 << 2) | //opcode fixed |
| 1162 | (C67_map_regs(c) << 1) | //side of dest | 1162 | (C67_map_regs(S, c) << 1) | //side of dest |
| 1163 | (0 << 0)); //parallel | 1163 | (0 << 0)); //parallel |
| 1164 | } else if (strstr(s, "||ADDK") == s) { | 1164 | } else if (strstr(s, "||ADDK") == s) { |
| 1165 | xpath = 0; // no xpath required just use the side of the src/dst | 1165 | xpath = 0; // no xpath required just use the side of the src/dst |
| 1166 | 1166 | ||
| 1167 | C67_g((0 << 29) | //creg | 1167 | C67_g(S, (0 << 29) | //creg |
| 1168 | (0 << 28) | //inv | 1168 | (0 << 28) | //inv |
| 1169 | (C67_map_regn(b) << 23) | //dst | 1169 | (C67_map_regn(S, b) << 23) | //dst |
| 1170 | (a << 07) | //scst16 | 1170 | (a << 07) | //scst16 |
| 1171 | (0x14 << 2) | //opcode fixed | 1171 | (0x14 << 2) | //opcode fixed |
| 1172 | (C67_map_regs(b) << 1) | //side of dst | 1172 | (C67_map_regs(S, b) << 1) | //side of dst |
| 1173 | (1 << 0)); //parallel | 1173 | (1 << 0)); //parallel |
| 1174 | } else if (strstr(s, "ADDK") == s) { | 1174 | } else if (strstr(s, "ADDK") == s) { |
| 1175 | xpath = 0; // no xpath required just use the side of the src/dst | 1175 | xpath = 0; // no xpath required just use the side of the src/dst |
| 1176 | 1176 | ||
| 1177 | C67_g((0 << 29) | //creg | 1177 | C67_g(S, (0 << 29) | //creg |
| 1178 | (0 << 28) | //inv | 1178 | (0 << 28) | //inv |
| 1179 | (C67_map_regn(b) << 23) | //dst | 1179 | (C67_map_regn(S, b) << 23) | //dst |
| 1180 | (a << 07) | //scst16 | 1180 | (a << 07) | //scst16 |
| 1181 | (0x14 << 2) | //opcode fixed | 1181 | (0x14 << 2) | //opcode fixed |
| 1182 | (C67_map_regs(b) << 1) | //side of dst | 1182 | (C67_map_regs(S, b) << 1) | //side of dst |
| 1183 | (0 << 0)); //parallel | 1183 | (0 << 0)); //parallel |
| 1184 | } else if (strstr(s, "NOP") == s) { | 1184 | } else if (strstr(s, "NOP") == s) { |
| 1185 | C67_g(((a - 1) << 13) | //no of cycles | 1185 | C67_g(S, ((a - 1) << 13) | //no of cycles |
| 1186 | (0 << 0)); //parallel | 1186 | (0 << 0)); //parallel |
| 1187 | } else | 1187 | } else |
| 1188 | ALWAYS_ASSERT(FALSE); | 1188 | ALWAYS_ASSERT(FALSE); |
| @@ -1195,198 +1195,198 @@ void C67_asm(const char *s, int a, int b, int c) · 6 unmodified lines | |||
| 1195 | 1195 | ||
| 1196 | //r=reg to load, fr=from reg, symbol for relocation, constant | 1196 | //r=reg to load, fr=from reg, symbol for relocation, constant |
| 1197 | 1197 | ||
| 1198 | void C67_MVKL(int r, int fc) | 1198 | void C67_MVKL(TCCState* S, int r, int fc) |
| 1199 | { | 1199 | { |
| 1200 | C67_asm("MVKL.", fc, r, 0); | 1200 | C67_asm(S, "MVKL.", fc, r, 0); |
| 1201 | } | 1201 | } |
| 1202 | 1202 | ||
| 1203 | void C67_MVKH(int r, int fc) | 1203 | void C67_MVKH(TCCState* S, int r, int fc) |
| 1204 | { | 1204 | { |
| 1205 | C67_asm("MVKH.", fc, r, 0); | 1205 | C67_asm(S, "MVKH.", fc, r, 0); |
| 1206 | } | 1206 | } |
| 1207 | 1207 | ||
| 1208 | void C67_STB_SP_A0(int r) | 1208 | void C67_STB_SP_A0(TCCState* S, int r) |
| 1209 | { | 1209 | { |
| 1210 | C67_asm("STB.D *+SP[A0]", r, 0, 0); // STB r,*+SP[A0] | 1210 | C67_asm(S, "STB.D *+SP[A0]", r, 0, 0); // STB r,*+SP[A0] |
| 1211 | } | 1211 | } |
| 1212 | 1212 | ||
| 1213 | void C67_STH_SP_A0(int r) | 1213 | void C67_STH_SP_A0(TCCState* S, int r) |
| 1214 | { | 1214 | { |
| 1215 | C67_asm("STH.D *+SP[A0]", r, 0, 0); // STH r,*+SP[A0] | 1215 | C67_asm(S, "STH.D *+SP[A0]", r, 0, 0); // STH r,*+SP[A0] |
| 1216 | } | 1216 | } |
| 1217 | 1217 | ||
| 1218 | void C67_STW_SP_A0(int r) | 1218 | void C67_STW_SP_A0(TCCState* S, int r) |
| 1219 | { | 1219 | { |
| 1220 | C67_asm("STW.D *+SP[A0]", r, 0, 0); // STW r,*+SP[A0] | 1220 | C67_asm(S, "STW.D *+SP[A0]", r, 0, 0); // STW r,*+SP[A0] |
| 1221 | } | 1221 | } |
| 1222 | 1222 | ||
| 1223 | void C67_STB_PTR(int r, int r2) | 1223 | void C67_STB_PTR(TCCState* S, int r, int r2) |
| 1224 | { | 1224 | { |
| 1225 | C67_asm("STB.D *", r, r2, 0); // STB r, *r2 | 1225 | C67_asm(S, "STB.D *", r, r2, 0); // STB r, *r2 |
| 1226 | } | 1226 | } |
| 1227 | 1227 | ||
| 1228 | void C67_STH_PTR(int r, int r2) | 1228 | void C67_STH_PTR(TCCState* S, int r, int r2) |
| 1229 | { | 1229 | { |
| 1230 | C67_asm("STH.D *", r, r2, 0); // STH r, *r2 | 1230 | C67_asm(S, "STH.D *", r, r2, 0); // STH r, *r2 |
| 1231 | } | 1231 | } |
| 1232 | 1232 | ||
| 1233 | void C67_STW_PTR(int r, int r2) | 1233 | void C67_STW_PTR(TCCState* S, int r, int r2) |
| 1234 | { | 1234 | { |
| 1235 | C67_asm("STW.D *", r, r2, 0); // STW r, *r2 | 1235 | C67_asm(S, "STW.D *", r, r2, 0); // STW r, *r2 |
| 1236 | } | 1236 | } |
| 1237 | 1237 | ||
| 1238 | void C67_STW_PTR_PRE_INC(int r, int r2, int n) | 1238 | void C67_STW_PTR_PRE_INC(TCCState* S, int r, int r2, int n) |
| 1239 | { | 1239 | { |
| 1240 | C67_asm("STW.D +*", r, r2, n); // STW r, *+r2 | 1240 | C67_asm(S, "STW.D +*", r, r2, n); // STW r, *+r2 |
| 1241 | } | 1241 | } |
| 1242 | 1242 | ||
| 1243 | void C67_PUSH(int r) | 1243 | void C67_PUSH(TCCState* S, int r) |
| 1244 | { | 1244 | { |
| 1245 | C67_asm("STW.D SP POST DEC", r, 0, 0); // STW r,*SP-- | 1245 | C67_asm(S, "STW.D SP POST DEC", r, 0, 0); // STW r,*SP-- |
| 1246 | } | 1246 | } |
| 1247 | 1247 | ||
| 1248 | void C67_LDW_SP_A0(int r) | 1248 | void C67_LDW_SP_A0(TCCState* S, int r) |
| 1249 | { | 1249 | { |
| 1250 | C67_asm("LDW.D *+SP[A0]", r, 0, 0); // LDW *+SP[A0],r | 1250 | C67_asm(S, "LDW.D *+SP[A0]", r, 0, 0); // LDW *+SP[A0],r |
| 1251 | } | 1251 | } |
| 1252 | 1252 | ||
| 1253 | void C67_LDDW_SP_A0(int r) | 1253 | void C67_LDDW_SP_A0(TCCState* S, int r) |
| 1254 | { | 1254 | { |
| 1255 | C67_asm("LDDW.D *+SP[A0]", r, 0, 0); // LDDW *+SP[A0],r | 1255 | C67_asm(S, "LDDW.D *+SP[A0]", r, 0, 0); // LDDW *+SP[A0],r |
| 1256 | } | 1256 | } |
| 1257 | 1257 | ||
| 1258 | void C67_LDH_SP_A0(int r) | 1258 | void C67_LDH_SP_A0(TCCState* S, int r) |
| 1259 | { | 1259 | { |
| 1260 | C67_asm("LDH.D *+SP[A0]", r, 0, 0); // LDH *+SP[A0],r | 1260 | C67_asm(S, "LDH.D *+SP[A0]", r, 0, 0); // LDH *+SP[A0],r |
| 1261 | } | 1261 | } |
| 1262 | 1262 | ||
| 1263 | void C67_LDB_SP_A0(int r) | 1263 | void C67_LDB_SP_A0(TCCState* S, int r) |
| 1264 | { | 1264 | { |
| 1265 | C67_asm("LDB.D *+SP[A0]", r, 0, 0); // LDB *+SP[A0],r | 1265 | C67_asm(S, "LDB.D *+SP[A0]", r, 0, 0); // LDB *+SP[A0],r |
| 1266 | } | 1266 | } |
| 1267 | 1267 | ||
| 1268 | void C67_LDHU_SP_A0(int r) | 1268 | void C67_LDHU_SP_A0(TCCState* S, int r) |
| 1269 | { | 1269 | { |
| 1270 | C67_asm("LDHU.D *+SP[A0]", r, 0, 0); // LDHU *+SP[A0],r | 1270 | C67_asm(S, "LDHU.D *+SP[A0]", r, 0, 0); // LDHU *+SP[A0],r |
| 1271 | } | 1271 | } |
| 1272 | 1272 | ||
| 1273 | void C67_LDBU_SP_A0(int r) | 1273 | void C67_LDBU_SP_A0(TCCState* S, int r) |
| 1274 | { | 1274 | { |
| 1275 | C67_asm("LDBU.D *+SP[A0]", r, 0, 0); // LDBU *+SP[A0],r | 1275 | C67_asm(S, "LDBU.D *+SP[A0]", r, 0, 0); // LDBU *+SP[A0],r |
| 1276 | } | 1276 | } |
| 1277 | 1277 | ||
| 1278 | void C67_LDW_PTR(int r, int r2) | 1278 | void C67_LDW_PTR(TCCState* S, int r, int r2) |
| 1279 | { | 1279 | { |
| 1280 | C67_asm("LDW.D *", r, r2, 0); // LDW *r,r2 | 1280 | C67_asm(S, "LDW.D *", r, r2, 0); // LDW *r,r2 |
| 1281 | } | 1281 | } |
| 1282 | 1282 | ||
| 1283 | void C67_LDDW_PTR(int r, int r2) | 1283 | void C67_LDDW_PTR(TCCState* S, int r, int r2) |
| 1284 | { | 1284 | { |
| 1285 | C67_asm("LDDW.D *", r, r2, 0); // LDDW *r,r2 | 1285 | C67_asm(S, "LDDW.D *", r, r2, 0); // LDDW *r,r2 |
| 1286 | } | 1286 | } |
| 1287 | 1287 | ||
| 1288 | void C67_LDH_PTR(int r, int r2) | 1288 | void C67_LDH_PTR(TCCState* S, int r, int r2) |
| 1289 | { | 1289 | { |
| 1290 | C67_asm("LDH.D *", r, r2, 0); // LDH *r,r2 | 1290 | C67_asm(S, "LDH.D *", r, r2, 0); // LDH *r,r2 |
| 1291 | } | 1291 | } |
| 1292 | 1292 | ||
| 1293 | void C67_LDB_PTR(int r, int r2) | 1293 | void C67_LDB_PTR(TCCState* S, int r, int r2) |
| 1294 | { | 1294 | { |
| 1295 | C67_asm("LDB.D *", r, r2, 0); // LDB *r,r2 | 1295 | C67_asm(S, "LDB.D *", r, r2, 0); // LDB *r,r2 |
| 1296 | } | 1296 | } |
| 1297 | 1297 | ||
| 1298 | void C67_LDHU_PTR(int r, int r2) | 1298 | void C67_LDHU_PTR(TCCState* S, int r, int r2) |
| 1299 | { | 1299 | { |
| 1300 | C67_asm("LDHU.D *", r, r2, 0); // LDHU *r,r2 | 1300 | C67_asm(S, "LDHU.D *", r, r2, 0); // LDHU *r,r2 |
| 1301 | } | 1301 | } |
| 1302 | 1302 | ||
| 1303 | void C67_LDBU_PTR(int r, int r2) | 1303 | void C67_LDBU_PTR(TCCState* S, int r, int r2) |
| 1304 | { | 1304 | { |
| 1305 | C67_asm("LDBU.D *", r, r2, 0); // LDBU *r,r2 | 1305 | C67_asm(S, "LDBU.D *", r, r2, 0); // LDBU *r,r2 |
| 1306 | } | 1306 | } |
| 1307 | 1307 | ||
| 1308 | void C67_LDW_PTR_PRE_INC(int r, int r2) | 1308 | void C67_LDW_PTR_PRE_INC(TCCState* S, int r, int r2) |
| 1309 | { | 1309 | { |
| 1310 | C67_asm("LDW.D +*", r, r2, 0); // LDW *+r,r2 | 1310 | C67_asm(S, "LDW.D +*", r, r2, 0); // LDW *+r,r2 |
| 1311 | } | 1311 | } |
| 1312 | 1312 | ||
| 1313 | void C67_POP(int r) | 1313 | void C67_POP(TCCState* S, int r) |
| 1314 | { | 1314 | { |
| 1315 | C67_asm("LDW.D SP PRE INC", r, 0, 0); // LDW *++SP,r | 1315 | C67_asm(S, "LDW.D SP PRE INC", r, 0, 0); // LDW *++SP,r |
| 1316 | } | 1316 | } |
| 1317 | 1317 | ||
| 1318 | void C67_POP_DW(int r) | 1318 | void C67_POP_DW(TCCState* S, int r) |
| 1319 | { | 1319 | { |
| 1320 | C67_asm("LDDW.D SP PRE INC", r, 0, 0); // LDDW *++SP,r | 1320 | C67_asm(S, "LDDW.D SP PRE INC", r, 0, 0); // LDDW *++SP,r |
| 1321 | } | 1321 | } |
| 1322 | 1322 | ||
| 1323 | void C67_CMPLT(int s1, int s2, int dst) | 1323 | void C67_CMPLT(TCCState* S, int s1, int s2, int dst) |
| 1324 | { | 1324 | { |
| 1325 | C67_asm("CMPLT.L1", s1, s2, dst); | 1325 | C67_asm(S, "CMPLT.L1", s1, s2, dst); |
| 1326 | } | 1326 | } |
| 1327 | 1327 | ||
| 1328 | void C67_CMPGT(int s1, int s2, int dst) | 1328 | void C67_CMPGT(TCCState* S, int s1, int s2, int dst) |
| 1329 | { | 1329 | { |
| 1330 | C67_asm("CMPGT.L1", s1, s2, dst); | 1330 | C67_asm(S, "CMPGT.L1", s1, s2, dst); |
| 1331 | } | 1331 | } |
| 1332 | 1332 | ||
| 1333 | void C67_CMPEQ(int s1, int s2, int dst) | 1333 | void C67_CMPEQ(TCCState* S, int s1, int s2, int dst) |
| 1334 | { | 1334 | { |
| 1335 | C67_asm("CMPEQ.L1", s1, s2, dst); | 1335 | C67_asm(S, "CMPEQ.L1", s1, s2, dst); |
| 1336 | } | 1336 | } |
| 1337 | 1337 | ||
| 1338 | void C67_CMPLTU(int s1, int s2, int dst) | 1338 | void C67_CMPLTU(TCCState* S, int s1, int s2, int dst) |
| 1339 | { | 1339 | { |
| 1340 | C67_asm("CMPLTU.L1", s1, s2, dst); | 1340 | C67_asm(S, "CMPLTU.L1", s1, s2, dst); |
| 1341 | } | 1341 | } |
| 1342 | 1342 | ||
| 1343 | void C67_CMPGTU(int s1, int s2, int dst) | 1343 | void C67_CMPGTU(TCCState* S, int s1, int s2, int dst) |
| 1344 | { | 1344 | { |
| 1345 | C67_asm("CMPGTU.L1", s1, s2, dst); | 1345 | C67_asm(S, "CMPGTU.L1", s1, s2, dst); |
| 1346 | } | 1346 | } |
| 1347 | 1347 | ||
| 1348 | 1348 | ||
| 1349 | void C67_CMPLTSP(int s1, int s2, int dst) | 1349 | void C67_CMPLTSP(TCCState* S, int s1, int s2, int dst) |
| 1350 | { | 1350 | { |
| 1351 | C67_asm("CMPLTSP.S1", s1, s2, dst); | 1351 | C67_asm(S, "CMPLTSP.S1", s1, s2, dst); |
| 1352 | } | 1352 | } |
| 1353 | 1353 | ||
| 1354 | void C67_CMPGTSP(int s1, int s2, int dst) | 1354 | void C67_CMPGTSP(TCCState* S, int s1, int s2, int dst) |
| 1355 | { | 1355 | { |
| 1356 | C67_asm("CMPGTSP.S1", s1, s2, dst); | 1356 | C67_asm(S, "CMPGTSP.S1", s1, s2, dst); |
| 1357 | } | 1357 | } |
| 1358 | 1358 | ||
| 1359 | void C67_CMPEQSP(int s1, int s2, int dst) | 1359 | void C67_CMPEQSP(TCCState* S, int s1, int s2, int dst) |
| 1360 | { | 1360 | { |
| 1361 | C67_asm("CMPEQSP.S1", s1, s2, dst); | 1361 | C67_asm(S, "CMPEQSP.S1", s1, s2, dst); |
| 1362 | } | 1362 | } |
| 1363 | 1363 | ||
| 1364 | void C67_CMPLTDP(int s1, int s2, int dst) | 1364 | void C67_CMPLTDP(TCCState* S, int s1, int s2, int dst) |
| 1365 | { | 1365 | { |
| 1366 | C67_asm("CMPLTDP.S1", s1, s2, dst); | 1366 | C67_asm(S, "CMPLTDP.S1", s1, s2, dst); |
| 1367 | } | 1367 | } |
| 1368 | 1368 | ||
| 1369 | void C67_CMPGTDP(int s1, int s2, int dst) | 1369 | void C67_CMPGTDP(TCCState* S, int s1, int s2, int dst) |
| 1370 | { | 1370 | { |
| 1371 | C67_asm("CMPGTDP.S1", s1, s2, dst); | 1371 | C67_asm(S, "CMPGTDP.S1", s1, s2, dst); |
| 1372 | } | 1372 | } |
| 1373 | 1373 | ||
| 1374 | void C67_CMPEQDP(int s1, int s2, int dst) | 1374 | void C67_CMPEQDP(TCCState* S, int s1, int s2, int dst) |
| 1375 | { | 1375 | { |
| 1376 | C67_asm("CMPEQDP.S1", s1, s2, dst); | 1376 | C67_asm(S, "CMPEQDP.S1", s1, s2, dst); |
| 1377 | } | 1377 | } |
| 1378 | 1378 | ||
| 1379 | 1379 | ||
| 1380 | void C67_IREG_B_REG(int inv, int r1, int r2) // [!R] B r2 | 1380 | void C67_IREG_B_REG(TCCState* S, int inv, int r1, int r2) // [!R] B r2 |
| 1381 | { | 1381 | { |
| 1382 | C67_asm("B.S2", inv, r1, r2); | 1382 | C67_asm(S, "B.S2", inv, r1, r2); |
| 1383 | } | 1383 | } |
| 1384 | 1384 | ||
| 1385 | 1385 | ||
| 1386 | // call with how many 32 bit words to skip | 1386 | // call with how many 32 bit words to skip |
| 1387 | // (0 would branch to the branch instruction) | 1387 | // (0 would branch to the branch instruction) |
| 1388 | 1388 | ||
| 1389 | void C67_B_DISP(int disp) // B +2 Branch with constant displacement | 1389 | void C67_B_DISP(TCCState* S, int disp) // B +2 Branch with constant displacement |
| 1390 | { | 1390 | { |
| 1391 | // Branch point is relative to the 8 word fetch packet | 1391 | // Branch point is relative to the 8 word fetch packet |
| 1392 | // | 1392 | // |
| @@ -1395,160 +1395,160 @@ void C67_B_DISP(int disp) // B +2 Branch with constant displacement · 2 unmodified lines | |||
| 1395 | // so add in how many words into the fetch packet the branch is | 1395 | // so add in how many words into the fetch packet the branch is |
| 1396 | 1396 | ||
| 1397 | 1397 | ||
| 1398 | C67_asm("B DISP", disp + ((ind & 31) >> 2), 0, 0); | 1398 | C67_asm(S, "B DISP", disp + ((S->tccgen_ind & 31) >> 2), 0, 0); |
| 1399 | } | 1399 | } |
| 1400 | 1400 | ||
| 1401 | void C67_NOP(int n) | 1401 | void C67_NOP(TCCState* S, int n) |
| 1402 | { | 1402 | { |
| 1403 | C67_asm("NOP", n, 0, 0); | 1403 | C67_asm(S, "NOP", n, 0, 0); |
| 1404 | } | 1404 | } |
| 1405 | 1405 | ||
| 1406 | void C67_ADDK(int n, int r) | 1406 | void C67_ADDK(TCCState* S, int n, int r) |
| 1407 | { | 1407 | { |
| 1408 | ALWAYS_ASSERT(abs(n) < 32767); | 1408 | ALWAYS_ASSERT(abs(n) < 32767); |
| 1409 | 1409 | ||
| 1410 | C67_asm("ADDK", n, r, 0); | 1410 | C67_asm(S, "ADDK", n, r, 0); |
| 1411 | } | 1411 | } |
| 1412 | 1412 | ||
| 1413 | void C67_ADDK_PARALLEL(int n, int r) | 1413 | void C67_ADDK_PARALLEL(TCCState* S, int n, int r) |
| 1414 | { | 1414 | { |
| 1415 | ALWAYS_ASSERT(abs(n) < 32767); | 1415 | ALWAYS_ASSERT(abs(n) < 32767); |
| 1416 | 1416 | ||
| 1417 | C67_asm("||ADDK", n, r, 0); | 1417 | C67_asm(S, "||ADDK", n, r, 0); |
| 1418 | } | 1418 | } |
| 1419 | 1419 | ||
| 1420 | void C67_Adjust_ADDK(int *inst, int n) | 1420 | void C67_Adjust_ADDK(TCCState* S, int *inst, int n) |
| 1421 | { | 1421 | { |
| 1422 | ALWAYS_ASSERT(abs(n) < 32767); | 1422 | ALWAYS_ASSERT(abs(n) < 32767); |
| 1423 | 1423 | ||
| 1424 | *inst = (*inst & (~(0xffff << 7))) | ((n & 0xffff) << 7); | 1424 | *inst = (*inst & (~(0xffff << 7))) | ((n & 0xffff) << 7); |
| 1425 | } | 1425 | } |
| 1426 | 1426 | ||
| 1427 | void C67_MV(int r, int v) | 1427 | void C67_MV(TCCState* S, int r, int v) |
| 1428 | { | 1428 | { |
| 1429 | C67_asm("MV.L", 0, r, v); | 1429 | C67_asm(S, "MV.L", 0, r, v); |
| 1430 | } | 1430 | } |
| 1431 | 1431 | ||
| 1432 | 1432 | ||
| 1433 | void C67_DPTRUNC(int r, int v) | 1433 | void C67_DPTRUNC(TCCState* S, int r, int v) |
| 1434 | { | 1434 | { |
| 1435 | C67_asm("DPTRUNC.L", 0, r, v); | 1435 | C67_asm(S, "DPTRUNC.L", 0, r, v); |
| 1436 | } | 1436 | } |
| 1437 | 1437 | ||
| 1438 | void C67_SPTRUNC(int r, int v) | 1438 | void C67_SPTRUNC(TCCState* S, int r, int v) |
| 1439 | { | 1439 | { |
| 1440 | C67_asm("SPTRUNC.L", 0, r, v); | 1440 | C67_asm(S, "SPTRUNC.L", 0, r, v); |
| 1441 | } | 1441 | } |
| 1442 | 1442 | ||
| 1443 | void C67_INTSP(int r, int v) | 1443 | void C67_INTSP(TCCState* S, int r, int v) |
| 1444 | { | 1444 | { |
| 1445 | C67_asm("INTSP.L", 0, r, v); | 1445 | C67_asm(S, "INTSP.L", 0, r, v); |
| 1446 | } | 1446 | } |
| 1447 | 1447 | ||
| 1448 | void C67_INTDP(int r, int v) | 1448 | void C67_INTDP(TCCState* S, int r, int v) |
| 1449 | { | 1449 | { |
| 1450 | C67_asm("INTDP.L", 0, r, v); | 1450 | C67_asm(S, "INTDP.L", 0, r, v); |
| 1451 | } | 1451 | } |
| 1452 | 1452 | ||
| 1453 | void C67_INTSPU(int r, int v) | 1453 | void C67_INTSPU(TCCState* S, int r, int v) |
| 1454 | { | 1454 | { |
| 1455 | C67_asm("INTSPU.L", 0, r, v); | 1455 | C67_asm(S, "INTSPU.L", 0, r, v); |
| 1456 | } | 1456 | } |
| 1457 | 1457 | ||
| 1458 | void C67_INTDPU(int r, int v) | 1458 | void C67_INTDPU(TCCState* S, int r, int v) |
| 1459 | { | 1459 | { |
| 1460 | C67_asm("INTDPU.L", 0, r, v); | 1460 | C67_asm(S, "INTDPU.L", 0, r, v); |
| 1461 | } | 1461 | } |
| 1462 | 1462 | ||
| 1463 | void C67_SPDP(int r, int v) | 1463 | void C67_SPDP(TCCState* S, int r, int v) |
| 1464 | { | 1464 | { |
| 1465 | C67_asm("SPDP.L", 0, r, v); | 1465 | C67_asm(S, "SPDP.L", 0, r, v); |
| 1466 | } | 1466 | } |
| 1467 | 1467 | ||
| 1468 | void C67_DPSP(int r, int v) // note regs must be on the same side | 1468 | void C67_DPSP(TCCState* S, int r, int v) // note regs must be on the same side |
| 1469 | { | 1469 | { |
| 1470 | C67_asm("DPSP.L", 0, r, v); | 1470 | C67_asm(S, "DPSP.L", 0, r, v); |
| 1471 | } | 1471 | } |
| 1472 | 1472 | ||
| 1473 | void C67_ADD(int r, int v) | 1473 | void C67_ADD(TCCState* S, int r, int v) |
| 1474 | { | 1474 | { |
| 1475 | C67_asm("ADD.L", v, r, v); | 1475 | C67_asm(S, "ADD.L", v, r, v); |
| 1476 | } | 1476 | } |
| 1477 | 1477 | ||
| 1478 | void C67_SUB(int r, int v) | 1478 | void C67_SUB(TCCState* S, int r, int v) |
| 1479 | { | 1479 | { |
| 1480 | C67_asm("SUB.L", v, r, v); | 1480 | C67_asm(S, "SUB.L", v, r, v); |
| 1481 | } | 1481 | } |
| 1482 | 1482 | ||
| 1483 | void C67_AND(int r, int v) | 1483 | void C67_AND(TCCState* S, int r, int v) |
| 1484 | { | 1484 | { |
| 1485 | C67_asm("AND.L", v, r, v); | 1485 | C67_asm(S, "AND.L", v, r, v); |
| 1486 | } | 1486 | } |
| 1487 | 1487 | ||
| 1488 | void C67_OR(int r, int v) | 1488 | void C67_OR(TCCState* S, int r, int v) |
| 1489 | { | 1489 | { |
| 1490 | C67_asm("OR.L", v, r, v); | 1490 | C67_asm(S, "OR.L", v, r, v); |
| 1491 | } | 1491 | } |
| 1492 | 1492 | ||
| 1493 | void C67_XOR(int r, int v) | 1493 | void C67_XOR(TCCState* S, int r, int v) |
| 1494 | { | 1494 | { |
| 1495 | C67_asm("XOR.L", v, r, v); | 1495 | C67_asm(S, "XOR.L", v, r, v); |
| 1496 | } | 1496 | } |
| 1497 | 1497 | ||
| 1498 | void C67_ADDSP(int r, int v) | 1498 | void C67_ADDSP(TCCState* S, int r, int v) |
| 1499 | { | 1499 | { |
| 1500 | C67_asm("ADDSP.L", v, r, v); | 1500 | C67_asm(S, "ADDSP.L", v, r, v); |
| 1501 | } | 1501 | } |
| 1502 | 1502 | ||
| 1503 | void C67_SUBSP(int r, int v) | 1503 | void C67_SUBSP(TCCState* S, int r, int v) |
| 1504 | { | 1504 | { |
| 1505 | C67_asm("SUBSP.L", v, r, v); | 1505 | C67_asm(S, "SUBSP.L", v, r, v); |
| 1506 | } | 1506 | } |
| 1507 | 1507 | ||
| 1508 | void C67_MPYSP(int r, int v) | 1508 | void C67_MPYSP(TCCState* S, int r, int v) |
| 1509 | { | 1509 | { |
| 1510 | C67_asm("MPYSP.M", v, r, v); | 1510 | C67_asm(S, "MPYSP.M", v, r, v); |
| 1511 | } | 1511 | } |
| 1512 | 1512 | ||
| 1513 | void C67_ADDDP(int r, int v) | 1513 | void C67_ADDDP(TCCState* S, int r, int v) |
| 1514 | { | 1514 | { |
| 1515 | C67_asm("ADDDP.L", v, r, v); | 1515 | C67_asm(S, "ADDDP.L", v, r, v); |
| 1516 | } | 1516 | } |
| 1517 | 1517 | ||
| 1518 | void C67_SUBDP(int r, int v) | 1518 | void C67_SUBDP(TCCState* S, int r, int v) |
| 1519 | { | 1519 | { |
| 1520 | C67_asm("SUBDP.L", v, r, v); | 1520 | C67_asm(S, "SUBDP.L", v, r, v); |
| 1521 | } | 1521 | } |
| 1522 | 1522 | ||
| 1523 | void C67_MPYDP(int r, int v) | 1523 | void C67_MPYDP(TCCState* S, int r, int v) |
| 1524 | { | 1524 | { |
| 1525 | C67_asm("MPYDP.M", v, r, v); | 1525 | C67_asm(S, "MPYDP.M", v, r, v); |
| 1526 | } | 1526 | } |
| 1527 | 1527 | ||
| 1528 | void C67_MPYI(int r, int v) | 1528 | void C67_MPYI(TCCState* S, int r, int v) |
| 1529 | { | 1529 | { |
| 1530 | C67_asm("MPYI.M", v, r, v); | 1530 | C67_asm(S, "MPYI.M", v, r, v); |
| 1531 | } | 1531 | } |
| 1532 | 1532 | ||
| 1533 | void C67_SHL(int r, int v) | 1533 | void C67_SHL(TCCState* S, int r, int v) |
| 1534 | { | 1534 | { |
| 1535 | C67_asm("SHL.S", r, v, v); | 1535 | C67_asm(S, "SHL.S", r, v, v); |
| 1536 | } | 1536 | } |
| 1537 | 1537 | ||
| 1538 | void C67_SHRU(int r, int v) | 1538 | void C67_SHRU(TCCState* S, int r, int v) |
| 1539 | { | 1539 | { |
| 1540 | C67_asm("SHRU.S", r, v, v); | 1540 | C67_asm(S, "SHRU.S", r, v, v); |
| 1541 | } | 1541 | } |
| 1542 | 1542 | ||
| 1543 | void C67_SHR(int r, int v) | 1543 | void C67_SHR(TCCState* S, int r, int v) |
| 1544 | { | 1544 | { |
| 1545 | C67_asm("SHR.S", r, v, v); | 1545 | C67_asm(S, "SHR.S", r, v, v); |
| 1546 | } | 1546 | } |
| 1547 | 1547 | ||
| 1548 | 1548 | ||
| 1549 | 1549 | ||
| 1550 | /* load 'r' from value 'sv' */ | 1550 | /* load 'r' from value 'sv' */ |
| 1551 | void load(int r, SValue * sv) | 1551 | void load(TCCState* S, int r, SValue * sv) |
| 1552 | { | 1552 | { |
| 1553 | int v, t, ft, fc, fr, size = 0, element; | 1553 | int v, t, ft, fc, fr, size = 0, element; |
| 1554 | BOOL Unsigned = FALSE; | 1554 | BOOL Unsigned = FALSE; |
| @@ -1564,10 +1564,10 @@ void load(int r, SValue * sv) · 9 unmodified lines | |||
| 1564 | v1.type.t = VT_INT; | 1564 | v1.type.t = VT_INT; |
| 1565 | v1.r = VT_LOCAL | VT_LVAL; | 1565 | v1.r = VT_LOCAL | VT_LVAL; |
| 1566 | v1.c.i = fc; | 1566 | v1.c.i = fc; |
| 1567 | load(r, &v1); | 1567 | load(S, r, &v1); |
| 1568 | fr = r; | 1568 | fr = r; |
| 1569 | } else if ((ft & VT_BTYPE) == VT_LDOUBLE) { | 1569 | } else if ((ft & VT_BTYPE) == VT_LDOUBLE) { |
| 1570 | tcc_error("long double not supported"); | 1570 | tcc_error(S, "long double not supported"); |
| 1571 | } else if ((ft & VT_TYPE) == VT_BYTE) { | 1571 | } else if ((ft & VT_TYPE) == VT_BYTE) { |
| 1572 | size = 1; | 1572 | size = 1; |
| 1573 | } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) { | 1573 | } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) { |
| @@ -1608,109 +1608,109 @@ void load(int r, SValue * sv) · 34 unmodified lines | |||
| 1608 | { | 1608 | { |
| 1609 | if (size == 1) { | 1609 | if (size == 1) { |
| 1610 | if (Unsigned) | 1610 | if (Unsigned) |
| 1611 | C67_LDBU_PTR(v, r); // LDBU *v,r | 1611 | C67_LDBU_PTR(S, v, r); // LDBU *v,r |
| 1612 | else | 1612 | else |
| 1613 | C67_LDB_PTR(v, r); // LDB *v,r | 1613 | C67_LDB_PTR(S, v, r); // LDB *v,r |
| 1614 | } else if (size == 2) { | 1614 | } else if (size == 2) { |
| 1615 | if (Unsigned) | 1615 | if (Unsigned) |
| 1616 | C67_LDHU_PTR(v, r); // LDHU *v,r | 1616 | C67_LDHU_PTR(S, v, r); // LDHU *v,r |
| 1617 | else | 1617 | else |
| 1618 | C67_LDH_PTR(v, r); // LDH *v,r | 1618 | C67_LDH_PTR(S, v, r); // LDH *v,r |
| 1619 | } else if (size == 4) { | 1619 | } else if (size == 4) { |
| 1620 | C67_LDW_PTR(v, r); // LDW *v,r | 1620 | C67_LDW_PTR(S, v, r); // LDW *v,r |
| 1621 | } else if (size == 8) { | 1621 | } else if (size == 8) { |
| 1622 | C67_LDDW_PTR(v, r); // LDDW *v,r | 1622 | C67_LDDW_PTR(S, v, r); // LDDW *v,r |
| 1623 | } | 1623 | } |
| 1624 | 1624 | ||
| 1625 | C67_NOP(4); // NOP 4 | 1625 | C67_NOP(S, 4); // NOP 4 |
| 1626 | return; | 1626 | return; |
| 1627 | } else if (fr & VT_SYM) { | 1627 | } else if (fr & VT_SYM) { |
| 1628 | greloc(cur_text_section, sv->sym, ind, R_C60LO16); // rem the inst need to be patched | 1628 | greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched |
| 1629 | greloc(cur_text_section, sv->sym, ind + 4, R_C60HI16); | 1629 | greloc(S, cur_text_section, sv->sym, S->tccgen_ind + 4, R_C60HI16); |
| 1630 | 1630 | ||
| 1631 | 1631 | ||
| 1632 | C67_MVKL(C67_A0, fc); //r=reg to load, constant | 1632 | C67_MVKL(S, C67_A0, fc); //r=reg to load, constant |
| 1633 | C67_MVKH(C67_A0, fc); //r=reg to load, constant | 1633 | C67_MVKH(S, C67_A0, fc); //r=reg to load, constant |
| 1634 | 1634 | ||
| 1635 | 1635 | ||
| 1636 | if (size == 1) { | 1636 | if (size == 1) { |
| 1637 | if (Unsigned) | 1637 | if (Unsigned) |
| 1638 | C67_LDBU_PTR(C67_A0, r); // LDBU *A0,r | 1638 | C67_LDBU_PTR(S, C67_A0, r); // LDBU *A0,r |
| 1639 | else | 1639 | else |
| 1640 | C67_LDB_PTR(C67_A0, r); // LDB *A0,r | 1640 | C67_LDB_PTR(S, C67_A0, r); // LDB *A0,r |
| 1641 | } else if (size == 2) { | 1641 | } else if (size == 2) { |
| 1642 | if (Unsigned) | 1642 | if (Unsigned) |
| 1643 | C67_LDHU_PTR(C67_A0, r); // LDHU *A0,r | 1643 | C67_LDHU_PTR(S, C67_A0, r); // LDHU *A0,r |
| 1644 | else | 1644 | else |
| 1645 | C67_LDH_PTR(C67_A0, r); // LDH *A0,r | 1645 | C67_LDH_PTR(S, C67_A0, r); // LDH *A0,r |
| 1646 | } else if (size == 4) { | 1646 | } else if (size == 4) { |
| 1647 | C67_LDW_PTR(C67_A0, r); // LDW *A0,r | 1647 | C67_LDW_PTR(S, C67_A0, r); // LDW *A0,r |
| 1648 | } else if (size == 8) { | 1648 | } else if (size == 8) { |
| 1649 | C67_LDDW_PTR(C67_A0, r); // LDDW *A0,r | 1649 | C67_LDDW_PTR(S, C67_A0, r); // LDDW *A0,r |
| 1650 | } | 1650 | } |
| 1651 | 1651 | ||
| 1652 | C67_NOP(4); // NOP 4 | 1652 | C67_NOP(S, 4); // NOP 4 |
| 1653 | return; | 1653 | return; |
| 1654 | } else { | 1654 | } else { |
| 1655 | element = size; | 1655 | element = size; |
| 1656 | 1656 | ||
| 1657 | // divide offset in bytes to create element index | 1657 | // divide offset in bytes to create element index |
| 1658 | C67_MVKL(C67_A0, (fc / element) + 8 / element); //r=reg to load, constant | 1658 | C67_MVKL(S, C67_A0, (fc / element) + 8 / element); //r=reg to load, constant |
| 1659 | C67_MVKH(C67_A0, (fc / element) + 8 / element); //r=reg to load, constant | 1659 | C67_MVKH(S, C67_A0, (fc / element) + 8 / element); //r=reg to load, constant |
| 1660 | 1660 | ||
| 1661 | if (size == 1) { | 1661 | if (size == 1) { |
| 1662 | if (Unsigned) | 1662 | if (Unsigned) |
| 1663 | C67_LDBU_SP_A0(r); // LDBU r, SP[A0] | 1663 | C67_LDBU_SP_A0(S, r); // LDBU r, SP[A0] |
| 1664 | else | 1664 | else |
| 1665 | C67_LDB_SP_A0(r); // LDB r, SP[A0] | 1665 | C67_LDB_SP_A0(S, r); // LDB r, SP[A0] |
| 1666 | } else if (size == 2) { | 1666 | } else if (size == 2) { |
| 1667 | if (Unsigned) | 1667 | if (Unsigned) |
| 1668 | C67_LDHU_SP_A0(r); // LDHU r, SP[A0] | 1668 | C67_LDHU_SP_A0(S, r); // LDHU r, SP[A0] |
| 1669 | else | 1669 | else |
| 1670 | C67_LDH_SP_A0(r); // LDH r, SP[A0] | 1670 | C67_LDH_SP_A0(S, r); // LDH r, SP[A0] |
| 1671 | } else if (size == 4) { | 1671 | } else if (size == 4) { |
| 1672 | C67_LDW_SP_A0(r); // LDW r, SP[A0] | 1672 | C67_LDW_SP_A0(S, r); // LDW r, SP[A0] |
| 1673 | } else if (size == 8) { | 1673 | } else if (size == 8) { |
| 1674 | C67_LDDW_SP_A0(r); // LDDW r, SP[A0] | 1674 | C67_LDDW_SP_A0(S, r); // LDDW r, SP[A0] |
| 1675 | } | 1675 | } |
| 1676 | 1676 | ||
| 1677 | 1677 | ||
| 1678 | C67_NOP(4); // NOP 4 | 1678 | C67_NOP(S, 4); // NOP 4 |
| 1679 | return; | 1679 | return; |
| 1680 | } | 1680 | } |
| 1681 | } else { | 1681 | } else { |
| 1682 | if (v == VT_CONST) { | 1682 | if (v == VT_CONST) { |
| 1683 | if (fr & VT_SYM) { | 1683 | if (fr & VT_SYM) { |
| 1684 | greloc(cur_text_section, sv->sym, ind, R_C60LO16); // rem the inst need to be patched | 1684 | greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched |
| 1685 | greloc(cur_text_section, sv->sym, ind + 4, R_C60HI16); | 1685 | greloc(S, cur_text_section, sv->sym, S->tccgen_ind + 4, R_C60HI16); |
| 1686 | } | 1686 | } |
| 1687 | C67_MVKL(r, fc); //r=reg to load, constant | 1687 | C67_MVKL(S, r, fc); //r=reg to load, constant |
| 1688 | C67_MVKH(r, fc); //r=reg to load, constant | 1688 | C67_MVKH(S, r, fc); //r=reg to load, constant |
| 1689 | } else if (v == VT_LOCAL) { | 1689 | } else if (v == VT_LOCAL) { |
| 1690 | C67_MVKL(r, fc + 8); //r=reg to load, constant C67 stack points to next free | 1690 | C67_MVKL(S, r, fc + 8); //r=reg to load, constant C67 stack points to next free |
| 1691 | C67_MVKH(r, fc + 8); //r=reg to load, constant | 1691 | C67_MVKH(S, r, fc + 8); //r=reg to load, constant |
| 1692 | C67_ADD(C67_FP, r); // MV v,r v -> r | 1692 | C67_ADD(S, C67_FP, r); // MV v,r v -> r |
| 1693 | } else if (v == VT_CMP) { | 1693 | } else if (v == VT_CMP) { |
| 1694 | C67_MV(C67_compare_reg, r); // MV v,r v -> r | 1694 | C67_MV(S, C67_compare_reg, r); // MV v,r v -> r |
| 1695 | } else if (v == VT_JMP || v == VT_JMPI) { | 1695 | } else if (v == VT_JMP || v == VT_JMPI) { |
| 1696 | t = v & 1; | 1696 | t = v & 1; |
| 1697 | C67_B_DISP(4); // Branch with constant displacement, skip over this branch, load, nop, load | 1697 | C67_B_DISP(S, 4); // Branch with constant displacement, skip over this branch, load, nop, load |
| 1698 | C67_MVKL(r, t); // r=reg to load, 0 or 1 (do this while branching) | 1698 | C67_MVKL(S, r, t); // r=reg to load, 0 or 1 (do this while branching) |
| 1699 | C67_NOP(4); // NOP 4 | 1699 | C67_NOP(S, 4); // NOP 4 |
| 1700 | gsym(fc); // modifies other branches to branch here | 1700 | gsym(S, fc); // modifies other branches to branch here |
| 1701 | C67_MVKL(r, t ^ 1); // r=reg to load, 0 or 1 | 1701 | C67_MVKL(S, r, t ^ 1); // r=reg to load, 0 or 1 |
| 1702 | } else if (v != r) { | 1702 | } else if (v != r) { |
| 1703 | C67_MV(v, r); // MV v,r v -> r | 1703 | C67_MV(S, v, r); // MV v,r v -> r |
| 1704 | 1704 | ||
| 1705 | if ((ft & VT_BTYPE) == VT_DOUBLE) | 1705 | if ((ft & VT_BTYPE) == VT_DOUBLE) |
| 1706 | C67_MV(v + 1, r + 1); // MV v,r v -> r | 1706 | C67_MV(S, v + 1, r + 1); // MV v,r v -> r |
| 1707 | } | 1707 | } |
| 1708 | } | 1708 | } |
| 1709 | } | 1709 | } |
| 1710 | 1710 | ||
| 1711 | 1711 | ||
| 1712 | /* store register 'r' in lvalue 'v' */ | 1712 | /* store register 'r' in lvalue 'v' */ |
| 1713 | void store(int r, SValue * v) | 1713 | void store(TCCState* S, int r, SValue * v) |
| 1714 | { | 1714 | { |
| 1715 | int fr, bt, ft, fc, size, t, element; | 1715 | int fr, bt, ft, fc, size, t, element; |
| 1716 | 1716 | ||
| @@ -1721,7 +1721,7 @@ void store(int r, SValue * v) · 4 unmodified lines | |||
| 1721 | /* XXX: incorrect if float reg to reg */ | 1721 | /* XXX: incorrect if float reg to reg */ |
| 1722 | 1722 | ||
| 1723 | if (bt == VT_LDOUBLE) { | 1723 | if (bt == VT_LDOUBLE) { |
| 1724 | tcc_error("long double not supported"); | 1724 | tcc_error(S, "long double not supported"); |
| 1725 | } else { | 1725 | } else { |
| 1726 | if (bt == VT_SHORT) | 1726 | if (bt == VT_SHORT) |
| 1727 | size = 2; | 1727 | size = 2; |
| @@ -1736,21 +1736,21 @@ void store(int r, SValue * v) · 8 unmodified lines | |||
| 1736 | /* constant memory reference */ | 1736 | /* constant memory reference */ |
| 1737 | 1737 | ||
| 1738 | if (v->r & VT_SYM) { | 1738 | if (v->r & VT_SYM) { |
| 1739 | greloc(cur_text_section, v->sym, ind, R_C60LO16); // rem the inst need to be patched | 1739 | greloc(S, cur_text_section, v->sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched |
| 1740 | greloc(cur_text_section, v->sym, ind + 4, R_C60HI16); | 1740 | greloc(S, cur_text_section, v->sym, S->tccgen_ind + 4, R_C60HI16); |
| 1741 | } | 1741 | } |
| 1742 | C67_MVKL(C67_A0, fc); //r=reg to load, constant | 1742 | C67_MVKL(S, C67_A0, fc); //r=reg to load, constant |
| 1743 | C67_MVKH(C67_A0, fc); //r=reg to load, constant | 1743 | C67_MVKH(S, C67_A0, fc); //r=reg to load, constant |
| 1744 | 1744 | ||
| 1745 | if (size == 1) | 1745 | if (size == 1) |
| 1746 | C67_STB_PTR(r, C67_A0); // STB r, *A0 | 1746 | C67_STB_PTR(S, r, C67_A0); // STB r, *A0 |
| 1747 | else if (size == 2) | 1747 | else if (size == 2) |
| 1748 | C67_STH_PTR(r, C67_A0); // STH r, *A0 | 1748 | C67_STH_PTR(S, r, C67_A0); // STH r, *A0 |
| 1749 | else if (size == 4 || size == 8) | 1749 | else if (size == 4 || size == 8) |
| 1750 | C67_STW_PTR(r, C67_A0); // STW r, *A0 | 1750 | C67_STW_PTR(S, r, C67_A0); // STW r, *A0 |
| 1751 | 1751 | ||
| 1752 | if (size == 8) | 1752 | if (size == 8) |
| 1753 | C67_STW_PTR_PRE_INC(r + 1, C67_A0, 1); // STW r, *+A0[1] | 1753 | C67_STW_PTR_PRE_INC(S, r + 1, C67_A0, 1); // STW r, *+A0[1] |
| 1754 | } else if ((v->r & VT_VALMASK) == VT_LOCAL) { | 1754 | } else if ((v->r & VT_VALMASK) == VT_LOCAL) { |
| 1755 | // check case of storing to passed argument that | 1755 | // check case of storing to passed argument that |
| 1756 | // tcc thinks is on the stack but for C67 is | 1756 | // tcc thinks is on the stack but for C67 is |
| @@ -1781,68 +1781,68 @@ void store(int r, SValue * v) · 24 unmodified lines | |||
| 1781 | element = size; | 1781 | element = size; |
| 1782 | 1782 | ||
| 1783 | // divide offset in bytes to create word index | 1783 | // divide offset in bytes to create word index |
| 1784 | C67_MVKL(C67_A0, (fc / element) + 8 / element); //r=reg to load, constant | 1784 | C67_MVKL(S, C67_A0, (fc / element) + 8 / element); //r=reg to load, constant |
| 1785 | C67_MVKH(C67_A0, (fc / element) + 8 / element); //r=reg to load, constant | 1785 | C67_MVKH(S, C67_A0, (fc / element) + 8 / element); //r=reg to load, constant |
| 1786 | 1786 | ||
| 1787 | 1787 | ||
| 1788 | 1788 | ||
| 1789 | if (size == 1) | 1789 | if (size == 1) |
| 1790 | C67_STB_SP_A0(r); // STB r, SP[A0] | 1790 | C67_STB_SP_A0(S, r); // STB r, SP[A0] |
| 1791 | else if (size == 2) | 1791 | else if (size == 2) |
| 1792 | C67_STH_SP_A0(r); // STH r, SP[A0] | 1792 | C67_STH_SP_A0(S, r); // STH r, SP[A0] |
| 1793 | else if (size == 4 || size == 8) | 1793 | else if (size == 4 || size == 8) |
| 1794 | C67_STW_SP_A0(r); // STW r, SP[A0] | 1794 | C67_STW_SP_A0(S, r); // STW r, SP[A0] |
| 1795 | 1795 | ||
| 1796 | if (size == 8) { | 1796 | if (size == 8) { |
| 1797 | C67_ADDK(1, C67_A0); // ADDK 1,A0 | 1797 | C67_ADDK(S, 1, C67_A0); // ADDK 1,A0 |
| 1798 | C67_STW_SP_A0(r + 1); // STW r, SP[A0] | 1798 | C67_STW_SP_A0(S, r + 1); // STW r, SP[A0] |
| 1799 | } | 1799 | } |
| 1800 | } else { | 1800 | } else { |
| 1801 | if (size == 1) | 1801 | if (size == 1) |
| 1802 | C67_STB_PTR(r, fr); // STB r, *fr | 1802 | C67_STB_PTR(S, r, fr); // STB r, *fr |
| 1803 | else if (size == 2) | 1803 | else if (size == 2) |
| 1804 | C67_STH_PTR(r, fr); // STH r, *fr | 1804 | C67_STH_PTR(S, r, fr); // STH r, *fr |
| 1805 | else if (size == 4 || size == 8) | 1805 | else if (size == 4 || size == 8) |
| 1806 | C67_STW_PTR(r, fr); // STW r, *fr | 1806 | C67_STW_PTR(S, r, fr); // STW r, *fr |
| 1807 | 1807 | ||
| 1808 | if (size == 8) { | 1808 | if (size == 8) { |
| 1809 | C67_STW_PTR_PRE_INC(r + 1, fr, 1); // STW r, *+fr[1] | 1809 | C67_STW_PTR_PRE_INC(S, r + 1, fr, 1); // STW r, *+fr[1] |
| 1810 | } | 1810 | } |
| 1811 | } | 1811 | } |
| 1812 | } | 1812 | } |
| 1813 | } | 1813 | } |
| 1814 | 1814 | ||
| 1815 | /* 'is_jmp' is '1' if it is a jump */ | 1815 | /* 'is_jmp' is '1' if it is a jump */ |
| 1816 | static void gcall_or_jmp(int is_jmp) | 1816 | static void gcall_or_jmp(TCCState* S, int is_jmp) |
| 1817 | { | 1817 | { |
| 1818 | int r; | 1818 | int r; |
| 1819 | Sym *sym; | 1819 | Sym *sym; |
| 1820 | 1820 | ||
| 1821 | if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { | 1821 | if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { |
| 1822 | /* constant case */ | 1822 | /* constant case */ |
| 1823 | if (vtop->r & VT_SYM) { | 1823 | if (S->tccgen_vtop->r & VT_SYM) { |
| 1824 | /* relocation case */ | 1824 | /* relocation case */ |
| 1825 | 1825 | ||
| 1826 | // get add into A0, then start the jump B3 | 1826 | // get add into A0, then start the jump B3 |
| 1827 | 1827 | ||
| 1828 | greloc(cur_text_section, vtop->sym, ind, R_C60LO16); // rem the inst need to be patched | 1828 | greloc(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched |
| 1829 | greloc(cur_text_section, vtop->sym, ind + 4, R_C60HI16); | 1829 | greloc(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind + 4, R_C60HI16); |
| 1830 | 1830 | ||
| 1831 | C67_MVKL(C67_A0, 0); //r=reg to load, constant | 1831 | C67_MVKL(S, C67_A0, 0); //r=reg to load, constant |
| 1832 | C67_MVKH(C67_A0, 0); //r=reg to load, constant | 1832 | C67_MVKH(S, C67_A0, 0); //r=reg to load, constant |
| 1833 | C67_IREG_B_REG(0, C67_CREG_ZERO, C67_A0); // B.S2x A0 | 1833 | C67_IREG_B_REG(S, 0, C67_CREG_ZERO, C67_A0); // B.S2x A0 |
| 1834 | 1834 | ||
| 1835 | if (is_jmp) { | 1835 | if (is_jmp) { |
| 1836 | C67_NOP(5); // simple jump, just put NOP | 1836 | C67_NOP(S, 5); // simple jump, just put NOP |
| 1837 | } else { | 1837 | } else { |
| 1838 | // Call, must load return address into B3 during delay slots | 1838 | // Call, must load return address into B3 during delay slots |
| 1839 | 1839 | ||
| 1840 | sym = get_sym_ref(&char_pointer_type, cur_text_section, ind + 12, 0); // symbol for return address | 1840 | sym = get_sym_ref(S, &S->tccgen_char_pointer_type, cur_text_section, S->tccgen_ind + 12, 0); // symbol for return address |
| 1841 | greloc(cur_text_section, sym, ind, R_C60LO16); // rem the inst need to be patched | 1841 | greloc(S, cur_text_section, sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched |
| 1842 | greloc(cur_text_section, sym, ind + 4, R_C60HI16); | 1842 | greloc(S, cur_text_section, sym, S->tccgen_ind + 4, R_C60HI16); |
| 1843 | C67_MVKL(C67_B3, 0); //r=reg to load, constant | 1843 | C67_MVKL(S, C67_B3, 0); //r=reg to load, constant |
| 1844 | C67_MVKH(C67_B3, 0); //r=reg to load, constant | 1844 | C67_MVKH(S, C67_B3, 0); //r=reg to load, constant |
| 1845 | C67_NOP(3); // put remaining NOPs | 1845 | C67_NOP(S, 3); // put remaining NOPs |
| 1846 | } | 1846 | } |
| 1847 | } else { | 1847 | } else { |
| 1848 | /* put an empty PC32 relocation */ | 1848 | /* put an empty PC32 relocation */ |
| @@ -1850,20 +1850,20 @@ static void gcall_or_jmp(int is_jmp) · 1 unmodified line | |||
| 1850 | } | 1850 | } |
| 1851 | } else { | 1851 | } else { |
| 1852 | /* otherwise, indirect call */ | 1852 | /* otherwise, indirect call */ |
| 1853 | r = gv(RC_INT); | 1853 | r = gv(S, RC_INT); |
| 1854 | C67_IREG_B_REG(0, C67_CREG_ZERO, r); // B.S2x r | 1854 | C67_IREG_B_REG(S, 0, C67_CREG_ZERO, r); // B.S2x r |
| 1855 | 1855 | ||
| 1856 | if (is_jmp) { | 1856 | if (is_jmp) { |
| 1857 | C67_NOP(5); // simple jump, just put NOP | 1857 | C67_NOP(S, 5); // simple jump, just put NOP |
| 1858 | } else { | 1858 | } else { |
| 1859 | // Call, must load return address into B3 during delay slots | 1859 | // Call, must load return address into B3 during delay slots |
| 1860 | 1860 | ||
| 1861 | sym = get_sym_ref(&char_pointer_type, cur_text_section, ind + 12, 0); // symbol for return address | 1861 | sym = get_sym_ref(S, &S->tccgen_char_pointer_type, cur_text_section, S->tccgen_ind + 12, 0); // symbol for return address |
| 1862 | greloc(cur_text_section, sym, ind, R_C60LO16); // rem the inst need to be patched | 1862 | greloc(S, cur_text_section, sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched |
| 1863 | greloc(cur_text_section, sym, ind + 4, R_C60HI16); | 1863 | greloc(S, cur_text_section, sym, S->tccgen_ind + 4, R_C60HI16); |
| 1864 | C67_MVKL(C67_B3, 0); //r=reg to load, constant | 1864 | C67_MVKL(S, C67_B3, 0); //r=reg to load, constant |
| 1865 | C67_MVKH(C67_B3, 0); //r=reg to load, constant | 1865 | C67_MVKH(S, C67_B3, 0); //r=reg to load, constant |
| 1866 | C67_NOP(3); // put remaining NOPs | 1866 | C67_NOP(S, 3); // put remaining NOPs |
| 1867 | } | 1867 | } |
| 1868 | } | 1868 | } |
| 1869 | } | 1869 | } |
| @@ -1877,29 +1877,29 @@ ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int · 7 unmodified lines | |||
| 1877 | 1877 | ||
| 1878 | /* generate function call with address in (vtop->t, vtop->c) and free function | 1878 | /* generate function call with address in (vtop->t, vtop->c) and free function |
| 1879 | context. Stack entry is popped */ | 1879 | context. Stack entry is popped */ |
| 1880 | void gfunc_call(int nb_args) | 1880 | void gfunc_call(TCCState* S, int nb_args) |
| 1881 | { | 1881 | { |
| 1882 | int i, r, size = 0; | 1882 | int i, r, size = 0; |
| 1883 | int args_sizes[NoCallArgsPassedOnStack]; | 1883 | int args_sizes[NoCallArgsPassedOnStack]; |
| 1884 | 1884 | ||
| 1885 | if (nb_args > NoCallArgsPassedOnStack) { | 1885 | if (nb_args > NoCallArgsPassedOnStack) { |
| 1886 | tcc_error("more than 10 function params not currently supported"); | 1886 | tcc_error(S, "more than 10 function params not currently supported"); |
| 1887 | // handle more than 10, put some on the stack | 1887 | // handle more than 10, put some on the stack |
| 1888 | } | 1888 | } |
| 1889 | 1889 | ||
| 1890 | for (i = 0; i < nb_args; i++) { | 1890 | for (i = 0; i < nb_args; i++) { |
| 1891 | if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) { | 1891 | if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_STRUCT) { |
| 1892 | ALWAYS_ASSERT(FALSE); | 1892 | ALWAYS_ASSERT(FALSE); |
| 1893 | } else { | 1893 | } else { |
| 1894 | /* simple type (currently always same size) */ | 1894 | /* simple type (currently always same size) */ |
| 1895 | /* XXX: implicit cast ? */ | 1895 | /* XXX: implicit cast ? */ |
| 1896 | 1896 | ||
| 1897 | 1897 | ||
| 1898 | if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { | 1898 | if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG) { |
| 1899 | tcc_error("long long not supported"); | 1899 | tcc_error(S, "long long not supported"); |
| 1900 | } else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { | 1900 | } else if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { |
| 1901 | tcc_error("long double not supported"); | 1901 | tcc_error(S, "long double not supported"); |
| 1902 | } else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) { | 1902 | } else if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_DOUBLE) { |
| 1903 | size = 8; | 1903 | size = 8; |
| 1904 | } else { | 1904 | } else { |
| 1905 | size = 4; | 1905 | size = 4; |
| @@ -1907,19 +1907,19 @@ void gfunc_call(int nb_args) · 1 unmodified line | |||
| 1907 | 1907 | ||
| 1908 | // put the parameter into the corresponding reg (pair) | 1908 | // put the parameter into the corresponding reg (pair) |
| 1909 | 1909 | ||
| 1910 | r = gv(RC_C67_A4 << (2 * i)); | 1910 | r = gv(S, RC_C67_A4 << (2 * i)); |
| 1911 | 1911 | ||
| 1912 | // must put on stack because with 1 pass compiler , no way to tell | 1912 | // must put on stack because with 1 pass compiler , no way to tell |
| 1913 | // if an up coming nested call might overwrite these regs | 1913 | // if an up coming nested call might overwrite these regs |
| 1914 | 1914 | ||
| 1915 | C67_PUSH(r); | 1915 | C67_PUSH(S, r); |
| 1916 | 1916 | ||
| 1917 | if (size == 8) { | 1917 | if (size == 8) { |
| 1918 | C67_STW_PTR_PRE_INC(r + 1, C67_SP, 3); // STW r, *+SP[3] (go back and put the other) | 1918 | C67_STW_PTR_PRE_INC(S, r + 1, C67_SP, 3); // STW r, *+SP[3] (go back and put the other) |
| 1919 | } | 1919 | } |
| 1920 | args_sizes[i] = size; | 1920 | args_sizes[i] = size; |
| 1921 | } | 1921 | } |
| 1922 | vtop--; | 1922 | S->tccgen_vtop--; |
| 1923 | } | 1923 | } |
| 1924 | // POP all the params on the stack into registers for the | 1924 | // POP all the params on the stack into registers for the |
| 1925 | // immediate call (in reverse order) | 1925 | // immediate call (in reverse order) |
| @@ -1927,12 +1927,12 @@ void gfunc_call(int nb_args) · 1 unmodified line | |||
| 1927 | for (i = nb_args - 1; i >= 0; i--) { | 1927 | for (i = nb_args - 1; i >= 0; i--) { |
| 1928 | 1928 | ||
| 1929 | if (args_sizes[i] == 8) | 1929 | if (args_sizes[i] == 8) |
| 1930 | C67_POP_DW(TREG_C67_A4 + i * 2); | 1930 | C67_POP_DW(S, TREG_C67_A4 + i * 2); |
| 1931 | else | 1931 | else |
| 1932 | C67_POP(TREG_C67_A4 + i * 2); | 1932 | C67_POP(S, TREG_C67_A4 + i * 2); |
| 1933 | } | 1933 | } |
| 1934 | gcall_or_jmp(0); | 1934 | gcall_or_jmp(S, 0); |
| 1935 | vtop--; | 1935 | S->tccgen_vtop--; |
| 1936 | } | 1936 | } |
| 1937 | 1937 | ||
| 1938 | 1938 | ||
| @@ -1946,7 +1946,7 @@ void gfunc_call(int nb_args) · 7 unmodified lines | |||
| 1946 | // parameters are loaded and restored upon return (or if/when needed). | 1946 | // parameters are loaded and restored upon return (or if/when needed). |
| 1947 | 1947 | ||
| 1948 | /* generate function prolog of type 't' */ | 1948 | /* generate function prolog of type 't' */ |
| 1949 | void gfunc_prolog(Sym *func_sym) | 1949 | void gfunc_prolog(TCCState* S, Sym *func_sym) |
| 1950 | { | 1950 | { |
| 1951 | CType *func_type = &func_sym->type; | 1951 | CType *func_type = &func_sym->type; |
| 1952 | int addr, align, size, func_call, i; | 1952 | int addr, align, size, func_call, i; |
| @@ -1958,8 +1958,8 @@ void gfunc_prolog(Sym *func_sym) · 5 unmodified lines | |||
| 1958 | addr = 8; | 1958 | addr = 8; |
| 1959 | /* if the function returns a structure, then add an | 1959 | /* if the function returns a structure, then add an |
| 1960 | implicit pointer parameter */ | 1960 | implicit pointer parameter */ |
| 1961 | if ((func_vt.t & VT_BTYPE) == VT_STRUCT) { | 1961 | if ((S->tccgen_func_vt.t & VT_BTYPE) == VT_STRUCT) { |
| 1962 | func_vc = addr; | 1962 | S->tccgen_func_vc = addr; |
| 1963 | addr += 4; | 1963 | addr += 4; |
| 1964 | } | 1964 | } |
| 1965 | 1965 | ||
| @@ -1968,7 +1968,7 @@ void gfunc_prolog(Sym *func_sym) · 2 unmodified lines | |||
| 1968 | /* define parameters */ | 1968 | /* define parameters */ |
| 1969 | while ((sym = sym->next) != NULL) { | 1969 | while ((sym = sym->next) != NULL) { |
| 1970 | type = &sym->type; | 1970 | type = &sym->type; |
| 1971 | sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL, addr); | 1971 | sym_push(S, sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL, addr); |
| 1972 | size = type_size(type, &align); | 1972 | size = type_size(type, &align); |
| 1973 | size = (size + 3) & ~3; | 1973 | size = (size + 3) & ~3; |
| 1974 | 1974 | ||
| @@ -1992,76 +1992,76 @@ void gfunc_prolog(Sym *func_sym) · 17 unmodified lines | |||
| 1992 | if (func_call == FUNC_STDCALL) | 1992 | if (func_call == FUNC_STDCALL) |
| 1993 | func_ret_sub = addr - 8; | 1993 | func_ret_sub = addr - 8; |
| 1994 | 1994 | ||
| 1995 | C67_MV(C67_FP, C67_A0); // move FP -> A0 | 1995 | C67_MV(S, C67_FP, C67_A0); // move FP -> A0 |
| 1996 | C67_MV(C67_SP, C67_FP); // move SP -> FP | 1996 | C67_MV(S, C67_SP, C67_FP); // move SP -> FP |
| 1997 | 1997 | ||
| 1998 | // place all the args passed in regs onto the stack | 1998 | // place all the args passed in regs onto the stack |
| 1999 | 1999 | ||
| 2000 | loc = 0; | 2000 | S->tccgen_loc = 0; |
| 2001 | for (i = 0; i < NoOfCurFuncArgs; i++) { | 2001 | for (i = 0; i < NoOfCurFuncArgs; i++) { |
| 2002 | 2002 | ||
| 2003 | ParamLocOnStack[i] = loc; // remember where the param is | 2003 | ParamLocOnStack[i] = S->tccgen_loc; // remember where the param is |
| 2004 | loc += -8; | 2004 | S->tccgen_loc += -8; |
| 2005 | 2005 | ||
| 2006 | C67_PUSH(TREG_C67_A4 + i * 2); | 2006 | C67_PUSH(S, TREG_C67_A4 + i * 2); |
| 2007 | 2007 | ||
| 2008 | if (TranslateStackToReg[i] == 8) { | 2008 | if (TranslateStackToReg[i] == 8) { |
| 2009 | C67_STW_PTR_PRE_INC(TREG_C67_A4 + i * 2 + 1, C67_SP, 3); // STW r, *+SP[1] (go back and put the other) | 2009 | C67_STW_PTR_PRE_INC(S, TREG_C67_A4 + i * 2 + 1, C67_SP, 3); // STW r, *+SP[1] (go back and put the other) |
| 2010 | } | 2010 | } |
| 2011 | } | 2011 | } |
| 2012 | 2012 | ||
| 2013 | TotalBytesPushedOnStack = -loc; | 2013 | TotalBytesPushedOnStack = -S->tccgen_loc; |
| 2014 | 2014 | ||
| 2015 | func_sub_sp_offset = ind; // remember where we put the stack instruction | 2015 | func_sub_sp_offset = S->tccgen_ind; // remember where we put the stack instruction |
| 2016 | C67_ADDK(0, C67_SP); // ADDK.L2 loc,SP (just put zero temporarily) | 2016 | C67_ADDK(S, 0, C67_SP); // ADDK.L2 loc,SP (just put zero temporarily) |
| 2017 | 2017 | ||
| 2018 | C67_PUSH(C67_A0); | 2018 | C67_PUSH(S, C67_A0); |
| 2019 | C67_PUSH(C67_B3); | 2019 | C67_PUSH(S, C67_B3); |
| 2020 | } | 2020 | } |
| 2021 | 2021 | ||
| 2022 | /* generate function epilog */ | 2022 | /* generate function epilog */ |
| 2023 | void gfunc_epilog(void) | 2023 | void gfunc_epilog(TCCState* S) |
| 2024 | { | 2024 | { |
| 2025 | { | 2025 | { |
| 2026 | int local = (-loc + 7) & -8; // stack must stay aligned to 8 bytes for LDDW instr | 2026 | int local = (-S->tccgen_loc + 7) & -8; // stack must stay aligned to 8 bytes for LDDW instr |
| 2027 | C67_POP(C67_B3); | 2027 | C67_POP(S, C67_B3); |
| 2028 | C67_NOP(4); // NOP wait for load | 2028 | C67_NOP(S, 4); // NOP wait for load |
| 2029 | C67_IREG_B_REG(0, C67_CREG_ZERO, C67_B3); // B.S2 B3 | 2029 | C67_IREG_B_REG(S, 0, C67_CREG_ZERO, C67_B3); // B.S2 B3 |
| 2030 | C67_POP(C67_FP); | 2030 | C67_POP(S, C67_FP); |
| 2031 | C67_ADDK(local, C67_SP); // ADDK.L2 loc,SP | 2031 | C67_ADDK(S, local, C67_SP); // ADDK.L2 loc,SP |
| 2032 | C67_Adjust_ADDK((int *) (cur_text_section->data + | 2032 | C67_Adjust_ADDK(S, (int *) (cur_text_section->data + |
| 2033 | func_sub_sp_offset), | 2033 | func_sub_sp_offset), |
| 2034 | -local + TotalBytesPushedOnStack); | 2034 | -local + TotalBytesPushedOnStack); |
| 2035 | C67_NOP(3); // NOP | 2035 | C67_NOP(S, 3); // NOP |
| 2036 | } | 2036 | } |
| 2037 | } | 2037 | } |
| 2038 | 2038 | ||
| 2039 | ST_FUNC void gen_fill_nops(int bytes) | 2039 | ST_FUNC void gen_fill_nops(TCCState* S, int bytes) |
| 2040 | { | 2040 | { |
| 2041 | if ((bytes & 3)) | 2041 | if ((bytes & 3)) |
| 2042 | tcc_error("alignment of code section not multiple of 4"); | 2042 | tcc_error(S, "alignment of code section not multiple of 4"); |
| 2043 | while (bytes > 0) { | 2043 | while (bytes > 0) { |
| 2044 | C67_NOP(4); | 2044 | C67_NOP(S, 4); |
| 2045 | bytes -= 4; | 2045 | bytes -= 4; |
| 2046 | } | 2046 | } |
| 2047 | } | 2047 | } |
| 2048 | 2048 | ||
| 2049 | /* generate a jump to a label */ | 2049 | /* generate a jump to a label */ |
| 2050 | int gjmp(int t) | 2050 | int gjmp(TCCState* S, int t) |
| 2051 | { | 2051 | { |
| 2052 | int ind1 = ind; | 2052 | int ind1 = S->tccgen_ind; |
| 2053 | if (nocode_wanted) | 2053 | if (S->tccgen_nocode_wanted) |
| 2054 | return t; | 2054 | return t; |
| 2055 | 2055 | ||
| 2056 | C67_MVKL(C67_A0, t); //r=reg to load, constant | 2056 | C67_MVKL(S, C67_A0, t); //r=reg to load, constant |
| 2057 | C67_MVKH(C67_A0, t); //r=reg to load, constant | 2057 | C67_MVKH(S, C67_A0, t); //r=reg to load, constant |
| 2058 | C67_IREG_B_REG(0, C67_CREG_ZERO, C67_A0); // [!R] B.S2x A0 | 2058 | C67_IREG_B_REG(S, 0, C67_CREG_ZERO, C67_A0); // [!R] B.S2x A0 |
| 2059 | C67_NOP(5); | 2059 | C67_NOP(S, 5); |
| 2060 | return ind1; | 2060 | return ind1; |
| 2061 | } | 2061 | } |
| 2062 | 2062 | ||
| 2063 | /* generate a jump to a fixed address */ | 2063 | /* generate a jump to a fixed address */ |
| 2064 | void gjmp_addr(int a) | 2064 | void gjmp_addr(TCCState* S, int a) |
| 2065 | { | 2065 | { |
| 2066 | Sym *sym; | 2066 | Sym *sym; |
| 2067 | // I guess this routine is used for relative short | 2067 | // I guess this routine is used for relative short |
| @@ -2070,42 +2070,42 @@ void gjmp_addr(int a) · 2 unmodified lines | |||
| 2070 | 2070 | ||
| 2071 | // define a label that will be relocated | 2071 | // define a label that will be relocated |
| 2072 | 2072 | ||
| 2073 | sym = get_sym_ref(&char_pointer_type, cur_text_section, a, 0); | 2073 | sym = get_sym_ref(S, &S->tccgen_char_pointer_type, cur_text_section, a, 0); |
| 2074 | greloc(cur_text_section, sym, ind, R_C60LO16); | 2074 | greloc(S, cur_text_section, sym, S->tccgen_ind, R_C60LO16); |
| 2075 | greloc(cur_text_section, sym, ind + 4, R_C60HI16); | 2075 | greloc(S, cur_text_section, sym, S->tccgen_ind + 4, R_C60HI16); |
| 2076 | 2076 | ||
| 2077 | gjmp(0); // place a zero there later the symbol will be added to it | 2077 | gjmp(S, 0); // place a zero there later the symbol will be added to it |
| 2078 | } | 2078 | } |
| 2079 | 2079 | ||
| 2080 | /* generate a test. set 'inv' to invert test. Stack entry is popped */ | 2080 | /* generate a test. set 'inv' to invert test. Stack entry is popped */ |
| 2081 | ST_FUNC int gjmp_cond(int op, int t) | 2081 | ST_FUNC int gjmp_cond(TCCState* S, int op, int t) |
| 2082 | { | 2082 | { |
| 2083 | int ind1; | 2083 | int ind1; |
| 2084 | int inv = op & 1; | 2084 | int inv = op & 1; |
| 2085 | if (nocode_wanted) | 2085 | if (S->tccgen_nocode_wanted) |
| 2086 | return t; | 2086 | return t; |
| 2087 | 2087 | ||
| 2088 | /* fast case : can jump directly since flags are set */ | 2088 | /* fast case : can jump directly since flags are set */ |
| 2089 | // C67 uses B2 sort of as flags register | 2089 | // C67 uses B2 sort of as flags register |
| 2090 | ind1 = ind; | 2090 | ind1 = S->tccgen_ind; |
| 2091 | C67_MVKL(C67_A0, t); //r=reg to load, constant | 2091 | C67_MVKL(S, C67_A0, t); //r=reg to load, constant |
| 2092 | C67_MVKH(C67_A0, t); //r=reg to load, constant | 2092 | C67_MVKH(S, C67_A0, t); //r=reg to load, constant |
| 2093 | 2093 | ||
| 2094 | if (C67_compare_reg != TREG_EAX && // check if not already in a conditional test reg | 2094 | if (C67_compare_reg != TREG_EAX && // check if not already in a conditional test reg |
| 2095 | C67_compare_reg != TREG_EDX && | 2095 | C67_compare_reg != TREG_EDX && |
| 2096 | C67_compare_reg != TREG_ST0 && C67_compare_reg != C67_B2) { | 2096 | C67_compare_reg != TREG_ST0 && C67_compare_reg != C67_B2) { |
| 2097 | C67_MV(C67_compare_reg, C67_B2); | 2097 | C67_MV(S, C67_compare_reg, C67_B2); |
| 2098 | C67_compare_reg = C67_B2; | 2098 | C67_compare_reg = C67_B2; |
| 2099 | } | 2099 | } |
| 2100 | 2100 | ||
| 2101 | C67_IREG_B_REG(C67_invert_test ^ inv, C67_compare_reg, C67_A0); // [!R] B.S2x A0 | 2101 | C67_IREG_B_REG(S, C67_invert_test ^ inv, C67_compare_reg, C67_A0); // [!R] B.S2x A0 |
| 2102 | C67_NOP(5); | 2102 | C67_NOP(S, 5); |
| 2103 | t = ind1; //return where we need to patch | 2103 | t = ind1; //return where we need to patch |
| 2104 | 2104 | ||
| 2105 | return t; | 2105 | return t; |
| 2106 | } | 2106 | } |
| 2107 | 2107 | ||
| 2108 | ST_FUNC int gjmp_append(int n0, int t) | 2108 | ST_FUNC int gjmp_append(TCCState* S, int n0, int t) |
| 2109 | { | 2109 | { |
| 2110 | if (n0) { | 2110 | if (n0) { |
| 2111 | int n = n0, *p; | 2111 | int n = n0, *p; |
| @@ -2129,7 +2129,7 @@ ST_FUNC int gjmp_append(int n0, int t) · 17 unmodified lines | |||
| 2129 | } | 2129 | } |
| 2130 | 2130 | ||
| 2131 | /* generate an integer binary operation */ | 2131 | /* generate an integer binary operation */ |
| 2132 | void gen_opi(int op) | 2132 | void gen_opi(TCCState* S, int op) |
| 2133 | { | 2133 | { |
| 2134 | int r, fr, opc, t; | 2134 | int r, fr, opc, t; |
| 2135 | 2135 | ||
| @@ -2146,62 +2146,62 @@ void gen_opi(int op) · 10 unmodified lines | |||
| 2146 | 2146 | ||
| 2147 | 2147 | ||
| 2148 | if (op >= TOK_ULT && op <= TOK_GT) | 2148 | if (op >= TOK_ULT && op <= TOK_GT) |
| 2149 | gv2(RC_INT_BSIDE, RC_INT); // make sure r (src1) is on the B Side of CPU | 2149 | gv2(S, RC_INT_BSIDE, RC_INT); // make sure r (src1) is on the B Side of CPU |
| 2150 | else | 2150 | else |
| 2151 | gv2(RC_INT, RC_INT); | 2151 | gv2(S, RC_INT, RC_INT); |
| 2152 | 2152 | ||
| 2153 | r = vtop[-1].r; | 2153 | r = S->tccgen_vtop[-1].r; |
| 2154 | fr = vtop[0].r; | 2154 | fr = S->tccgen_vtop[0].r; |
| 2155 | 2155 | ||
| 2156 | C67_compare_reg = C67_B2; | 2156 | C67_compare_reg = C67_B2; |
| 2157 | 2157 | ||
| 2158 | 2158 | ||
| 2159 | if (op == TOK_LT) { | 2159 | if (op == TOK_LT) { |
| 2160 | C67_CMPLT(r, fr, C67_B2); | 2160 | C67_CMPLT(S, r, fr, C67_B2); |
| 2161 | C67_invert_test = FALSE; | 2161 | C67_invert_test = FALSE; |
| 2162 | } else if (op == TOK_GE) { | 2162 | } else if (op == TOK_GE) { |
| 2163 | C67_CMPLT(r, fr, C67_B2); | 2163 | C67_CMPLT(S, r, fr, C67_B2); |
| 2164 | C67_invert_test = TRUE; | 2164 | C67_invert_test = TRUE; |
| 2165 | } else if (op == TOK_GT) { | 2165 | } else if (op == TOK_GT) { |
| 2166 | C67_CMPGT(r, fr, C67_B2); | 2166 | C67_CMPGT(S, r, fr, C67_B2); |
| 2167 | C67_invert_test = FALSE; | 2167 | C67_invert_test = FALSE; |
| 2168 | } else if (op == TOK_LE) { | 2168 | } else if (op == TOK_LE) { |
| 2169 | C67_CMPGT(r, fr, C67_B2); | 2169 | C67_CMPGT(S, r, fr, C67_B2); |
| 2170 | C67_invert_test = TRUE; | 2170 | C67_invert_test = TRUE; |
| 2171 | } else if (op == TOK_EQ) { | 2171 | } else if (op == TOK_EQ) { |
| 2172 | C67_CMPEQ(r, fr, C67_B2); | 2172 | C67_CMPEQ(S, r, fr, C67_B2); |
| 2173 | C67_invert_test = FALSE; | 2173 | C67_invert_test = FALSE; |
| 2174 | } else if (op == TOK_NE) { | 2174 | } else if (op == TOK_NE) { |
| 2175 | C67_CMPEQ(r, fr, C67_B2); | 2175 | C67_CMPEQ(S, r, fr, C67_B2); |
| 2176 | C67_invert_test = TRUE; | 2176 | C67_invert_test = TRUE; |
| 2177 | } else if (op == TOK_ULT) { | 2177 | } else if (op == TOK_ULT) { |
| 2178 | C67_CMPLTU(r, fr, C67_B2); | 2178 | C67_CMPLTU(S, r, fr, C67_B2); |
| 2179 | C67_invert_test = FALSE; | 2179 | C67_invert_test = FALSE; |
| 2180 | } else if (op == TOK_UGE) { | 2180 | } else if (op == TOK_UGE) { |
| 2181 | C67_CMPLTU(r, fr, C67_B2); | 2181 | C67_CMPLTU(S, r, fr, C67_B2); |
| 2182 | C67_invert_test = TRUE; | 2182 | C67_invert_test = TRUE; |
| 2183 | } else if (op == TOK_UGT) { | 2183 | } else if (op == TOK_UGT) { |
| 2184 | C67_CMPGTU(r, fr, C67_B2); | 2184 | C67_CMPGTU(S, r, fr, C67_B2); |
| 2185 | C67_invert_test = FALSE; | 2185 | C67_invert_test = FALSE; |
| 2186 | } else if (op == TOK_ULE) { | 2186 | } else if (op == TOK_ULE) { |
| 2187 | C67_CMPGTU(r, fr, C67_B2); | 2187 | C67_CMPGTU(S, r, fr, C67_B2); |
| 2188 | C67_invert_test = TRUE; | 2188 | C67_invert_test = TRUE; |
| 2189 | } else if (op == '+') | 2189 | } else if (op == '+') |
| 2190 | C67_ADD(fr, r); // ADD r,fr,r | 2190 | C67_ADD(S, fr, r); // ADD r,fr,r |
| 2191 | else if (op == '-') | 2191 | else if (op == '-') |
| 2192 | C67_SUB(fr, r); // SUB r,fr,r | 2192 | C67_SUB(S, fr, r); // SUB r,fr,r |
| 2193 | else if (op == '&') | 2193 | else if (op == '&') |
| 2194 | C67_AND(fr, r); // AND r,fr,r | 2194 | C67_AND(S, fr, r); // AND r,fr,r |
| 2195 | else if (op == '|') | 2195 | else if (op == '|') |
| 2196 | C67_OR(fr, r); // OR r,fr,r | 2196 | C67_OR(S, fr, r); // OR r,fr,r |
| 2197 | else if (op == '^') | 2197 | else if (op == '^') |
| 2198 | C67_XOR(fr, r); // XOR r,fr,r | 2198 | C67_XOR(S, fr, r); // XOR r,fr,r |
| 2199 | else | 2199 | else |
| 2200 | ALWAYS_ASSERT(FALSE); | 2200 | ALWAYS_ASSERT(FALSE); |
| 2201 | 2201 | ||
| 2202 | vtop--; | 2202 | S->tccgen_vtop--; |
| 2203 | if (op >= TOK_ULT && op <= TOK_GT) | 2203 | if (op >= TOK_ULT && op <= TOK_GT) |
| 2204 | vset_VT_CMP(0x80); | 2204 | vset_VT_CMP(S, 0x80); |
| 2205 | break; | 2205 | break; |
| 2206 | case '-': | 2206 | case '-': |
| 2207 | case TOK_SUBC1: /* sub with carry generation */ | 2207 | case TOK_SUBC1: /* sub with carry generation */ |
| @@ -2224,48 +2224,48 @@ void gen_opi(int op) · 16 unmodified lines | |||
| 2224 | goto gen_op8; | 2224 | goto gen_op8; |
| 2225 | case '*': | 2225 | case '*': |
| 2226 | case TOK_UMULL: | 2226 | case TOK_UMULL: |
| 2227 | gv2(RC_INT, RC_INT); | 2227 | gv2(S, RC_INT, RC_INT); |
| 2228 | r = vtop[-1].r; | 2228 | r = S->tccgen_vtop[-1].r; |
| 2229 | fr = vtop[0].r; | 2229 | fr = S->tccgen_vtop[0].r; |
| 2230 | vtop--; | 2230 | S->tccgen_vtop--; |
| 2231 | C67_MPYI(fr, r); // 32 bit multiply fr,r,fr | 2231 | C67_MPYI(S, fr, r); // 32 bit multiply fr,r,fr |
| 2232 | C67_NOP(8); // NOP 8 for worst case | 2232 | C67_NOP(S, 8); // NOP 8 for worst case |
| 2233 | break; | 2233 | break; |
| 2234 | case TOK_SHL: | 2234 | case TOK_SHL: |
| 2235 | gv2(RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst | 2235 | gv2(S, RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst |
| 2236 | r = vtop[-1].r; | 2236 | r = S->tccgen_vtop[-1].r; |
| 2237 | fr = vtop[0].r; | 2237 | fr = S->tccgen_vtop[0].r; |
| 2238 | vtop--; | 2238 | S->tccgen_vtop--; |
| 2239 | C67_SHL(fr, r); // arithmetic/logical shift | 2239 | C67_SHL(S, fr, r); // arithmetic/logical shift |
| 2240 | break; | 2240 | break; |
| 2241 | 2241 | ||
| 2242 | case TOK_SHR: | 2242 | case TOK_SHR: |
| 2243 | gv2(RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst | 2243 | gv2(S, RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst |
| 2244 | r = vtop[-1].r; | 2244 | r = S->tccgen_vtop[-1].r; |
| 2245 | fr = vtop[0].r; | 2245 | fr = S->tccgen_vtop[0].r; |
| 2246 | vtop--; | 2246 | S->tccgen_vtop--; |
| 2247 | C67_SHRU(fr, r); // logical shift | 2247 | C67_SHRU(S, fr, r); // logical shift |
| 2248 | break; | 2248 | break; |
| 2249 | 2249 | ||
| 2250 | case TOK_SAR: | 2250 | case TOK_SAR: |
| 2251 | gv2(RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst | 2251 | gv2(S, RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst |
| 2252 | r = vtop[-1].r; | 2252 | r = S->tccgen_vtop[-1].r; |
| 2253 | fr = vtop[0].r; | 2253 | fr = S->tccgen_vtop[0].r; |
| 2254 | vtop--; | 2254 | S->tccgen_vtop--; |
| 2255 | C67_SHR(fr, r); // arithmetic shift | 2255 | C67_SHR(S, fr, r); // arithmetic shift |
| 2256 | break; | 2256 | break; |
| 2257 | 2257 | ||
| 2258 | case '/': | 2258 | case '/': |
| 2259 | t = TOK__divi; | 2259 | t = TOK__divi; |
| 2260 | call_func: | 2260 | call_func: |
| 2261 | vswap(); | 2261 | vswap(S); |
| 2262 | /* call generic idiv function */ | 2262 | /* call generic idiv function */ |
| 2263 | vpush_helper_func(t); | 2263 | vpush_helper_func(S, t); |
| 2264 | vrott(3); | 2264 | vrott(S, 3); |
| 2265 | gfunc_call(2); | 2265 | gfunc_call(S, 2); |
| 2266 | vpushi(0); | 2266 | vpushi(S, 0); |
| 2267 | vtop->r = REG_IRET; | 2267 | S->tccgen_vtop->r = REG_IRET; |
| 2268 | vtop->r2 = VT_CONST; | 2268 | S->tccgen_vtop->r2 = VT_CONST; |
| 2269 | break; | 2269 | break; |
| 2270 | case TOK_UDIV: | 2270 | case TOK_UDIV: |
| 2271 | case TOK_PDIV: | 2271 | case TOK_PDIV: |
| @@ -2287,127 +2287,127 @@ void gen_opi(int op) · 15 unmodified lines | |||
| 2287 | /* generate a floating point operation 'v = t1 op t2' instruction. The | 2287 | /* generate a floating point operation 'v = t1 op t2' instruction. The |
| 2288 | two operands are guaranteed to have the same floating point type */ | 2288 | two operands are guaranteed to have the same floating point type */ |
| 2289 | /* XXX: need to use ST1 too */ | 2289 | /* XXX: need to use ST1 too */ |
| 2290 | void gen_opf(int op) | 2290 | void gen_opf(TCCState* S, int op) |
| 2291 | { | 2291 | { |
| 2292 | int ft, fc, fr, r; | 2292 | int ft, fc, fr, r; |
| 2293 | 2293 | ||
| 2294 | if (op >= TOK_ULT && op <= TOK_GT) | 2294 | if (op >= TOK_ULT && op <= TOK_GT) |
| 2295 | gv2(RC_EDX, RC_EAX); // make sure src2 is on b side | 2295 | gv2(S, RC_EDX, RC_EAX); // make sure src2 is on b side |
| 2296 | else | 2296 | else |
| 2297 | gv2(RC_FLOAT, RC_FLOAT); // make sure src2 is on b side | 2297 | gv2(S, RC_FLOAT, RC_FLOAT); // make sure src2 is on b side |
| 2298 | 2298 | ||
| 2299 | ft = vtop->type.t; | 2299 | ft = S->tccgen_vtop->type.t; |
| 2300 | fc = vtop->c.i; | 2300 | fc = S->tccgen_vtop->c.i; |
| 2301 | r = vtop->r; | 2301 | r = S->tccgen_vtop->r; |
| 2302 | fr = vtop[-1].r; | 2302 | fr = S->tccgen_vtop[-1].r; |
| 2303 | 2303 | ||
| 2304 | 2304 | ||
| 2305 | if ((ft & VT_BTYPE) == VT_LDOUBLE) | 2305 | if ((ft & VT_BTYPE) == VT_LDOUBLE) |
| 2306 | tcc_error("long doubles not supported"); | 2306 | tcc_error(S, "long doubles not supported"); |
| 2307 | 2307 | ||
| 2308 | if (op >= TOK_ULT && op <= TOK_GT) { | 2308 | if (op >= TOK_ULT && op <= TOK_GT) { |
| 2309 | 2309 | ||
| 2310 | r = vtop[-1].r; | 2310 | r = S->tccgen_vtop[-1].r; |
| 2311 | fr = vtop[0].r; | 2311 | fr = S->tccgen_vtop[0].r; |
| 2312 | 2312 | ||
| 2313 | C67_compare_reg = C67_B2; | 2313 | C67_compare_reg = C67_B2; |
| 2314 | 2314 | ||
| 2315 | if (op == TOK_LT) { | 2315 | if (op == TOK_LT) { |
| 2316 | if ((ft & VT_BTYPE) == VT_DOUBLE) | 2316 | if ((ft & VT_BTYPE) == VT_DOUBLE) |
| 2317 | C67_CMPLTDP(r, fr, C67_B2); | 2317 | C67_CMPLTDP(S, r, fr, C67_B2); |
| 2318 | else | 2318 | else |
| 2319 | C67_CMPLTSP(r, fr, C67_B2); | 2319 | C67_CMPLTSP(S, r, fr, C67_B2); |
| 2320 | 2320 | ||
| 2321 | C67_invert_test = FALSE; | 2321 | C67_invert_test = FALSE; |
| 2322 | } else if (op == TOK_GE) { | 2322 | } else if (op == TOK_GE) { |
| 2323 | if ((ft & VT_BTYPE) == VT_DOUBLE) | 2323 | if ((ft & VT_BTYPE) == VT_DOUBLE) |
| 2324 | C67_CMPLTDP(r, fr, C67_B2); | 2324 | C67_CMPLTDP(S, r, fr, C67_B2); |
| 2325 | else | 2325 | else |
| 2326 | C67_CMPLTSP(r, fr, C67_B2); | 2326 | C67_CMPLTSP(S, r, fr, C67_B2); |
| 2327 | 2327 | ||
| 2328 | C67_invert_test = TRUE; | 2328 | C67_invert_test = TRUE; |
| 2329 | } else if (op == TOK_GT) { | 2329 | } else if (op == TOK_GT) { |
| 2330 | if ((ft & VT_BTYPE) == VT_DOUBLE) | 2330 | if ((ft & VT_BTYPE) == VT_DOUBLE) |
| 2331 | C67_CMPGTDP(r, fr, C67_B2); | 2331 | C67_CMPGTDP(S, r, fr, C67_B2); |
| 2332 | else | 2332 | else |
| 2333 | C67_CMPGTSP(r, fr, C67_B2); | 2333 | C67_CMPGTSP(S, r, fr, C67_B2); |
| 2334 | 2334 | ||
| 2335 | C67_invert_test = FALSE; | 2335 | C67_invert_test = FALSE; |
| 2336 | } else if (op == TOK_LE) { | 2336 | } else if (op == TOK_LE) { |
| 2337 | if ((ft & VT_BTYPE) == VT_DOUBLE) | 2337 | if ((ft & VT_BTYPE) == VT_DOUBLE) |
| 2338 | C67_CMPGTDP(r, fr, C67_B2); | 2338 | C67_CMPGTDP(S, r, fr, C67_B2); |
| 2339 | else | 2339 | else |
| 2340 | C67_CMPGTSP(r, fr, C67_B2); | 2340 | C67_CMPGTSP(S, r, fr, C67_B2); |
| 2341 | 2341 | ||
| 2342 | C67_invert_test = TRUE; | 2342 | C67_invert_test = TRUE; |
| 2343 | } else if (op == TOK_EQ) { | 2343 | } else if (op == TOK_EQ) { |
| 2344 | if ((ft & VT_BTYPE) == VT_DOUBLE) | 2344 | if ((ft & VT_BTYPE) == VT_DOUBLE) |
| 2345 | C67_CMPEQDP(r, fr, C67_B2); | 2345 | C67_CMPEQDP(S, r, fr, C67_B2); |
| 2346 | else | 2346 | else |
| 2347 | C67_CMPEQSP(r, fr, C67_B2); | 2347 | C67_CMPEQSP(S, r, fr, C67_B2); |
| 2348 | 2348 | ||
| 2349 | C67_invert_test = FALSE; | 2349 | C67_invert_test = FALSE; |
| 2350 | } else if (op == TOK_NE) { | 2350 | } else if (op == TOK_NE) { |
| 2351 | if ((ft & VT_BTYPE) == VT_DOUBLE) | 2351 | if ((ft & VT_BTYPE) == VT_DOUBLE) |
| 2352 | C67_CMPEQDP(r, fr, C67_B2); | 2352 | C67_CMPEQDP(S, r, fr, C67_B2); |
| 2353 | else | 2353 | else |
| 2354 | C67_CMPEQSP(r, fr, C67_B2); | 2354 | C67_CMPEQSP(S, r, fr, C67_B2); |
| 2355 | 2355 | ||
| 2356 | C67_invert_test = TRUE; | 2356 | C67_invert_test = TRUE; |
| 2357 | } else { | 2357 | } else { |
| 2358 | ALWAYS_ASSERT(FALSE); | 2358 | ALWAYS_ASSERT(FALSE); |
| 2359 | } | 2359 | } |
| 2360 | vset_VT_CMP(0x80); | 2360 | vset_VT_CMP(S, 0x80); |
| 2361 | } else { | 2361 | } else { |
| 2362 | if (op == '+') { | 2362 | if (op == '+') { |
| 2363 | if ((ft & VT_BTYPE) == VT_DOUBLE) { | 2363 | if ((ft & VT_BTYPE) == VT_DOUBLE) { |
| 2364 | C67_ADDDP(r, fr); // ADD fr,r,fr | 2364 | C67_ADDDP(S, r, fr); // ADD fr,r,fr |
| 2365 | C67_NOP(6); | 2365 | C67_NOP(S, 6); |
| 2366 | } else { | 2366 | } else { |
| 2367 | C67_ADDSP(r, fr); // ADD fr,r,fr | 2367 | C67_ADDSP(S, r, fr); // ADD fr,r,fr |
| 2368 | C67_NOP(3); | 2368 | C67_NOP(S, 3); |
| 2369 | } | 2369 | } |
| 2370 | vtop--; | 2370 | S->tccgen_vtop--; |
| 2371 | } else if (op == '-') { | 2371 | } else if (op == '-') { |
| 2372 | if ((ft & VT_BTYPE) == VT_DOUBLE) { | 2372 | if ((ft & VT_BTYPE) == VT_DOUBLE) { |
| 2373 | C67_SUBDP(r, fr); // SUB fr,r,fr | 2373 | C67_SUBDP(S, r, fr); // SUB fr,r,fr |
| 2374 | C67_NOP(6); | 2374 | C67_NOP(S, 6); |
| 2375 | } else { | 2375 | } else { |
| 2376 | C67_SUBSP(r, fr); // SUB fr,r,fr | 2376 | C67_SUBSP(S, r, fr); // SUB fr,r,fr |
| 2377 | C67_NOP(3); | 2377 | C67_NOP(S, 3); |
| 2378 | } | 2378 | } |
| 2379 | vtop--; | 2379 | S->tccgen_vtop--; |
| 2380 | } else if (op == '*') { | 2380 | } else if (op == '*') { |
| 2381 | if ((ft & VT_BTYPE) == VT_DOUBLE) { | 2381 | if ((ft & VT_BTYPE) == VT_DOUBLE) { |
| 2382 | C67_MPYDP(r, fr); // MPY fr,r,fr | 2382 | C67_MPYDP(S, r, fr); // MPY fr,r,fr |
| 2383 | C67_NOP(9); | 2383 | C67_NOP(S, 9); |
| 2384 | } else { | 2384 | } else { |
| 2385 | C67_MPYSP(r, fr); // MPY fr,r,fr | 2385 | C67_MPYSP(S, r, fr); // MPY fr,r,fr |
| 2386 | C67_NOP(3); | 2386 | C67_NOP(S, 3); |
| 2387 | } | 2387 | } |
| 2388 | vtop--; | 2388 | S->tccgen_vtop--; |
| 2389 | } else if (op == '/') { | 2389 | } else if (op == '/') { |
| 2390 | if ((ft & VT_BTYPE) == VT_DOUBLE) { | 2390 | if ((ft & VT_BTYPE) == VT_DOUBLE) { |
| 2391 | // must call intrinsic DP floating point divide | 2391 | // must call intrinsic DP floating point divide |
| 2392 | vswap(); | 2392 | vswap(S); |
| 2393 | /* call generic idiv function */ | 2393 | /* call generic idiv function */ |
| 2394 | vpush_helper_func(TOK__divd); | 2394 | vpush_helper_func(S, TOK__divd); |
| 2395 | vrott(3); | 2395 | vrott(S, 3); |
| 2396 | gfunc_call(2); | 2396 | gfunc_call(S, 2); |
| 2397 | vpushi(0); | 2397 | vpushi(S, 0); |
| 2398 | vtop->r = REG_FRET; | 2398 | S->tccgen_vtop->r = REG_FRET; |
| 2399 | vtop->r2 = REG_IRE2; | 2399 | S->tccgen_vtop->r2 = REG_IRE2; |
| 2400 | 2400 | ||
| 2401 | } else { | 2401 | } else { |
| 2402 | // must call intrinsic SP floating point divide | 2402 | // must call intrinsic SP floating point divide |
| 2403 | vswap(); | 2403 | vswap(S); |
| 2404 | /* call generic idiv function */ | 2404 | /* call generic idiv function */ |
| 2405 | vpush_helper_func(TOK__divf); | 2405 | vpush_helper_func(S, TOK__divf); |
| 2406 | vrott(3); | 2406 | vrott(S, 3); |
| 2407 | gfunc_call(2); | 2407 | gfunc_call(S, 2); |
| 2408 | vpushi(0); | 2408 | vpushi(S, 0); |
| 2409 | vtop->r = REG_FRET; | 2409 | S->tccgen_vtop->r = REG_FRET; |
| 2410 | vtop->r2 = VT_CONST; | 2410 | S->tccgen_vtop->r2 = VT_CONST; |
| 2411 | } | 2411 | } |
| 2412 | } else | 2412 | } else |
| 2413 | ALWAYS_ASSERT(FALSE); | 2413 | ALWAYS_ASSERT(FALSE); |
| @@ -2419,122 +2419,122 @@ void gen_opf(int op) · 5 unmodified lines | |||
| 2419 | 2419 | ||
| 2420 | /* convert integers to fp 't' type. Must handle 'int', 'unsigned int' | 2420 | /* convert integers to fp 't' type. Must handle 'int', 'unsigned int' |
| 2421 | and 'long long' cases. */ | 2421 | and 'long long' cases. */ |
| 2422 | void gen_cvt_itof(int t) | 2422 | void gen_cvt_itof(TCCState* S, int t) |
| 2423 | { | 2423 | { |
| 2424 | int r; | 2424 | int r; |
| 2425 | 2425 | ||
| 2426 | gv(RC_INT); | 2426 | gv(S, RC_INT); |
| 2427 | r = vtop->r; | 2427 | r = S->tccgen_vtop->r; |
| 2428 | 2428 | ||
| 2429 | if ((t & VT_BTYPE) == VT_DOUBLE) { | 2429 | if ((t & VT_BTYPE) == VT_DOUBLE) { |
| 2430 | if (t & VT_UNSIGNED) | 2430 | if (t & VT_UNSIGNED) |
| 2431 | C67_INTDPU(r, r); | 2431 | C67_INTDPU(S, r, r); |
| 2432 | else | 2432 | else |
| 2433 | C67_INTDP(r, r); | 2433 | C67_INTDP(S, r, r); |
| 2434 | 2434 | ||
| 2435 | C67_NOP(4); | 2435 | C67_NOP(S, 4); |
| 2436 | vtop->type.t = VT_DOUBLE; | 2436 | S->tccgen_vtop->type.t = VT_DOUBLE; |
| 2437 | } else { | 2437 | } else { |
| 2438 | if (t & VT_UNSIGNED) | 2438 | if (t & VT_UNSIGNED) |
| 2439 | C67_INTSPU(r, r); | 2439 | C67_INTSPU(S, r, r); |
| 2440 | else | 2440 | else |
| 2441 | C67_INTSP(r, r); | 2441 | C67_INTSP(S, r, r); |
| 2442 | C67_NOP(3); | 2442 | C67_NOP(S, 3); |
| 2443 | vtop->type.t = VT_FLOAT; | 2443 | S->tccgen_vtop->type.t = VT_FLOAT; |
| 2444 | } | 2444 | } |
| 2445 | 2445 | ||
| 2446 | } | 2446 | } |
| 2447 | 2447 | ||
| 2448 | /* convert fp to int 't' type */ | 2448 | /* convert fp to int 't' type */ |
| 2449 | /* XXX: handle long long case */ | 2449 | /* XXX: handle long long case */ |
| 2450 | void gen_cvt_ftoi(int t) | 2450 | void gen_cvt_ftoi(TCCState* S, int t) |
| 2451 | { | 2451 | { |
| 2452 | int r; | 2452 | int r; |
| 2453 | 2453 | ||
| 2454 | gv(RC_FLOAT); | 2454 | gv(S, RC_FLOAT); |
| 2455 | r = vtop->r; | 2455 | r = S->tccgen_vtop->r; |
| 2456 | 2456 | ||
| 2457 | if (t != VT_INT) | 2457 | if (t != VT_INT) |
| 2458 | tcc_error("long long not supported"); | 2458 | tcc_error(S, "long long not supported"); |
| 2459 | else { | 2459 | else { |
| 2460 | if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) { | 2460 | if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_DOUBLE) { |
| 2461 | C67_DPTRUNC(r, r); | 2461 | C67_DPTRUNC(S, r, r); |
| 2462 | C67_NOP(3); | 2462 | C67_NOP(S, 3); |
| 2463 | } else { | 2463 | } else { |
| 2464 | C67_SPTRUNC(r, r); | 2464 | C67_SPTRUNC(S, r, r); |
| 2465 | C67_NOP(3); | 2465 | C67_NOP(S, 3); |
| 2466 | } | 2466 | } |
| 2467 | 2467 | ||
| 2468 | vtop->type.t = VT_INT; | 2468 | S->tccgen_vtop->type.t = VT_INT; |
| 2469 | 2469 | ||
| 2470 | } | 2470 | } |
| 2471 | } | 2471 | } |
| 2472 | 2472 | ||
| 2473 | /* convert from one floating point type to another */ | 2473 | /* convert from one floating point type to another */ |
| 2474 | void gen_cvt_ftof(int t) | 2474 | void gen_cvt_ftof(TCCState* S, int t) |
| 2475 | { | 2475 | { |
| 2476 | int r, r2; | 2476 | int r, r2; |
| 2477 | 2477 | ||
| 2478 | if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE && | 2478 | if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_DOUBLE && |
| 2479 | (t & VT_BTYPE) == VT_FLOAT) { | 2479 | (t & VT_BTYPE) == VT_FLOAT) { |
| 2480 | // convert double to float | 2480 | // convert double to float |
| 2481 | 2481 | ||
| 2482 | gv(RC_FLOAT); // get it in a register pair | 2482 | gv(S, RC_FLOAT); // get it in a register pair |
| 2483 | 2483 | ||
| 2484 | r = vtop->r; | 2484 | r = S->tccgen_vtop->r; |
| 2485 | 2485 | ||
| 2486 | C67_DPSP(r, r); // convert it to SP same register | 2486 | C67_DPSP(S, r, r); // convert it to SP same register |
| 2487 | C67_NOP(3); | 2487 | C67_NOP(S, 3); |
| 2488 | 2488 | ||
| 2489 | vtop->type.t = VT_FLOAT; | 2489 | S->tccgen_vtop->type.t = VT_FLOAT; |
| 2490 | vtop->r2 = VT_CONST; // set this as unused | 2490 | S->tccgen_vtop->r2 = VT_CONST; // set this as unused |
| 2491 | } else if ((vtop->type.t & VT_BTYPE) == VT_FLOAT && | 2491 | } else if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_FLOAT && |
| 2492 | (t & VT_BTYPE) == VT_DOUBLE) { | 2492 | (t & VT_BTYPE) == VT_DOUBLE) { |
| 2493 | // convert float to double | 2493 | // convert float to double |
| 2494 | 2494 | ||
| 2495 | gv(RC_FLOAT); // get it in a register | 2495 | gv(S, RC_FLOAT); // get it in a register |
| 2496 | 2496 | ||
| 2497 | r = vtop->r; | 2497 | r = S->tccgen_vtop->r; |
| 2498 | 2498 | ||
| 2499 | if (r == TREG_EAX) { // make sure the paired reg is avail | 2499 | if (r == TREG_EAX) { // make sure the paired reg is avail |
| 2500 | r2 = get_reg(RC_ECX); | 2500 | r2 = get_reg(S, RC_ECX); |
| 2501 | } else if (r == TREG_EDX) { | 2501 | } else if (r == TREG_EDX) { |
| 2502 | r2 = get_reg(RC_ST0); | 2502 | r2 = get_reg(S, RC_ST0); |
| 2503 | } else { | 2503 | } else { |
| 2504 | ALWAYS_ASSERT(FALSE); | 2504 | ALWAYS_ASSERT(FALSE); |
| 2505 | r2 = 0; /* avoid warning */ | 2505 | r2 = 0; /* avoid warning */ |
| 2506 | } | 2506 | } |
| 2507 | 2507 | ||
| 2508 | C67_SPDP(r, r); // convert it to DP same register | 2508 | C67_SPDP(S, r, r); // convert it to DP same register |
| 2509 | C67_NOP(1); | 2509 | C67_NOP(S, 1); |
| 2510 | 2510 | ||
| 2511 | vtop->type.t = VT_DOUBLE; | 2511 | S->tccgen_vtop->type.t = VT_DOUBLE; |
| 2512 | vtop->r2 = r2; // set this as unused | 2512 | S->tccgen_vtop->r2 = r2; // set this as unused |
| 2513 | } else { | 2513 | } else { |
| 2514 | ALWAYS_ASSERT(FALSE); | 2514 | ALWAYS_ASSERT(FALSE); |
| 2515 | } | 2515 | } |
| 2516 | } | 2516 | } |
| 2517 | 2517 | ||
| 2518 | /* computed goto support */ | 2518 | /* computed goto support */ |
| 2519 | void ggoto(void) | 2519 | void ggoto(TCCState* S) |
| 2520 | { | 2520 | { |
| 2521 | gcall_or_jmp(1); | 2521 | gcall_or_jmp(S, 1); |
| 2522 | vtop--; | 2522 | S->tccgen_vtop--; |
| 2523 | } | 2523 | } |
| 2524 | 2524 | ||
| 2525 | /* Save the stack pointer onto the stack and return the location of its address */ | 2525 | /* Save the stack pointer onto the stack and return the location of its address */ |
| 2526 | ST_FUNC void gen_vla_sp_save(int addr) { | 2526 | ST_FUNC void gen_vla_sp_save(TCCState* S, int addr) { |
| 2527 | tcc_error("variable length arrays unsupported for this target"); | 2527 | tcc_error(S, "variable length arrays unsupported for this target"); |
| 2528 | } | 2528 | } |
| 2529 | 2529 | ||
| 2530 | /* Restore the SP from a location on the stack */ | 2530 | /* Restore the SP from a location on the stack */ |
| 2531 | ST_FUNC void gen_vla_sp_restore(int addr) { | 2531 | ST_FUNC void gen_vla_sp_restore(TCCState* S, int addr) { |
| 2532 | tcc_error("variable length arrays unsupported for this target"); | 2532 | tcc_error(S, "variable length arrays unsupported for this target"); |
| 2533 | } | 2533 | } |
| 2534 | 2534 | ||
| 2535 | /* Subtract from the stack pointer, and push the resulting value onto the stack */ | 2535 | /* Subtract from the stack pointer, and push the resulting value onto the stack */ |
| 2536 | ST_FUNC void gen_vla_alloc(CType *type, int align) { | 2536 | ST_FUNC void gen_vla_alloc(TCCState* S, CType *type, int align) { |
| 2537 | tcc_error("variable length arrays unsupported for this target"); | 2537 | tcc_error(S, "variable length arrays unsupported for this target"); |
| 2538 | } | 2538 | } |
| 2539 | 2539 | ||
| 2540 | /* end of C67 code generator */ | 2540 | /* end of C67 code generator */ |
| @@ -65,23 +65,23 @@ int gotplt_entry_type (int reloc_type) · 64 unmodified lines | |||
| 65 | return -1; | 65 | return -1; |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr) | 68 | ST_FUNC unsigned create_plt_entry(TCCState *S, unsigned got_offset, struct sym_attr *attr) |
| 69 | { | 69 | { |
| 70 | tcc_error("C67 got not implemented"); | 70 | tcc_error(S, "C67 got not implemented"); |
| 71 | return 0; | 71 | return 0; |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | /* relocate the PLT: compute addresses and offsets in the PLT now that final | 74 | /* relocate the PLT: compute addresses and offsets in the PLT now that final |
| 75 | address for PLT and GOT are known (see fill_program_header) */ | 75 | address for PLT and GOT are known (see fill_program_header) */ |
| 76 | ST_FUNC void relocate_plt(TCCState *s1) | 76 | ST_FUNC void relocate_plt(TCCState *S) |
| 77 | { | 77 | { |
| 78 | uint8_t *p, *p_end; | 78 | uint8_t *p, *p_end; |
| 79 | 79 | ||
| 80 | if (!s1->plt) | 80 | if (!S->plt) |
| 81 | return; | 81 | return; |
| 82 | 82 | ||
| 83 | p = s1->plt->data; | 83 | p = S->plt->data; |
| 84 | p_end = p + s1->plt->data_offset; | 84 | p_end = p + S->plt->data_offset; |
| 85 | 85 | ||
| 86 | if (p < p_end) { | 86 | if (p < p_end) { |
| 87 | /* XXX: TODO */ | 87 | /* XXX: TODO */ |
| @@ -91,7 +91,7 @@ ST_FUNC void relocate_plt(TCCState *s1) · 3 unmodified lines | |||
| 91 | } | 91 | } |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val) | 94 | void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val) |
| 95 | { | 95 | { |
| 96 | switch(type) { | 96 | switch(type) { |
| 97 | case R_C60_32: | 97 | case R_C60_32: |
| @@ -253,10 +253,10 @@ static const uint16_t op0_codes[] = { · 252 unmodified lines | |||
| 253 | #endif | 253 | #endif |
| 254 | }; | 254 | }; |
| 255 | 255 | ||
| 256 | static inline int get_reg_shift(TCCState *s1) | 256 | static inline int get_reg_shift(TCCState *S) |
| 257 | { | 257 | { |
| 258 | int shift, v; | 258 | int shift, v; |
| 259 | v = asm_int_expr(s1); | 259 | v = asm_int_expr(S); |
| 260 | switch(v) { | 260 | switch(v) { |
| 261 | case 1: | 261 | case 1: |
| 262 | shift = 0; | 262 | shift = 0; |
| @@ -271,7 +271,7 @@ static inline int get_reg_shift(TCCState *s1) · 8 unmodified lines | |||
| 271 | shift = 3; | 271 | shift = 3; |
| 272 | break; | 272 | break; |
| 273 | default: | 273 | default: |
| 274 | expect("1, 2, 4 or 8 constant"); | 274 | expect(S, "1, 2, 4 or 8 constant"); |
| 275 | shift = 0; | 275 | shift = 0; |
| 276 | break; | 276 | break; |
| 277 | } | 277 | } |
| @@ -279,11 +279,11 @@ static inline int get_reg_shift(TCCState *s1) · 1 unmodified line | |||
| 279 | } | 279 | } |
| 280 | 280 | ||
| 281 | #ifdef TCC_TARGET_X86_64 | 281 | #ifdef TCC_TARGET_X86_64 |
| 282 | static int asm_parse_numeric_reg(int t, unsigned int *type) | 282 | static int asm_parse_numeric_reg(TCCState *S, int t, unsigned int *type) |
| 283 | { | 283 | { |
| 284 | int reg = -1; | 284 | int reg = -1; |
| 285 | if (t >= TOK_IDENT && t < tok_ident) { | 285 | if (t >= TOK_IDENT && t < S->tccpp_tok_ident) { |
| 286 | const char *s = table_ident[t - TOK_IDENT]->str; | 286 | const char *s = S->tccpp_table_ident[t - TOK_IDENT]->str; |
| 287 | char c; | 287 | char c; |
| 288 | *type = OP_REG64; | 288 | *type = OP_REG64; |
| 289 | if (*s == 'c') { | 289 | if (*s == 'c') { |
| @@ -318,51 +318,51 @@ static int asm_parse_numeric_reg(int t, unsigned int *type) · 28 unmodified lines | |||
| 318 | } | 318 | } |
| 319 | #endif | 319 | #endif |
| 320 | 320 | ||
| 321 | static int asm_parse_reg(unsigned int *type) | 321 | static int asm_parse_reg(TCCState* S, unsigned int *type) |
| 322 | { | 322 | { |
| 323 | int reg = 0; | 323 | int reg = 0; |
| 324 | *type = 0; | 324 | *type = 0; |
| 325 | if (tok != '%') | 325 | if (S->tccpp_tok != '%') |
| 326 | goto error_32; | 326 | goto error_32; |
| 327 | next(); | 327 | next(S); |
| 328 | if (tok >= TOK_ASM_eax && tok <= TOK_ASM_edi) { | 328 | if (S->tccpp_tok >= TOK_ASM_eax && S->tccpp_tok <= TOK_ASM_edi) { |
| 329 | reg = tok - TOK_ASM_eax; | 329 | reg = S->tccpp_tok - TOK_ASM_eax; |
| 330 | *type = OP_REG32; | 330 | *type = OP_REG32; |
| 331 | #ifdef TCC_TARGET_X86_64 | 331 | #ifdef TCC_TARGET_X86_64 |
| 332 | } else if (tok >= TOK_ASM_rax && tok <= TOK_ASM_rdi) { | 332 | } else if (S->tccpp_tok >= TOK_ASM_rax && S->tccpp_tok <= TOK_ASM_rdi) { |
| 333 | reg = tok - TOK_ASM_rax; | 333 | reg = S->tccpp_tok - TOK_ASM_rax; |
| 334 | *type = OP_REG64; | 334 | *type = OP_REG64; |
| 335 | } else if (tok == TOK_ASM_rip) { | 335 | } else if (S->tccpp_tok == TOK_ASM_rip) { |
| 336 | reg = -2; /* Probably should use different escape code. */ | 336 | reg = -2; /* Probably should use different escape code. */ |
| 337 | *type = OP_REG64; | 337 | *type = OP_REG64; |
| 338 | } else if ((reg = asm_parse_numeric_reg(tok, type)) >= 0 | 338 | } else if ((reg = asm_parse_numeric_reg(S, S->tccpp_tok, type)) >= 0 |
| 339 | && (*type == OP_REG32 || *type == OP_REG64)) { | 339 | && (*type == OP_REG32 || *type == OP_REG64)) { |
| 340 | ; | 340 | ; |
| 341 | #endif | 341 | #endif |
| 342 | } else { | 342 | } else { |
| 343 | error_32: | 343 | error_32: |
| 344 | expect("register"); | 344 | expect(S, "register"); |
| 345 | } | 345 | } |
| 346 | next(); | 346 | next(S); |
| 347 | return reg; | 347 | return reg; |
| 348 | } | 348 | } |
| 349 | 349 | ||
| 350 | static void parse_operand(TCCState *s1, Operand *op) | 350 | static void parse_operand(TCCState *S, Operand *op) |
| 351 | { | 351 | { |
| 352 | ExprValue e; | 352 | ExprValue e; |
| 353 | int reg, indir; | 353 | int reg, indir; |
| 354 | const char *p; | 354 | const char *p; |
| 355 | 355 | ||
| 356 | indir = 0; | 356 | indir = 0; |
| 357 | if (tok == '*') { | 357 | if (S->tccpp_tok == '*') { |
| 358 | next(); | 358 | next(S); |
| 359 | indir = OP_INDIR; | 359 | indir = OP_INDIR; |
| 360 | } | 360 | } |
| 361 | 361 | ||
| 362 | if (tok == '%') { | 362 | if (S->tccpp_tok == '%') { |
| 363 | next(); | 363 | next(S); |
| 364 | if (tok >= TOK_ASM_al && tok <= TOK_ASM_db7) { | 364 | if (S->tccpp_tok >= TOK_ASM_al && S->tccpp_tok <= TOK_ASM_db7) { |
| 365 | reg = tok - TOK_ASM_al; | 365 | reg = S->tccpp_tok - TOK_ASM_al; |
| 366 | op->type = 1 << (reg >> 3); /* WARNING: do not change constant order */ | 366 | op->type = 1 << (reg >> 3); /* WARNING: do not change constant order */ |
| 367 | op->reg = reg & 7; | 367 | op->reg = reg & 7; |
| 368 | if ((op->type & OP_REG) && op->reg == TREG_XAX) | 368 | if ((op->type & OP_REG) && op->reg == TREG_XAX) |
| @@ -371,48 +371,48 @@ static void parse_operand(TCCState *s1, Operand *op) · 2 unmodified lines | |||
| 371 | op->type |= OP_CL; | 371 | op->type |= OP_CL; |
| 372 | else if (op->type == OP_REG16 && op->reg == TREG_XDX) | 372 | else if (op->type == OP_REG16 && op->reg == TREG_XDX) |
| 373 | op->type |= OP_DX; | 373 | op->type |= OP_DX; |
| 374 | } else if (tok >= TOK_ASM_dr0 && tok <= TOK_ASM_dr7) { | 374 | } else if (S->tccpp_tok >= TOK_ASM_dr0 && S->tccpp_tok <= TOK_ASM_dr7) { |
| 375 | op->type = OP_DB; | 375 | op->type = OP_DB; |
| 376 | op->reg = tok - TOK_ASM_dr0; | 376 | op->reg = S->tccpp_tok - TOK_ASM_dr0; |
| 377 | } else if (tok >= TOK_ASM_es && tok <= TOK_ASM_gs) { | 377 | } else if (S->tccpp_tok >= TOK_ASM_es && S->tccpp_tok <= TOK_ASM_gs) { |
| 378 | op->type = OP_SEG; | 378 | op->type = OP_SEG; |
| 379 | op->reg = tok - TOK_ASM_es; | 379 | op->reg = S->tccpp_tok - TOK_ASM_es; |
| 380 | } else if (tok == TOK_ASM_st) { | 380 | } else if (S->tccpp_tok == TOK_ASM_st) { |
| 381 | op->type = OP_ST; | 381 | op->type = OP_ST; |
| 382 | op->reg = 0; | 382 | op->reg = 0; |
| 383 | next(); | 383 | next(S); |
| 384 | if (tok == '(') { | 384 | if (S->tccpp_tok == '(') { |
| 385 | next(); | 385 | next(S); |
| 386 | if (tok != TOK_PPNUM) | 386 | if (S->tccpp_tok != TOK_PPNUM) |
| 387 | goto reg_error; | 387 | goto reg_error; |
| 388 | p = tokc.str.data; | 388 | p = S->tccpp_tokc.str.data; |
| 389 | reg = p[0] - '0'; | 389 | reg = p[0] - '0'; |
| 390 | if ((unsigned)reg >= 8 || p[1] != '\0') | 390 | if ((unsigned)reg >= 8 || p[1] != '\0') |
| 391 | goto reg_error; | 391 | goto reg_error; |
| 392 | op->reg = reg; | 392 | op->reg = reg; |
| 393 | next(); | 393 | next(S); |
| 394 | skip(')'); | 394 | skip(S, ')'); |
| 395 | } | 395 | } |
| 396 | if (op->reg == 0) | 396 | if (op->reg == 0) |
| 397 | op->type |= OP_ST0; | 397 | op->type |= OP_ST0; |
| 398 | goto no_skip; | 398 | goto no_skip; |
| 399 | #ifdef TCC_TARGET_X86_64 | 399 | #ifdef TCC_TARGET_X86_64 |
| 400 | } else if (tok >= TOK_ASM_spl && tok <= TOK_ASM_dil) { | 400 | } else if (S->tccpp_tok >= TOK_ASM_spl && S->tccpp_tok <= TOK_ASM_dil) { |
| 401 | op->type = OP_REG8 | OP_REG8_LOW; | 401 | op->type = OP_REG8 | OP_REG8_LOW; |
| 402 | op->reg = 4 + tok - TOK_ASM_spl; | 402 | op->reg = 4 + S->tccpp_tok - TOK_ASM_spl; |
| 403 | } else if ((op->reg = asm_parse_numeric_reg(tok, &op->type)) >= 0) { | 403 | } else if ((op->reg = asm_parse_numeric_reg(S, S->tccpp_tok, &op->type)) >= 0) { |
| 404 | ; | 404 | ; |
| 405 | #endif | 405 | #endif |
| 406 | } else { | 406 | } else { |
| 407 | reg_error: | 407 | reg_error: |
| 408 | tcc_error("unknown register %%%s", get_tok_str(tok, &tokc)); | 408 | tcc_error(S, "unknown register %%%s", get_tok_str(S, S->tccpp_tok, &S->tccpp_tokc)); |
| 409 | } | 409 | } |
| 410 | next(); | 410 | next(S); |
| 411 | no_skip: ; | 411 | no_skip: ; |
| 412 | } else if (tok == '$') { | 412 | } else if (S->tccpp_tok == '$') { |
| 413 | /* constant value */ | 413 | /* constant value */ |
| 414 | next(); | 414 | next(S); |
| 415 | asm_expr(s1, &e); | 415 | asm_expr(S, &e); |
| 416 | op->type = OP_IM32; | 416 | op->type = OP_IM32; |
| 417 | op->e = e; | 417 | op->e = e; |
| 418 | if (!op->e.sym) { | 418 | if (!op->e.sym) { |
| @@ -433,45 +433,45 @@ static void parse_operand(TCCState *s1, Operand *op) · 14 unmodified lines | |||
| 433 | op->reg = -1; | 433 | op->reg = -1; |
| 434 | op->reg2 = -1; | 434 | op->reg2 = -1; |
| 435 | op->shift = 0; | 435 | op->shift = 0; |
| 436 | if (tok != '(') { | 436 | if (S->tccpp_tok != '(') { |
| 437 | asm_expr(s1, &e); | 437 | asm_expr(S, &e); |
| 438 | op->e = e; | 438 | op->e = e; |
| 439 | } else { | 439 | } else { |
| 440 | next(); | 440 | next(S); |
| 441 | if (tok == '%') { | 441 | if (S->tccpp_tok == '%') { |
| 442 | unget_tok('('); | 442 | unget_tok(S, '('); |
| 443 | op->e.v = 0; | 443 | op->e.v = 0; |
| 444 | op->e.sym = NULL; | 444 | op->e.sym = NULL; |
| 445 | } else { | 445 | } else { |
| 446 | /* bracketed offset expression */ | 446 | /* bracketed offset expression */ |
| 447 | asm_expr(s1, &e); | 447 | asm_expr(S, &e); |
| 448 | if (tok != ')') | 448 | if (S->tccpp_tok != ')') |
| 449 | expect(")"); | 449 | expect(S, ")"); |
| 450 | next(); | 450 | next(S); |
| 451 | op->e.v = e.v; | 451 | op->e.v = e.v; |
| 452 | op->e.sym = e.sym; | 452 | op->e.sym = e.sym; |
| 453 | } | 453 | } |
| 454 | op->e.pcrel = 0; | 454 | op->e.pcrel = 0; |
| 455 | } | 455 | } |
| 456 | if (tok == '(') { | 456 | if (S->tccpp_tok == '(') { |
| 457 | unsigned int type = 0; | 457 | unsigned int type = 0; |
| 458 | next(); | 458 | next(S); |
| 459 | if (tok != ',') { | 459 | if (S->tccpp_tok != ',') { |
| 460 | op->reg = asm_parse_reg(&type); | 460 | op->reg = asm_parse_reg(S, &type); |
| 461 | } | 461 | } |
| 462 | if (tok == ',') { | 462 | if (S->tccpp_tok == ',') { |
| 463 | next(); | 463 | next(S); |
| 464 | if (tok != ',') { | 464 | if (S->tccpp_tok != ',') { |
| 465 | op->reg2 = asm_parse_reg(&type); | 465 | op->reg2 = asm_parse_reg(S, &type); |
| 466 | } | 466 | } |
| 467 | if (tok == ',') { | 467 | if (S->tccpp_tok == ',') { |
| 468 | next(); | 468 | next(S); |
| 469 | op->shift = get_reg_shift(s1); | 469 | op->shift = get_reg_shift(S); |
| 470 | } | 470 | } |
| 471 | } | 471 | } |
| 472 | if (type & OP_REG32) | 472 | if (type & OP_REG32) |
| 473 | op->type |= OP_EA32; | 473 | op->type |= OP_EA32; |
| 474 | skip(')'); | 474 | skip(S, ')'); |
| 475 | } | 475 | } |
| 476 | if (op->reg == -1 && op->reg2 == -1) | 476 | if (op->reg == -1 && op->reg2 == -1) |
| 477 | op->type |= OP_ADDR; | 477 | op->type |= OP_ADDR; |
| @@ -480,65 +480,65 @@ static void parse_operand(TCCState *s1, Operand *op) · 2 unmodified lines | |||
| 480 | } | 480 | } |
| 481 | 481 | ||
| 482 | /* XXX: unify with C code output ? */ | 482 | /* XXX: unify with C code output ? */ |
| 483 | ST_FUNC void gen_expr32(ExprValue *pe) | 483 | ST_FUNC void gen_expr32(TCCState* S, ExprValue *pe) |
| 484 | { | 484 | { |
| 485 | if (pe->pcrel) | 485 | if (pe->pcrel) |
| 486 | /* If PC-relative, always set VT_SYM, even without symbol, | 486 | /* If PC-relative, always set VT_SYM, even without symbol, |
| 487 | so as to force a relocation to be emitted. */ | 487 | so as to force a relocation to be emitted. */ |
| 488 | gen_addrpc32(VT_SYM, pe->sym, pe->v); | 488 | gen_addrpc32(S, VT_SYM, pe->sym, pe->v); |
| 489 | else | 489 | else |
| 490 | gen_addr32(pe->sym ? VT_SYM : 0, pe->sym, pe->v); | 490 | gen_addr32(S, pe->sym ? VT_SYM : 0, pe->sym, pe->v); |
| 491 | } | 491 | } |
| 492 | 492 | ||
| 493 | #ifdef TCC_TARGET_X86_64 | 493 | #ifdef TCC_TARGET_X86_64 |
| 494 | ST_FUNC void gen_expr64(ExprValue *pe) | 494 | ST_FUNC void gen_expr64(TCCState* S, ExprValue *pe) |
| 495 | { | 495 | { |
| 496 | gen_addr64(pe->sym ? VT_SYM : 0, pe->sym, pe->v); | 496 | gen_addr64(S, pe->sym ? VT_SYM : 0, pe->sym, pe->v); |
| 497 | } | 497 | } |
| 498 | #endif | 498 | #endif |
| 499 | 499 | ||
| 500 | /* XXX: unify with C code output ? */ | 500 | /* XXX: unify with C code output ? */ |
| 501 | static void gen_disp32(ExprValue *pe) | 501 | static void gen_disp32(TCCState* S, ExprValue *pe) |
| 502 | { | 502 | { |
| 503 | Sym *sym = pe->sym; | 503 | Sym *sym = pe->sym; |
| 504 | ElfSym *esym = elfsym(sym); | 504 | ElfSym *esym = elfsym(S, sym); |
| 505 | if (esym && esym->st_shndx == cur_text_section->sh_num) { | 505 | if (esym && esym->st_shndx == cur_text_section->sh_num) { |
| 506 | /* same section: we can output an absolute value. Note | 506 | /* same section: we can output an absolute value. Note |
| 507 | that the TCC compiler behaves differently here because | 507 | that the TCC compiler behaves differently here because |
| 508 | it always outputs a relocation to ease (future) code | 508 | it always outputs a relocation to ease (future) code |
| 509 | elimination in the linker */ | 509 | elimination in the linker */ |
| 510 | gen_le32(pe->v + esym->st_value - ind - 4); | 510 | gen_le32(S, pe->v + esym->st_value - S->tccgen_ind - 4); |
| 511 | } else { | 511 | } else { |
| 512 | if (sym && sym->type.t == VT_VOID) { | 512 | if (sym && sym->type.t == VT_VOID) { |
| 513 | sym->type.t = VT_FUNC; | 513 | sym->type.t = VT_FUNC; |
| 514 | sym->type.ref = NULL; | 514 | sym->type.ref = NULL; |
| 515 | } | 515 | } |
| 516 | gen_addrpc32(VT_SYM, sym, pe->v); | 516 | gen_addrpc32(S, VT_SYM, sym, pe->v); |
| 517 | } | 517 | } |
| 518 | } | 518 | } |
| 519 | 519 | ||
| 520 | /* generate the modrm operand */ | 520 | /* generate the modrm operand */ |
| 521 | static inline int asm_modrm(int reg, Operand *op) | 521 | static inline int asm_modrm(TCCState* S, int reg, Operand *op) |
| 522 | { | 522 | { |
| 523 | int mod, reg1, reg2, sib_reg1; | 523 | int mod, reg1, reg2, sib_reg1; |
| 524 | 524 | ||
| 525 | if (op->type & (OP_REG | OP_MMX | OP_SSE)) { | 525 | if (op->type & (OP_REG | OP_MMX | OP_SSE)) { |
| 526 | g(0xc0 + (reg << 3) + op->reg); | 526 | g(S, 0xc0 + (reg << 3) + op->reg); |
| 527 | } else if (op->reg == -1 && op->reg2 == -1) { | 527 | } else if (op->reg == -1 && op->reg2 == -1) { |
| 528 | /* displacement only */ | 528 | /* displacement only */ |
| 529 | #ifdef TCC_TARGET_X86_64 | 529 | #ifdef TCC_TARGET_X86_64 |
| 530 | g(0x04 + (reg << 3)); | 530 | g(S, 0x04 + (reg << 3)); |
| 531 | g(0x25); | 531 | g(S, 0x25); |
| 532 | #else | 532 | #else |
| 533 | g(0x05 + (reg << 3)); | 533 | g(S, 0x05 + (reg << 3)); |
| 534 | #endif | 534 | #endif |
| 535 | gen_expr32(&op->e); | 535 | gen_expr32(S, &op->e); |
| 536 | #ifdef TCC_TARGET_X86_64 | 536 | #ifdef TCC_TARGET_X86_64 |
| 537 | } else if (op->reg == -2) { | 537 | } else if (op->reg == -2) { |
| 538 | ExprValue *pe = &op->e; | 538 | ExprValue *pe = &op->e; |
| 539 | g(0x05 + (reg << 3)); | 539 | g(S, 0x05 + (reg << 3)); |
| 540 | gen_addrpc32(pe->sym ? VT_SYM : 0, pe->sym, pe->v); | 540 | gen_addrpc32(S, pe->sym ? VT_SYM : 0, pe->sym, pe->v); |
| 541 | return ind; | 541 | return S->tccgen_ind; |
| 542 | #endif | 542 | #endif |
| 543 | } else { | 543 | } else { |
| 544 | sib_reg1 = op->reg; | 544 | sib_reg1 = op->reg; |
| @@ -557,19 +557,19 @@ static inline int asm_modrm(int reg, Operand *op) · 12 unmodified lines | |||
| 557 | reg1 = op->reg; | 557 | reg1 = op->reg; |
| 558 | if (op->reg2 != -1) | 558 | if (op->reg2 != -1) |
| 559 | reg1 = 4; | 559 | reg1 = 4; |
| 560 | g(mod + (reg << 3) + reg1); | 560 | g(S, mod + (reg << 3) + reg1); |
| 561 | if (reg1 == 4) { | 561 | if (reg1 == 4) { |
| 562 | /* add sib byte */ | 562 | /* add sib byte */ |
| 563 | reg2 = op->reg2; | 563 | reg2 = op->reg2; |
| 564 | if (reg2 == -1) | 564 | if (reg2 == -1) |
| 565 | reg2 = 4; /* indicate no index */ | 565 | reg2 = 4; /* indicate no index */ |
| 566 | g((op->shift << 6) + (reg2 << 3) + sib_reg1); | 566 | g(S, (op->shift << 6) + (reg2 << 3) + sib_reg1); |
| 567 | } | 567 | } |
| 568 | /* add offset */ | 568 | /* add offset */ |
| 569 | if (mod == 0x40) { | 569 | if (mod == 0x40) { |
| 570 | g(op->e.v); | 570 | g(S, op->e.v); |
| 571 | } else if (mod == 0x80 || op->reg == -1) { | 571 | } else if (mod == 0x80 || op->reg == -1) { |
| 572 | gen_expr32(&op->e); | 572 | gen_expr32(S, &op->e); |
| 573 | } | 573 | } |
| 574 | } | 574 | } |
| 575 | return 0; | 575 | return 0; |
| @@ -581,7 +581,7 @@ static inline int asm_modrm(int reg, Operand *op) · 5 unmodified lines | |||
| 581 | #define REX_X 0x42 | 581 | #define REX_X 0x42 |
| 582 | #define REX_B 0x41 | 582 | #define REX_B 0x41 |
| 583 | 583 | ||
| 584 | static void asm_rex(int width64, Operand *ops, int nb_ops, int *op_type, | 584 | static void asm_rex(TCCState* S, int width64, Operand *ops, int nb_ops, int *op_type, |
| 585 | int regi, int rmi) | 585 | int regi, int rmi) |
| 586 | { | 586 | { |
| 587 | unsigned char rex = width64 ? 0x48 : 0; | 587 | unsigned char rex = width64 ? 0x48 : 0; |
| @@ -631,9 +631,9 @@ static void asm_rex(int width64, Operand *ops, int nb_ops, int *op_type, · 43 unmodified lines | |||
| 631 | } | 631 | } |
| 632 | if (rex) { | 632 | if (rex) { |
| 633 | if (saw_high_8bit) | 633 | if (saw_high_8bit) |
| 634 | tcc_error("can't encode register %%%ch when REX prefix is required", | 634 | tcc_error(S, "can't encode register %%%ch when REX prefix is required", |
| 635 | "acdb"[saw_high_8bit-4]); | 635 | "acdb"[saw_high_8bit-4]); |
| 636 | g(rex); | 636 | g(S, rex); |
| 637 | } | 637 | } |
| 638 | } | 638 | } |
| 639 | #endif | 639 | #endif |
| @@ -679,7 +679,7 @@ static void maybe_print_stats (void) · 39 unmodified lines | |||
| 679 | } | 679 | } |
| 680 | } | 680 | } |
| 681 | 681 | ||
| 682 | ST_FUNC void asm_opcode(TCCState *s1, int opcode) | 682 | ST_FUNC void asm_opcode(TCCState *S, int opcode) |
| 683 | { | 683 | { |
| 684 | const ASMInstr *pa; | 684 | const ASMInstr *pa; |
| 685 | int i, modrm_index, modreg_index, reg, v, op1, seg_prefix, pc; | 685 | int i, modrm_index, modreg_index, reg, v, op1, seg_prefix, pc; |
| @@ -697,7 +697,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode) · 11 unmodified lines | |||
| 697 | /* force synthetic ';' after prefix instruction, so we can handle */ | 697 | /* force synthetic ';' after prefix instruction, so we can handle */ |
| 698 | /* one-line things like "rep stosb" instead of only "rep\nstosb" */ | 698 | /* one-line things like "rep stosb" instead of only "rep\nstosb" */ |
| 699 | if (opcode >= TOK_ASM_wait && opcode <= TOK_ASM_repnz) | 699 | if (opcode >= TOK_ASM_wait && opcode <= TOK_ASM_repnz) |
| 700 | unget_tok(';'); | 700 | unget_tok(S, ';'); |
| 701 | 701 | ||
| 702 | /* get operands */ | 702 | /* get operands */ |
| 703 | pop = ops; | 703 | pop = ops; |
| @@ -705,27 +705,27 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode) · 1 unmodified line | |||
| 705 | seg_prefix = 0; | 705 | seg_prefix = 0; |
| 706 | alltypes = 0; | 706 | alltypes = 0; |
| 707 | for(;;) { | 707 | for(;;) { |
| 708 | if (tok == ';' || tok == TOK_LINEFEED) | 708 | if (S->tccpp_tok == ';' || S->tccpp_tok == TOK_LINEFEED) |
| 709 | break; | 709 | break; |
| 710 | if (nb_ops >= MAX_OPERANDS) { | 710 | if (nb_ops >= MAX_OPERANDS) { |
| 711 | tcc_error("incorrect number of operands"); | 711 | tcc_error(S, "incorrect number of operands"); |
| 712 | } | 712 | } |
| 713 | parse_operand(s1, pop); | 713 | parse_operand(S, pop); |
| 714 | if (tok == ':') { | 714 | if (S->tccpp_tok == ':') { |
| 715 | if (pop->type != OP_SEG || seg_prefix) | 715 | if (pop->type != OP_SEG || seg_prefix) |
| 716 | tcc_error("incorrect prefix"); | 716 | tcc_error(S, "incorrect prefix"); |
| 717 | seg_prefix = segment_prefixes[pop->reg]; | 717 | seg_prefix = segment_prefixes[pop->reg]; |
| 718 | next(); | 718 | next(S); |
| 719 | parse_operand(s1, pop); | 719 | parse_operand(S, pop); |
| 720 | if (!(pop->type & OP_EA)) { | 720 | if (!(pop->type & OP_EA)) { |
| 721 | tcc_error("segment prefix must be followed by memory reference"); | 721 | tcc_error(S, "segment prefix must be followed by memory reference"); |
| 722 | } | 722 | } |
| 723 | } | 723 | } |
| 724 | pop++; | 724 | pop++; |
| 725 | nb_ops++; | 725 | nb_ops++; |
| 726 | if (tok != ',') | 726 | if (S->tccpp_tok != ',') |
| 727 | break; | 727 | break; |
| 728 | next(); | 728 | next(S); |
| 729 | } | 729 | } |
| 730 | 730 | ||
| 731 | s = 0; /* avoid warning */ | 731 | s = 0; /* avoid warning */ |
| @@ -842,23 +842,23 @@ again: · 110 unmodified lines | |||
| 842 | int b; | 842 | int b; |
| 843 | b = op0_codes[opcode - TOK_ASM_first]; | 843 | b = op0_codes[opcode - TOK_ASM_first]; |
| 844 | if (b & 0xff00) | 844 | if (b & 0xff00) |
| 845 | g(b >> 8); | 845 | g(S, b >> 8); |
| 846 | g(b); | 846 | g(S, b); |
| 847 | return; | 847 | return; |
| 848 | } else if (opcode <= TOK_ASM_alllast) { | 848 | } else if (opcode <= TOK_ASM_alllast) { |
| 849 | tcc_error("bad operand with opcode '%s'", | 849 | tcc_error(S, "bad operand with opcode '%s'", |
| 850 | get_tok_str(opcode, NULL)); | 850 | get_tok_str(S, opcode, NULL)); |
| 851 | } else { | 851 | } else { |
| 852 | /* Special case for cmovcc, we accept size suffixes but ignore | 852 | /* Special case for cmovcc, we accept size suffixes but ignore |
| 853 | them, but we don't want them to blow up our tables. */ | 853 | them, but we don't want them to blow up our tables. */ |
| 854 | TokenSym *ts = table_ident[opcode - TOK_IDENT]; | 854 | TokenSym *ts = S->tccpp_table_ident[opcode - TOK_IDENT]; |
| 855 | if (ts->len >= 6 | 855 | if (ts->len >= 6 |
| 856 | && strchr("wlq", ts->str[ts->len-1]) | 856 | && strchr("wlq", ts->str[ts->len-1]) |
| 857 | && !memcmp(ts->str, "cmov", 4)) { | 857 | && !memcmp(ts->str, "cmov", 4)) { |
| 858 | opcode = tok_alloc(ts->str, ts->len-1)->tok; | 858 | opcode = tok_alloc(S, ts->str, ts->len-1)->tok; |
| 859 | goto again; | 859 | goto again; |
| 860 | } | 860 | } |
| 861 | tcc_error("unknown opcode '%s'", ts->str); | 861 | tcc_error(S, "unknown opcode '%s'", ts->str); |
| 862 | } | 862 | } |
| 863 | } | 863 | } |
| 864 | /* if the size is unknown, then evaluate it (OPC_B or OPC_WL case) */ | 864 | /* if the size is unknown, then evaluate it (OPC_B or OPC_WL case) */ |
| @@ -886,7 +886,7 @@ again: · 21 unmodified lines | |||
| 886 | (ops[0].type & OP_EA)) | 886 | (ops[0].type & OP_EA)) |
| 887 | s = NBWLX - 2; | 887 | s = NBWLX - 2; |
| 888 | else | 888 | else |
| 889 | tcc_error("cannot infer opcode suffix"); | 889 | tcc_error(S, "cannot infer opcode suffix"); |
| 890 | } | 890 | } |
| 891 | } | 891 | } |
| 892 | 892 | ||
| @@ -894,7 +894,7 @@ again: · 1 unmodified line | |||
| 894 | /* Generate addr32 prefix if needed */ | 894 | /* Generate addr32 prefix if needed */ |
| 895 | for(i = 0; i < nb_ops; i++) { | 895 | for(i = 0; i < nb_ops; i++) { |
| 896 | if (ops[i].type & OP_EA32) { | 896 | if (ops[i].type & OP_EA32) { |
| 897 | g(0x67); | 897 | g(S, 0x67); |
| 898 | break; | 898 | break; |
| 899 | } | 899 | } |
| 900 | } | 900 | } |
| @@ -913,7 +913,7 @@ again: · 12 unmodified lines | |||
| 913 | p66 = 1; | 913 | p66 = 1; |
| 914 | } | 914 | } |
| 915 | if (p66) | 915 | if (p66) |
| 916 | g(0x66); | 916 | g(S, 0x66); |
| 917 | #ifdef TCC_TARGET_X86_64 | 917 | #ifdef TCC_TARGET_X86_64 |
| 918 | rex64 = 0; | 918 | rex64 = 0; |
| 919 | if (pa->instr_type & OPC_48) | 919 | if (pa->instr_type & OPC_48) |
| @@ -943,9 +943,9 @@ again: · 23 unmodified lines | |||
| 943 | 943 | ||
| 944 | /* now generates the operation */ | 944 | /* now generates the operation */ |
| 945 | if (OPCT_IS(pa->instr_type, OPC_FWAIT)) | 945 | if (OPCT_IS(pa->instr_type, OPC_FWAIT)) |
| 946 | g(0x9b); | 946 | g(S, 0x9b); |
| 947 | if (seg_prefix) | 947 | if (seg_prefix) |
| 948 | g(seg_prefix); | 948 | g(S, seg_prefix); |
| 949 | 949 | ||
| 950 | v = pa->opcode; | 950 | v = pa->opcode; |
| 951 | if (pa->instr_type & OPC_0F) | 951 | if (pa->instr_type & OPC_0F) |
| @@ -998,7 +998,7 @@ again: · 46 unmodified lines | |||
| 998 | goto modrm_found; | 998 | goto modrm_found; |
| 999 | } | 999 | } |
| 1000 | #ifdef ASM_DEBUG | 1000 | #ifdef ASM_DEBUG |
| 1001 | tcc_error("bad op table"); | 1001 | tcc_error(S, "bad op table"); |
| 1002 | #endif | 1002 | #endif |
| 1003 | modrm_found: | 1003 | modrm_found: |
| 1004 | modrm_index = i; | 1004 | modrm_index = i; |
| @@ -1014,7 +1014,7 @@ again: · 9 unmodified lines | |||
| 1014 | } | 1014 | } |
| 1015 | } | 1015 | } |
| 1016 | #ifdef TCC_TARGET_X86_64 | 1016 | #ifdef TCC_TARGET_X86_64 |
| 1017 | asm_rex (rex64, ops, nb_ops, op_type, modreg_index, modrm_index); | 1017 | asm_rex (S, rex64, ops, nb_ops, op_type, modreg_index, modrm_index); |
| 1018 | #endif | 1018 | #endif |
| 1019 | 1019 | ||
| 1020 | if (pa->instr_type & OPC_REG) { | 1020 | if (pa->instr_type & OPC_REG) { |
| @@ -1035,10 +1035,10 @@ again: · 14 unmodified lines | |||
| 1035 | int jmp_disp; | 1035 | int jmp_disp; |
| 1036 | 1036 | ||
| 1037 | /* see if we can really generate the jump with a byte offset */ | 1037 | /* see if we can really generate the jump with a byte offset */ |
| 1038 | esym = elfsym(ops[0].e.sym); | 1038 | esym = elfsym(S, ops[0].e.sym); |
| 1039 | if (!esym || esym->st_shndx != cur_text_section->sh_num) | 1039 | if (!esym || esym->st_shndx != cur_text_section->sh_num) |
| 1040 | goto no_short_jump; | 1040 | goto no_short_jump; |
| 1041 | jmp_disp = ops[0].e.v + esym->st_value - ind - 2 - (v >= 0xff); | 1041 | jmp_disp = ops[0].e.v + esym->st_value - S->tccgen_ind - 2 - (v >= 0xff); |
| 1042 | if (jmp_disp == (int8_t)jmp_disp) { | 1042 | if (jmp_disp == (int8_t)jmp_disp) { |
| 1043 | /* OK to generate jump */ | 1043 | /* OK to generate jump */ |
| 1044 | ops[0].e.sym = 0; | 1044 | ops[0].e.sym = 0; |
| @@ -1053,18 +1053,18 @@ again: · 8 unmodified lines | |||
| 1053 | else if (v == 0x70) /* jcc */ | 1053 | else if (v == 0x70) /* jcc */ |
| 1054 | v += 0x0f10; | 1054 | v += 0x0f10; |
| 1055 | else | 1055 | else |
| 1056 | tcc_error("invalid displacement"); | 1056 | tcc_error(S, "invalid displacement"); |
| 1057 | } | 1057 | } |
| 1058 | } | 1058 | } |
| 1059 | if (OPCT_IS(pa->instr_type, OPC_TEST)) | 1059 | if (OPCT_IS(pa->instr_type, OPC_TEST)) |
| 1060 | v += test_bits[opcode - pa->sym]; | 1060 | v += test_bits[opcode - pa->sym]; |
| 1061 | op1 = v >> 16; | 1061 | op1 = v >> 16; |
| 1062 | if (op1) | 1062 | if (op1) |
| 1063 | g(op1); | 1063 | g(S, op1); |
| 1064 | op1 = (v >> 8) & 0xff; | 1064 | op1 = (v >> 8) & 0xff; |
| 1065 | if (op1) | 1065 | if (op1) |
| 1066 | g(op1); | 1066 | g(S, op1); |
| 1067 | g(v); | 1067 | g(S, v); |
| 1068 | 1068 | ||
| 1069 | if (OPCT_IS(pa->instr_type, OPC_SHIFT)) { | 1069 | if (OPCT_IS(pa->instr_type, OPC_SHIFT)) { |
| 1070 | reg = (opcode - pa->sym) / NBWLX; | 1070 | reg = (opcode - pa->sym) / NBWLX; |
| @@ -1084,7 +1084,7 @@ again: · 13 unmodified lines | |||
| 1084 | used instead of group */ | 1084 | used instead of group */ |
| 1085 | if (modreg_index >= 0) | 1085 | if (modreg_index >= 0) |
| 1086 | reg = ops[modreg_index].reg; | 1086 | reg = ops[modreg_index].reg; |
| 1087 | pc = asm_modrm(reg, &ops[modrm_index]); | 1087 | pc = asm_modrm(S, reg, &ops[modrm_index]); |
| 1088 | } | 1088 | } |
| 1089 | 1089 | ||
| 1090 | /* emit constants */ | 1090 | /* emit constants */ |
| @@ -1092,10 +1092,10 @@ again: · 1 unmodified line | |||
| 1092 | if (!(pa->instr_type & OPC_0F) | 1092 | if (!(pa->instr_type & OPC_0F) |
| 1093 | && (pa->opcode == 0x9a || pa->opcode == 0xea)) { | 1093 | && (pa->opcode == 0x9a || pa->opcode == 0xea)) { |
| 1094 | /* ljmp or lcall kludge */ | 1094 | /* ljmp or lcall kludge */ |
| 1095 | gen_expr32(&ops[1].e); | 1095 | gen_expr32(S, &ops[1].e); |
| 1096 | if (ops[0].e.sym) | 1096 | if (ops[0].e.sym) |
| 1097 | tcc_error("cannot relocate"); | 1097 | tcc_error(S, "cannot relocate"); |
| 1098 | gen_le16(ops[0].e.v); | 1098 | gen_le16(S, ops[0].e.v); |
| 1099 | return; | 1099 | return; |
| 1100 | } | 1100 | } |
| 1101 | #endif | 1101 | #endif |
| @@ -1116,32 +1116,32 @@ again: · 14 unmodified lines | |||
| 1116 | } | 1116 | } |
| 1117 | 1117 | ||
| 1118 | if ((v & (OP_IM8 | OP_IM8S | OP_IM16)) && ops[i].e.sym) | 1118 | if ((v & (OP_IM8 | OP_IM8S | OP_IM16)) && ops[i].e.sym) |
| 1119 | tcc_error("cannot relocate"); | 1119 | tcc_error(S, "cannot relocate"); |
| 1120 | 1120 | ||
| 1121 | if (v & (OP_IM8 | OP_IM8S)) { | 1121 | if (v & (OP_IM8 | OP_IM8S)) { |
| 1122 | g(ops[i].e.v); | 1122 | g(S, ops[i].e.v); |
| 1123 | } else if (v & OP_IM16) { | 1123 | } else if (v & OP_IM16) { |
| 1124 | gen_le16(ops[i].e.v); | 1124 | gen_le16(S, ops[i].e.v); |
| 1125 | #ifdef TCC_TARGET_X86_64 | 1125 | #ifdef TCC_TARGET_X86_64 |
| 1126 | } else if (v & OP_IM64) { | 1126 | } else if (v & OP_IM64) { |
| 1127 | gen_expr64(&ops[i].e); | 1127 | gen_expr64(S, &ops[i].e); |
| 1128 | #endif | 1128 | #endif |
| 1129 | } else if (pa->op_type[i] == OPT_DISP || pa->op_type[i] == OPT_DISP8) { | 1129 | } else if (pa->op_type[i] == OPT_DISP || pa->op_type[i] == OPT_DISP8) { |
| 1130 | gen_disp32(&ops[i].e); | 1130 | gen_disp32(S, &ops[i].e); |
| 1131 | } else { | 1131 | } else { |
| 1132 | gen_expr32(&ops[i].e); | 1132 | gen_expr32(S, &ops[i].e); |
| 1133 | } | 1133 | } |
| 1134 | } | 1134 | } |
| 1135 | } | 1135 | } |
| 1136 | 1136 | ||
| 1137 | /* after immediate operands, adjust pc-relative address */ | 1137 | /* after immediate operands, adjust pc-relative address */ |
| 1138 | if (pc) | 1138 | if (pc) |
| 1139 | add32le(cur_text_section->data + pc - 4, pc - ind); | 1139 | add32le(cur_text_section->data + pc - 4, pc - S->tccgen_ind); |
| 1140 | } | 1140 | } |
| 1141 | 1141 | ||
| 1142 | /* return the constraint priority (we allocate first the lowest | 1142 | /* return the constraint priority (we allocate first the lowest |
| 1143 | numbered constraints) */ | 1143 | numbered constraints) */ |
| 1144 | static inline int constraint_priority(const char *str) | 1144 | static inline int constraint_priority(TCCState* S, const char *str) |
| 1145 | { | 1145 | { |
| 1146 | int priority, c, pr; | 1146 | int priority, c, pr; |
| 1147 | 1147 | ||
| @@ -1182,7 +1182,7 @@ static inline int constraint_priority(const char *str) · 34 unmodified lines | |||
| 1182 | pr = 4; | 1182 | pr = 4; |
| 1183 | break; | 1183 | break; |
| 1184 | default: | 1184 | default: |
| 1185 | tcc_error("unknown constraint '%c'", c); | 1185 | tcc_error(S, "unknown constraint '%c'", c); |
| 1186 | pr = 0; | 1186 | pr = 0; |
| 1187 | } | 1187 | } |
| 1188 | if (pr > priority) | 1188 | if (pr > priority) |
| @@ -1200,19 +1200,19 @@ static const char *skip_constraint_modifiers(const char *p) · 11 unmodified lines | |||
| 1200 | 1200 | ||
| 1201 | /* If T (a token) is of the form "%reg" returns the register | 1201 | /* If T (a token) is of the form "%reg" returns the register |
| 1202 | number and type, otherwise return -1. */ | 1202 | number and type, otherwise return -1. */ |
| 1203 | ST_FUNC int asm_parse_regvar (int t) | 1203 | ST_FUNC int asm_parse_regvar (TCCState* S, int t) |
| 1204 | { | 1204 | { |
| 1205 | const char *s; | 1205 | const char *s; |
| 1206 | Operand op; | 1206 | Operand op; |
| 1207 | if (t < TOK_IDENT || (t & SYM_FIELD)) | 1207 | if (t < TOK_IDENT || (t & SYM_FIELD)) |
| 1208 | return -1; | 1208 | return -1; |
| 1209 | s = table_ident[t - TOK_IDENT]->str; | 1209 | s = S->tccpp_table_ident[t - TOK_IDENT]->str; |
| 1210 | if (s[0] != '%') | 1210 | if (s[0] != '%') |
| 1211 | return -1; | 1211 | return -1; |
| 1212 | t = tok_alloc_const(s + 1); | 1212 | t = tok_alloc_const(S, s + 1); |
| 1213 | unget_tok(t); | 1213 | unget_tok(S, t); |
| 1214 | unget_tok('%'); | 1214 | unget_tok(S, '%'); |
| 1215 | parse_operand(tcc_state, &op); | 1215 | parse_operand(S, &op); |
| 1216 | /* Accept only integer regs for now. */ | 1216 | /* Accept only integer regs for now. */ |
| 1217 | if (op.type & OP_REG) | 1217 | if (op.type & OP_REG) |
| 1218 | return op.reg; | 1218 | return op.reg; |
| @@ -1225,7 +1225,7 @@ ST_FUNC int asm_parse_regvar (int t) · 6 unmodified lines | |||
| 1225 | 1225 | ||
| 1226 | #define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask) | 1226 | #define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask) |
| 1227 | 1227 | ||
| 1228 | ST_FUNC void asm_compute_constraints(ASMOperand *operands, | 1228 | ST_FUNC void asm_compute_constraints(TCCState* S, ASMOperand *operands, |
| 1229 | int nb_operands, int nb_outputs, | 1229 | int nb_operands, int nb_outputs, |
| 1230 | const uint8_t *clobber_regs, | 1230 | const uint8_t *clobber_regs, |
| 1231 | int *pout_reg) | 1231 | int *pout_reg) |
| @@ -1253,13 +1253,13 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 21 unmodified lines | |||
| 1253 | str = skip_constraint_modifiers(str); | 1253 | str = skip_constraint_modifiers(str); |
| 1254 | if (isnum(*str) || *str == '[') { | 1254 | if (isnum(*str) || *str == '[') { |
| 1255 | /* this is a reference to another constraint */ | 1255 | /* this is a reference to another constraint */ |
| 1256 | k = find_constraint(operands, nb_operands, str, NULL); | 1256 | k = find_constraint(S, operands, nb_operands, str, NULL); |
| 1257 | if ((unsigned)k >= i || i < nb_outputs) | 1257 | if ((unsigned)k >= i || i < nb_outputs) |
| 1258 | tcc_error("invalid reference in constraint %d ('%s')", | 1258 | tcc_error(S, "invalid reference in constraint %d ('%s')", |
| 1259 | i, str); | 1259 | i, str); |
| 1260 | op->ref_index = k; | 1260 | op->ref_index = k; |
| 1261 | if (operands[k].input_index >= 0) | 1261 | if (operands[k].input_index >= 0) |
| 1262 | tcc_error("cannot reference twice the same operand"); | 1262 | tcc_error(S, "cannot reference twice the same operand"); |
| 1263 | operands[k].input_index = i; | 1263 | operands[k].input_index = i; |
| 1264 | op->priority = 5; | 1264 | op->priority = 5; |
| 1265 | } else if ((op->vt->r & VT_VALMASK) == VT_LOCAL | 1265 | } else if ((op->vt->r & VT_VALMASK) == VT_LOCAL |
| @@ -1268,7 +1268,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 2 unmodified lines | |||
| 1268 | op->priority = 1; | 1268 | op->priority = 1; |
| 1269 | op->reg = reg; | 1269 | op->reg = reg; |
| 1270 | } else { | 1270 | } else { |
| 1271 | op->priority = constraint_priority(str); | 1271 | op->priority = constraint_priority(S, str); |
| 1272 | } | 1272 | } |
| 1273 | } | 1273 | } |
| 1274 | 1274 | ||
| @@ -1316,7 +1316,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 41 unmodified lines | |||
| 1316 | } | 1316 | } |
| 1317 | if (op->reg >= 0) { | 1317 | if (op->reg >= 0) { |
| 1318 | if (is_reg_allocated(op->reg)) | 1318 | if (is_reg_allocated(op->reg)) |
| 1319 | tcc_error("asm regvar requests register that's taken already"); | 1319 | tcc_error(S, "asm regvar requests register that's taken already"); |
| 1320 | reg = op->reg; | 1320 | reg = op->reg; |
| 1321 | goto reg_found; | 1321 | goto reg_found; |
| 1322 | } | 1322 | } |
| @@ -1330,7 +1330,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 7 unmodified lines | |||
| 1330 | /* FALL THRU */ | 1330 | /* FALL THRU */ |
| 1331 | case '&': | 1331 | case '&': |
| 1332 | if (j >= nb_outputs) | 1332 | if (j >= nb_outputs) |
| 1333 | tcc_error("'%c' modifier can only be applied to outputs", c); | 1333 | tcc_error(S, "'%c' modifier can only be applied to outputs", c); |
| 1334 | reg_mask = REG_IN_MASK | REG_OUT_MASK; | 1334 | reg_mask = REG_IN_MASK | REG_OUT_MASK; |
| 1335 | goto try_next; | 1335 | goto try_next; |
| 1336 | case 'A': | 1336 | case 'A': |
| @@ -1424,7 +1424,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 87 unmodified lines | |||
| 1424 | } | 1424 | } |
| 1425 | break; | 1425 | break; |
| 1426 | default: | 1426 | default: |
| 1427 | tcc_error("asm constraint %d ('%s') could not be satisfied", | 1427 | tcc_error(S, "asm constraint %d ('%s') could not be satisfied", |
| 1428 | j, op->constraint); | 1428 | j, op->constraint); |
| 1429 | break; | 1429 | break; |
| 1430 | } | 1430 | } |
| @@ -1447,7 +1447,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 16 unmodified lines | |||
| 1447 | if (!(regs_allocated[reg] & REG_OUT_MASK)) | 1447 | if (!(regs_allocated[reg] & REG_OUT_MASK)) |
| 1448 | goto reg_found2; | 1448 | goto reg_found2; |
| 1449 | } | 1449 | } |
| 1450 | tcc_error("could not find free output register for reloading"); | 1450 | tcc_error(S, "could not find free output register for reloading"); |
| 1451 | reg_found2: | 1451 | reg_found2: |
| 1452 | *pout_reg = reg; | 1452 | *pout_reg = reg; |
| 1453 | break; | 1453 | break; |
| @@ -1461,7 +1461,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 7 unmodified lines | |||
| 1461 | op = &operands[j]; | 1461 | op = &operands[j]; |
| 1462 | printf("%%%d [%s]: \"%s\" r=0x%04x reg=%d\n", | 1462 | printf("%%%d [%s]: \"%s\" r=0x%04x reg=%d\n", |
| 1463 | j, | 1463 | j, |
| 1464 | op->id ? get_tok_str(op->id, NULL) : "", | 1464 | op->id ? get_tok_str(S, op->id, NULL) : "", |
| 1465 | op->constraint, | 1465 | op->constraint, |
| 1466 | op->vt->r, | 1466 | op->vt->r, |
| 1467 | op->reg); | 1467 | op->reg); |
| @@ -1471,7 +1471,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, · 3 unmodified lines | |||
| 1471 | #endif | 1471 | #endif |
| 1472 | } | 1472 | } |
| 1473 | 1473 | ||
| 1474 | ST_FUNC void subst_asm_operand(CString *add_str, | 1474 | ST_FUNC void subst_asm_operand(TCCState* S, CString *add_str, |
| 1475 | SValue *sv, int modifier) | 1475 | SValue *sv, int modifier) |
| 1476 | { | 1476 | { |
| 1477 | int r, reg, size, val; | 1477 | int r, reg, size, val; |
| @@ -1481,33 +1481,33 @@ ST_FUNC void subst_asm_operand(CString *add_str, · 3 unmodified lines | |||
| 1481 | if ((r & VT_VALMASK) == VT_CONST) { | 1481 | if ((r & VT_VALMASK) == VT_CONST) { |
| 1482 | if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n' && | 1482 | if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n' && |
| 1483 | modifier != 'P') | 1483 | modifier != 'P') |
| 1484 | cstr_ccat(add_str, '$'); | 1484 | cstr_ccat(S, add_str, '$'); |
| 1485 | if (r & VT_SYM) { | 1485 | if (r & VT_SYM) { |
| 1486 | const char *name = get_tok_str(sv->sym->v, NULL); | 1486 | const char *name = get_tok_str(S, sv->sym->v, NULL); |
| 1487 | if (sv->sym->v >= SYM_FIRST_ANOM) { | 1487 | if (sv->sym->v >= SYM_FIRST_ANOM) { |
| 1488 | /* In case of anonymous symbols ("L.42", used | 1488 | /* In case of anonymous symbols ("L.42", used |
| 1489 | for static data labels) we can't find them | 1489 | for static data labels) we can't find them |
| 1490 | in the C symbol table when later looking up | 1490 | in the C symbol table when later looking up |
| 1491 | this name. So enter them now into the asm label | 1491 | this name. So enter them now into the asm label |
| 1492 | list when we still know the symbol. */ | 1492 | list when we still know the symbol. */ |
| 1493 | get_asm_sym(tok_alloc_const(name), sv->sym); | 1493 | get_asm_sym(S, tok_alloc_const(S, name), sv->sym); |
| 1494 | } | 1494 | } |
| 1495 | if (tcc_state->leading_underscore) | 1495 | if (S->leading_underscore) |
| 1496 | cstr_ccat(add_str, '_'); | 1496 | cstr_ccat(S, add_str, '_'); |
| 1497 | cstr_cat(add_str, name, -1); | 1497 | cstr_cat(S, add_str, name, -1); |
| 1498 | if ((uint32_t)sv->c.i == 0) | 1498 | if ((uint32_t)sv->c.i == 0) |
| 1499 | goto no_offset; | 1499 | goto no_offset; |
| 1500 | cstr_ccat(add_str, '+'); | 1500 | cstr_ccat(S, add_str, '+'); |
| 1501 | } | 1501 | } |
| 1502 | val = sv->c.i; | 1502 | val = sv->c.i; |
| 1503 | if (modifier == 'n') | 1503 | if (modifier == 'n') |
| 1504 | val = -val; | 1504 | val = -val; |
| 1505 | snprintf(buf, sizeof(buf), "%d", (int)sv->c.i); | 1505 | snprintf(buf, sizeof(buf), "%d", (int)sv->c.i); |
| 1506 | cstr_cat(add_str, buf, -1); | 1506 | cstr_cat(S, add_str, buf, -1); |
| 1507 | no_offset:; | 1507 | no_offset:; |
| 1508 | #ifdef TCC_TARGET_X86_64 | 1508 | #ifdef TCC_TARGET_X86_64 |
| 1509 | if (r & VT_LVAL) | 1509 | if (r & VT_LVAL) |
| 1510 | cstr_cat(add_str, "(%rip)", -1); | 1510 | cstr_cat(S, add_str, "(%rip)", -1); |
| 1511 | #endif | 1511 | #endif |
| 1512 | } else if ((r & VT_VALMASK) == VT_LOCAL) { | 1512 | } else if ((r & VT_VALMASK) == VT_LOCAL) { |
| 1513 | #ifdef TCC_TARGET_X86_64 | 1513 | #ifdef TCC_TARGET_X86_64 |
| @@ -1515,24 +1515,24 @@ ST_FUNC void subst_asm_operand(CString *add_str, · 1 unmodified line | |||
| 1515 | #else | 1515 | #else |
| 1516 | snprintf(buf, sizeof(buf), "%d(%%ebp)", (int)sv->c.i); | 1516 | snprintf(buf, sizeof(buf), "%d(%%ebp)", (int)sv->c.i); |
| 1517 | #endif | 1517 | #endif |
| 1518 | cstr_cat(add_str, buf, -1); | 1518 | cstr_cat(S, add_str, buf, -1); |
| 1519 | } else if (r & VT_LVAL) { | 1519 | } else if (r & VT_LVAL) { |
| 1520 | reg = r & VT_VALMASK; | 1520 | reg = r & VT_VALMASK; |
| 1521 | if (reg >= VT_CONST) | 1521 | if (reg >= VT_CONST) |
| 1522 | tcc_internal_error(""); | 1522 | tcc_internal_error(S, ""); |
| 1523 | snprintf(buf, sizeof(buf), "(%%%s)", | 1523 | snprintf(buf, sizeof(buf), "(%%%s)", |
| 1524 | #ifdef TCC_TARGET_X86_64 | 1524 | #ifdef TCC_TARGET_X86_64 |
| 1525 | get_tok_str(TOK_ASM_rax + reg, NULL) | 1525 | get_tok_str(S, TOK_ASM_rax + reg, NULL) |
| 1526 | #else | 1526 | #else |
| 1527 | get_tok_str(TOK_ASM_eax + reg, NULL) | 1527 | get_tok_str(S, TOK_ASM_eax + reg, NULL) |
| 1528 | #endif | 1528 | #endif |
| 1529 | ); | 1529 | ); |
| 1530 | cstr_cat(add_str, buf, -1); | 1530 | cstr_cat(S, add_str, buf, -1); |
| 1531 | } else { | 1531 | } else { |
| 1532 | /* register case */ | 1532 | /* register case */ |
| 1533 | reg = r & VT_VALMASK; | 1533 | reg = r & VT_VALMASK; |
| 1534 | if (reg >= VT_CONST) | 1534 | if (reg >= VT_CONST) |
| 1535 | tcc_internal_error(""); | 1535 | tcc_internal_error(S, ""); |
| 1536 | 1536 | ||
| 1537 | /* choose register operand size */ | 1537 | /* choose register operand size */ |
| 1538 | if ((sv->type.t & VT_BTYPE) == VT_BYTE || | 1538 | if ((sv->type.t & VT_BTYPE) == VT_BYTE || |
| @@ -1552,11 +1552,11 @@ ST_FUNC void subst_asm_operand(CString *add_str, · 13 unmodified lines | |||
| 1552 | 1552 | ||
| 1553 | if (modifier == 'b') { | 1553 | if (modifier == 'b') { |
| 1554 | if (reg >= 4) | 1554 | if (reg >= 4) |
| 1555 | tcc_error("cannot use byte register"); | 1555 | tcc_error(S, "cannot use byte register"); |
| 1556 | size = 1; | 1556 | size = 1; |
| 1557 | } else if (modifier == 'h') { | 1557 | } else if (modifier == 'h') { |
| 1558 | if (reg >= 4) | 1558 | if (reg >= 4) |
| 1559 | tcc_error("cannot use byte register"); | 1559 | tcc_error(S, "cannot use byte register"); |
| 1560 | size = -1; | 1560 | size = -1; |
| 1561 | } else if (modifier == 'w') { | 1561 | } else if (modifier == 'w') { |
| 1562 | size = 2; | 1562 | size = 2; |
| @@ -1587,13 +1587,13 @@ ST_FUNC void subst_asm_operand(CString *add_str, · 24 unmodified lines | |||
| 1587 | break; | 1587 | break; |
| 1588 | #endif | 1588 | #endif |
| 1589 | } | 1589 | } |
| 1590 | snprintf(buf, sizeof(buf), "%%%s", get_tok_str(reg, NULL)); | 1590 | snprintf(buf, sizeof(buf), "%%%s", get_tok_str(S, reg, NULL)); |
| 1591 | cstr_cat(add_str, buf, -1); | 1591 | cstr_cat(S, add_str, buf, -1); |
| 1592 | } | 1592 | } |
| 1593 | } | 1593 | } |
| 1594 | 1594 | ||
| 1595 | /* generate prolog and epilog code for asm statement */ | 1595 | /* generate prolog and epilog code for asm statement */ |
| 1596 | ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, | 1596 | ST_FUNC void asm_gen_code(TCCState* S, ASMOperand *operands, int nb_operands, |
| 1597 | int nb_outputs, int is_output, | 1597 | int nb_outputs, int is_output, |
| 1598 | uint8_t *clobber_regs, | 1598 | uint8_t *clobber_regs, |
| 1599 | int out_reg) | 1599 | int out_reg) |
| @@ -1627,8 +1627,8 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, · 27 unmodified lines | |||
| 1627 | reg = reg_saved[i]; | 1627 | reg = reg_saved[i]; |
| 1628 | if (regs_allocated[reg]) { | 1628 | if (regs_allocated[reg]) { |
| 1629 | if (reg >= 8) | 1629 | if (reg >= 8) |
| 1630 | g(0x41), reg-=8; | 1630 | g(S, 0x41), reg-=8; |
| 1631 | g(0x50 + reg); | 1631 | g(S, 0x50 + reg); |
| 1632 | } | 1632 | } |
| 1633 | } | 1633 | } |
| 1634 | 1634 | ||
| @@ -1644,15 +1644,15 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, · 9 unmodified lines | |||
| 1644 | sv = *op->vt; | 1644 | sv = *op->vt; |
| 1645 | sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL | VT_LVAL; | 1645 | sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL | VT_LVAL; |
| 1646 | sv.type.t = VT_PTR; | 1646 | sv.type.t = VT_PTR; |
| 1647 | load(op->reg, &sv); | 1647 | load(S, op->reg, &sv); |
| 1648 | } else if (i >= nb_outputs || op->is_rw) { | 1648 | } else if (i >= nb_outputs || op->is_rw) { |
| 1649 | /* load value in register */ | 1649 | /* load value in register */ |
| 1650 | load(op->reg, op->vt); | 1650 | load(S, op->reg, op->vt); |
| 1651 | if (op->is_llong) { | 1651 | if (op->is_llong) { |
| 1652 | SValue sv; | 1652 | SValue sv; |
| 1653 | sv = *op->vt; | 1653 | sv = *op->vt; |
| 1654 | sv.c.i += 4; | 1654 | sv.c.i += 4; |
| 1655 | load(TREG_XDX, &sv); | 1655 | load(S, TREG_XDX, &sv); |
| 1656 | } | 1656 | } |
| 1657 | } | 1657 | } |
| 1658 | } | 1658 | } |
| @@ -1668,19 +1668,19 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, · 9 unmodified lines | |||
| 1668 | sv = *op->vt; | 1668 | sv = *op->vt; |
| 1669 | sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL; | 1669 | sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL; |
| 1670 | sv.type.t = VT_PTR; | 1670 | sv.type.t = VT_PTR; |
| 1671 | load(out_reg, &sv); | 1671 | load(S, out_reg, &sv); |
| 1672 | 1672 | ||
| 1673 | sv = *op->vt; | 1673 | sv = *op->vt; |
| 1674 | sv.r = (sv.r & ~VT_VALMASK) | out_reg; | 1674 | sv.r = (sv.r & ~VT_VALMASK) | out_reg; |
| 1675 | store(op->reg, &sv); | 1675 | store(S, op->reg, &sv); |
| 1676 | } | 1676 | } |
| 1677 | } else { | 1677 | } else { |
| 1678 | store(op->reg, op->vt); | 1678 | store(S, op->reg, op->vt); |
| 1679 | if (op->is_llong) { | 1679 | if (op->is_llong) { |
| 1680 | SValue sv; | 1680 | SValue sv; |
| 1681 | sv = *op->vt; | 1681 | sv = *op->vt; |
| 1682 | sv.c.i += 4; | 1682 | sv.c.i += 4; |
| 1683 | store(TREG_XDX, &sv); | 1683 | store(S, TREG_XDX, &sv); |
| 1684 | } | 1684 | } |
| 1685 | } | 1685 | } |
| 1686 | } | 1686 | } |
| @@ -1690,14 +1690,14 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, · 3 unmodified lines | |||
| 1690 | reg = reg_saved[i]; | 1690 | reg = reg_saved[i]; |
| 1691 | if (regs_allocated[reg]) { | 1691 | if (regs_allocated[reg]) { |
| 1692 | if (reg >= 8) | 1692 | if (reg >= 8) |
| 1693 | g(0x41), reg-=8; | 1693 | g(S, 0x41), reg-=8; |
| 1694 | g(0x58 + reg); | 1694 | g(S, 0x58 + reg); |
| 1695 | } | 1695 | } |
| 1696 | } | 1696 | } |
| 1697 | } | 1697 | } |
| 1698 | } | 1698 | } |
| 1699 | 1699 | ||
| 1700 | ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str) | 1700 | ST_FUNC void asm_clobber(TCCState* S, uint8_t *clobber_regs, const char *str) |
| 1701 | { | 1701 | { |
| 1702 | int reg; | 1702 | int reg; |
| 1703 | #ifdef TCC_TARGET_X86_64 | 1703 | #ifdef TCC_TARGET_X86_64 |
| @@ -1708,7 +1708,7 @@ ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str) · 4 unmodified lines | |||
| 1708 | !strcmp(str, "cc") || | 1708 | !strcmp(str, "cc") || |
| 1709 | !strcmp(str, "flags")) | 1709 | !strcmp(str, "flags")) |
| 1710 | return; | 1710 | return; |
| 1711 | reg = tok_alloc_const(str); | 1711 | reg = tok_alloc_const(S, str); |
| 1712 | if (reg >= TOK_ASM_eax && reg <= TOK_ASM_edi) { | 1712 | if (reg >= TOK_ASM_eax && reg <= TOK_ASM_edi) { |
| 1713 | reg -= TOK_ASM_eax; | 1713 | reg -= TOK_ASM_eax; |
| 1714 | } else if (reg >= TOK_ASM_ax && reg <= TOK_ASM_di) { | 1714 | } else if (reg >= TOK_ASM_ax && reg <= TOK_ASM_di) { |
| @@ -1716,11 +1716,11 @@ ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str) · 1 unmodified line | |||
| 1716 | #ifdef TCC_TARGET_X86_64 | 1716 | #ifdef TCC_TARGET_X86_64 |
| 1717 | } else if (reg >= TOK_ASM_rax && reg <= TOK_ASM_rdi) { | 1717 | } else if (reg >= TOK_ASM_rax && reg <= TOK_ASM_rdi) { |
| 1718 | reg -= TOK_ASM_rax; | 1718 | reg -= TOK_ASM_rax; |
| 1719 | } else if ((reg = asm_parse_numeric_reg(reg, &type)) >= 0) { | 1719 | } else if ((reg = asm_parse_numeric_reg(S, reg, &type)) >= 0) { |
| 1720 | ; | 1720 | ; |
| 1721 | #endif | 1721 | #endif |
| 1722 | } else { | 1722 | } else { |
| 1723 | tcc_error("invalid clobber register '%s'", str); | 1723 | tcc_error(S, "invalid clobber register '%s'", str); |
| 1724 | } | 1724 | } |
| 1725 | clobber_regs[reg] = 1; | 1725 | clobber_regs[reg] = 1; |
| 1726 | } | 1726 | } |
| @@ -100,50 +100,47 @@ ST_DATA const int reg_classes[NB_REGS] = { · 99 unmodified lines | |||
| 100 | static unsigned long func_sub_sp_offset; | 100 | static unsigned long func_sub_sp_offset; |
| 101 | static int func_ret_sub; | 101 | static int func_ret_sub; |
| 102 | #ifdef CONFIG_TCC_BCHECK | 102 | #ifdef CONFIG_TCC_BCHECK |
| 103 | static addr_t func_bound_offset; | 103 | static void gen_bounds_prolog(TCCState* S); |
| 104 | static unsigned long func_bound_ind; | 104 | static void gen_bounds_epilog(TCCState* S); |
| 105 | ST_DATA int func_bound_add_epilog; | ||
| 106 | static void gen_bounds_prolog(void); | ||
| 107 | static void gen_bounds_epilog(void); | ||
| 108 | #endif | 105 | #endif |
| 109 | 106 | ||
| 110 | /* XXX: make it faster ? */ | 107 | /* XXX: make it faster ? */ |
| 111 | ST_FUNC void g(int c) | 108 | ST_FUNC void g(TCCState* S, int c) |
| 112 | { | 109 | { |
| 113 | int ind1; | 110 | int ind1; |
| 114 | if (nocode_wanted) | 111 | if (S->tccgen_nocode_wanted) |
| 115 | return; | 112 | return; |
| 116 | ind1 = ind + 1; | 113 | ind1 = S->tccgen_ind + 1; |
| 117 | if (ind1 > cur_text_section->data_allocated) | 114 | if (ind1 > cur_text_section->data_allocated) |
| 118 | section_realloc(cur_text_section, ind1); | 115 | section_realloc(S, cur_text_section, ind1); |
| 119 | cur_text_section->data[ind] = c; | 116 | cur_text_section->data[S->tccgen_ind] = c; |
| 120 | ind = ind1; | 117 | S->tccgen_ind = ind1; |
| 121 | } | 118 | } |
| 122 | 119 | ||
| 123 | ST_FUNC void o(unsigned int c) | 120 | ST_FUNC void o(TCCState* S, unsigned int c) |
| 124 | { | 121 | { |
| 125 | while (c) { | 122 | while (c) { |
| 126 | g(c); | 123 | g(S, c); |
| 127 | c = c >> 8; | 124 | c = c >> 8; |
| 128 | } | 125 | } |
| 129 | } | 126 | } |
| 130 | 127 | ||
| 131 | ST_FUNC void gen_le16(int v) | 128 | ST_FUNC void gen_le16(TCCState* S, int v) |
| 132 | { | 129 | { |
| 133 | g(v); | 130 | g(S, v); |
| 134 | g(v >> 8); | 131 | g(S, v >> 8); |
| 135 | } | 132 | } |
| 136 | 133 | ||
| 137 | ST_FUNC void gen_le32(int c) | 134 | ST_FUNC void gen_le32(TCCState* S, int c) |
| 138 | { | 135 | { |
| 139 | g(c); | 136 | g(S, c); |
| 140 | g(c >> 8); | 137 | g(S, c >> 8); |
| 141 | g(c >> 16); | 138 | g(S, c >> 16); |
| 142 | g(c >> 24); | 139 | g(S, c >> 24); |
| 143 | } | 140 | } |
| 144 | 141 | ||
| 145 | /* output a symbol and patch all calls to it */ | 142 | /* output a symbol and patch all calls to it */ |
| 146 | ST_FUNC void gsym_addr(int t, int a) | 143 | ST_FUNC void gsym_addr(TCCState* S, int t, int a) |
| 147 | { | 144 | { |
| 148 | while (t) { | 145 | while (t) { |
| 149 | unsigned char *ptr = cur_text_section->data + t; | 146 | unsigned char *ptr = cur_text_section->data + t; |
| @@ -154,73 +151,73 @@ ST_FUNC void gsym_addr(int t, int a) · 4 unmodified lines | |||
| 154 | } | 151 | } |
| 155 | 152 | ||
| 156 | /* instruction + 4 bytes data. Return the address of the data */ | 153 | /* instruction + 4 bytes data. Return the address of the data */ |
| 157 | static int oad(int c, int s) | 154 | static int oad(TCCState* S, int c, int s) |
| 158 | { | 155 | { |
| 159 | int t; | 156 | int t; |
| 160 | if (nocode_wanted) | 157 | if (S->tccgen_nocode_wanted) |
| 161 | return s; | 158 | return s; |
| 162 | o(c); | 159 | o(S, c); |
| 163 | t = ind; | 160 | t = S->tccgen_ind; |
| 164 | gen_le32(s); | 161 | gen_le32(S, s); |
| 165 | return t; | 162 | return t; |
| 166 | } | 163 | } |
| 167 | 164 | ||
| 168 | ST_FUNC void gen_fill_nops(int bytes) | 165 | ST_FUNC void gen_fill_nops(TCCState* S, int bytes) |
| 169 | { | 166 | { |
| 170 | while (bytes--) | 167 | while (bytes--) |
| 171 | g(0x90); | 168 | g(S, 0x90); |
| 172 | } | 169 | } |
| 173 | 170 | ||
| 174 | /* generate jmp to a label */ | 171 | /* generate jmp to a label */ |
| 175 | #define gjmp2(instr,lbl) oad(instr,lbl) | 172 | #define gjmp2(s, instr,lbl) oad(s, instr,lbl) |
| 176 | 173 | ||
| 177 | /* output constant with relocation if 'r & VT_SYM' is true */ | 174 | /* output constant with relocation if 'r & VT_SYM' is true */ |
| 178 | ST_FUNC void gen_addr32(int r, Sym *sym, int c) | 175 | ST_FUNC void gen_addr32(TCCState* S, int r, Sym *sym, int c) |
| 179 | { | 176 | { |
| 180 | if (r & VT_SYM) | 177 | if (r & VT_SYM) |
| 181 | greloc(cur_text_section, sym, ind, R_386_32); | 178 | greloc(S, cur_text_section, sym, S->tccgen_ind, R_386_32); |
| 182 | gen_le32(c); | 179 | gen_le32(S, c); |
| 183 | } | 180 | } |
| 184 | 181 | ||
| 185 | ST_FUNC void gen_addrpc32(int r, Sym *sym, int c) | 182 | ST_FUNC void gen_addrpc32(TCCState* S, int r, Sym *sym, int c) |
| 186 | { | 183 | { |
| 187 | if (r & VT_SYM) | 184 | if (r & VT_SYM) |
| 188 | greloc(cur_text_section, sym, ind, R_386_PC32); | 185 | greloc(S, cur_text_section, sym, S->tccgen_ind, R_386_PC32); |
| 189 | gen_le32(c - 4); | 186 | gen_le32(S, c - 4); |
| 190 | } | 187 | } |
| 191 | 188 | ||
| 192 | /* generate a modrm reference. 'op_reg' contains the additional 3 | 189 | /* generate a modrm reference. 'op_reg' contains the additional 3 |
| 193 | opcode bits */ | 190 | opcode bits */ |
| 194 | static void gen_modrm(int op_reg, int r, Sym *sym, int c) | 191 | static void gen_modrm(TCCState* S, int op_reg, int r, Sym *sym, int c) |
| 195 | { | 192 | { |
| 196 | op_reg = op_reg << 3; | 193 | op_reg = op_reg << 3; |
| 197 | if ((r & VT_VALMASK) == VT_CONST) { | 194 | if ((r & VT_VALMASK) == VT_CONST) { |
| 198 | /* constant memory reference */ | 195 | /* constant memory reference */ |
| 199 | o(0x05 | op_reg); | 196 | o(S, 0x05 | op_reg); |
| 200 | gen_addr32(r, sym, c); | 197 | gen_addr32(S, r, sym, c); |
| 201 | } else if ((r & VT_VALMASK) == VT_LOCAL) { | 198 | } else if ((r & VT_VALMASK) == VT_LOCAL) { |
| 202 | /* currently, we use only ebp as base */ | 199 | /* currently, we use only ebp as base */ |
| 203 | if (c == (char)c) { | 200 | if (c == (char)c) { |
| 204 | /* short reference */ | 201 | /* short reference */ |
| 205 | o(0x45 | op_reg); | 202 | o(S, 0x45 | op_reg); |
| 206 | g(c); | 203 | g(S, c); |
| 207 | } else { | 204 | } else { |
| 208 | oad(0x85 | op_reg, c); | 205 | oad(S, 0x85 | op_reg, c); |
| 209 | } | 206 | } |
| 210 | } else { | 207 | } else { |
| 211 | g(0x00 | op_reg | (r & VT_VALMASK)); | 208 | g(S, 0x00 | op_reg | (r & VT_VALMASK)); |
| 212 | } | 209 | } |
| 213 | } | 210 | } |
| 214 | 211 | ||
| 215 | /* load 'r' from value 'sv' */ | 212 | /* load 'r' from value 'sv' */ |
| 216 | ST_FUNC void load(int r, SValue *sv) | 213 | ST_FUNC void load(TCCState* S, int r, SValue *sv) |
| 217 | { | 214 | { |
| 218 | int v, t, ft, fc, fr; | 215 | int v, t, ft, fc, fr; |
| 219 | SValue v1; | 216 | SValue v1; |
| 220 | 217 | ||
| 221 | #ifdef TCC_TARGET_PE | 218 | #ifdef TCC_TARGET_PE |
| 222 | SValue v2; | 219 | SValue v2; |
| 223 | sv = pe_getimport(sv, &v2); | 220 | sv = pe_getimport(S, sv, &v2); |
| 224 | #endif | 221 | #endif |
| 225 | 222 | ||
| 226 | fr = sv->r; | 223 | fr = sv->r; |
| @@ -238,68 +235,68 @@ ST_FUNC void load(int r, SValue *sv) · 11 unmodified lines | |||
| 238 | v1.sym = NULL; | 235 | v1.sym = NULL; |
| 239 | fr = r; | 236 | fr = r; |
| 240 | if (!(reg_classes[fr] & RC_INT)) | 237 | if (!(reg_classes[fr] & RC_INT)) |
| 241 | fr = get_reg(RC_INT); | 238 | fr = get_reg(S, RC_INT); |
| 242 | load(fr, &v1); | 239 | load(S, fr, &v1); |
| 243 | } | 240 | } |
| 244 | if ((ft & VT_BTYPE) == VT_FLOAT) { | 241 | if ((ft & VT_BTYPE) == VT_FLOAT) { |
| 245 | o(0xd9); /* flds */ | 242 | o(S, 0xd9); /* flds */ |
| 246 | r = 0; | 243 | r = 0; |
| 247 | } else if ((ft & VT_BTYPE) == VT_DOUBLE) { | 244 | } else if ((ft & VT_BTYPE) == VT_DOUBLE) { |
| 248 | o(0xdd); /* fldl */ | 245 | o(S, 0xdd); /* fldl */ |
| 249 | r = 0; | 246 | r = 0; |
| 250 | } else if ((ft & VT_BTYPE) == VT_LDOUBLE) { | 247 | } else if ((ft & VT_BTYPE) == VT_LDOUBLE) { |
| 251 | o(0xdb); /* fldt */ | 248 | o(S, 0xdb); /* fldt */ |
| 252 | r = 5; | 249 | r = 5; |
| 253 | } else if ((ft & VT_TYPE) == VT_BYTE || (ft & VT_TYPE) == VT_BOOL) { | 250 | } else if ((ft & VT_TYPE) == VT_BYTE || (ft & VT_TYPE) == VT_BOOL) { |
| 254 | o(0xbe0f); /* movsbl */ | 251 | o(S, 0xbe0f); /* movsbl */ |
| 255 | } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) { | 252 | } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) { |
| 256 | o(0xb60f); /* movzbl */ | 253 | o(S, 0xb60f); /* movzbl */ |
| 257 | } else if ((ft & VT_TYPE) == VT_SHORT) { | 254 | } else if ((ft & VT_TYPE) == VT_SHORT) { |
| 258 | o(0xbf0f); /* movswl */ | 255 | o(S, 0xbf0f); /* movswl */ |
| 259 | } else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) { | 256 | } else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) { |
| 260 | o(0xb70f); /* movzwl */ | 257 | o(S, 0xb70f); /* movzwl */ |
| 261 | } else { | 258 | } else { |
| 262 | o(0x8b); /* movl */ | 259 | o(S, 0x8b); /* movl */ |
| 263 | } | 260 | } |
| 264 | gen_modrm(r, fr, sv->sym, fc); | 261 | gen_modrm(S, r, fr, sv->sym, fc); |
| 265 | } else { | 262 | } else { |
| 266 | if (v == VT_CONST) { | 263 | if (v == VT_CONST) { |
| 267 | o(0xb8 + r); /* mov $xx, r */ | 264 | o(S, 0xb8 + r); /* mov $xx, r */ |
| 268 | gen_addr32(fr, sv->sym, fc); | 265 | gen_addr32(S, fr, sv->sym, fc); |
| 269 | } else if (v == VT_LOCAL) { | 266 | } else if (v == VT_LOCAL) { |
| 270 | if (fc) { | 267 | if (fc) { |
| 271 | o(0x8d); /* lea xxx(%ebp), r */ | 268 | o(S, 0x8d); /* lea xxx(%ebp), r */ |
| 272 | gen_modrm(r, VT_LOCAL, sv->sym, fc); | 269 | gen_modrm(S, r, VT_LOCAL, sv->sym, fc); |
| 273 | } else { | 270 | } else { |
| 274 | o(0x89); | 271 | o(S, 0x89); |
| 275 | o(0xe8 + r); /* mov %ebp, r */ | 272 | o(S, 0xe8 + r); /* mov %ebp, r */ |
| 276 | } | 273 | } |
| 277 | } else if (v == VT_CMP) { | 274 | } else if (v == VT_CMP) { |
| 278 | o(0x0f); /* setxx %br */ | 275 | o(S, 0x0f); /* setxx %br */ |
| 279 | o(fc); | 276 | o(S, fc); |
| 280 | o(0xc0 + r); | 277 | o(S, 0xc0 + r); |
| 281 | o(0xc0b60f + r * 0x90000); /* movzbl %al, %eax */ | 278 | o(S, 0xc0b60f + r * 0x90000); /* movzbl %al, %eax */ |
| 282 | } else if (v == VT_JMP || v == VT_JMPI) { | 279 | } else if (v == VT_JMP || v == VT_JMPI) { |
| 283 | t = v & 1; | 280 | t = v & 1; |
| 284 | oad(0xb8 + r, t); /* mov $1, r */ | 281 | oad(S, 0xb8 + r, t); /* mov $1, r */ |
| 285 | o(0x05eb); /* jmp after */ | 282 | o(S, 0x05eb); /* jmp after */ |
| 286 | gsym(fc); | 283 | gsym(S, fc); |
| 287 | oad(0xb8 + r, t ^ 1); /* mov $0, r */ | 284 | oad(S, 0xb8 + r, t ^ 1); /* mov $0, r */ |
| 288 | } else if (v != r) { | 285 | } else if (v != r) { |
| 289 | o(0x89); | 286 | o(S, 0x89); |
| 290 | o(0xc0 + r + v * 8); /* mov v, r */ | 287 | o(S, 0xc0 + r + v * 8); /* mov v, r */ |
| 291 | } | 288 | } |
| 292 | } | 289 | } |
| 293 | } | 290 | } |
| 294 | 291 | ||
| 295 | /* store register 'r' in lvalue 'v' */ | 292 | /* store register 'r' in lvalue 'v' */ |
| 296 | ST_FUNC void store(int r, SValue *v) | 293 | ST_FUNC void store(TCCState* S, int r, SValue *v) |
| 297 | { | 294 | { |
| 298 | int fr, bt, ft, fc; | 295 | int fr, bt, ft, fc; |
| 299 | 296 | ||
| 300 | #ifdef TCC_TARGET_PE | 297 | #ifdef TCC_TARGET_PE |
| 301 | SValue v2; | 298 | SValue v2; |
| 302 | v = pe_getimport(v, &v2); | 299 | v = pe_getimport(S, v, &v2); |
| 303 | #endif | 300 | #endif |
| 304 | 301 | ||
| 305 | ft = v->type.t; | 302 | ft = v->type.t; |
| @@ -309,66 +306,66 @@ ST_FUNC void store(int r, SValue *v) · 3 unmodified lines | |||
| 309 | bt = ft & VT_BTYPE; | 306 | bt = ft & VT_BTYPE; |
| 310 | /* XXX: incorrect if float reg to reg */ | 307 | /* XXX: incorrect if float reg to reg */ |
| 311 | if (bt == VT_FLOAT) { | 308 | if (bt == VT_FLOAT) { |
| 312 | o(0xd9); /* fsts */ | 309 | o(S, 0xd9); /* fsts */ |
| 313 | r = 2; | 310 | r = 2; |
| 314 | } else if (bt == VT_DOUBLE) { | 311 | } else if (bt == VT_DOUBLE) { |
| 315 | o(0xdd); /* fstpl */ | 312 | o(S, 0xdd); /* fstpl */ |
| 316 | r = 2; | 313 | r = 2; |
| 317 | } else if (bt == VT_LDOUBLE) { | 314 | } else if (bt == VT_LDOUBLE) { |
| 318 | o(0xc0d9); /* fld %st(0) */ | 315 | o(S, 0xc0d9); /* fld %st(0) */ |
| 319 | o(0xdb); /* fstpt */ | 316 | o(S, 0xdb); /* fstpt */ |
| 320 | r = 7; | 317 | r = 7; |
| 321 | } else { | 318 | } else { |
| 322 | if (bt == VT_SHORT) | 319 | if (bt == VT_SHORT) |
| 323 | o(0x66); | 320 | o(S, 0x66); |
| 324 | if (bt == VT_BYTE || bt == VT_BOOL) | 321 | if (bt == VT_BYTE || bt == VT_BOOL) |
| 325 | o(0x88); | 322 | o(S, 0x88); |
| 326 | else | 323 | else |
| 327 | o(0x89); | 324 | o(S, 0x89); |
| 328 | } | 325 | } |
| 329 | if (fr == VT_CONST || | 326 | if (fr == VT_CONST || |
| 330 | fr == VT_LOCAL || | 327 | fr == VT_LOCAL || |
| 331 | (v->r & VT_LVAL)) { | 328 | (v->r & VT_LVAL)) { |
| 332 | gen_modrm(r, v->r, v->sym, fc); | 329 | gen_modrm(S, r, v->r, v->sym, fc); |
| 333 | } else if (fr != r) { | 330 | } else if (fr != r) { |
| 334 | o(0xc0 + fr + r * 8); /* mov r, fr */ | 331 | o(S, 0xc0 + fr + r * 8); /* mov r, fr */ |
| 335 | } | 332 | } |
| 336 | } | 333 | } |
| 337 | 334 | ||
| 338 | static void gadd_sp(int val) | 335 | static void gadd_sp(TCCState* S, int val) |
| 339 | { | 336 | { |
| 340 | if (val == (char)val) { | 337 | if (val == (char)val) { |
| 341 | o(0xc483); | 338 | o(S, 0xc483); |
| 342 | g(val); | 339 | g(S, val); |
| 343 | } else { | 340 | } else { |
| 344 | oad(0xc481, val); /* add $xxx, %esp */ | 341 | oad(S, 0xc481, val); /* add $xxx, %esp */ |
| 345 | } | 342 | } |
| 346 | } | 343 | } |
| 347 | 344 | ||
| 348 | #if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_PE | 345 | #if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_PE |
| 349 | static void gen_static_call(int v) | 346 | static void gen_static_call(TCCState* S, int v) |
| 350 | { | 347 | { |
| 351 | Sym *sym; | 348 | Sym *sym; |
| 352 | 349 | ||
| 353 | sym = external_helper_sym(v); | 350 | sym = external_helper_sym(S, v); |
| 354 | oad(0xe8, -4); | 351 | oad(S, 0xe8, -4); |
| 355 | greloc(cur_text_section, sym, ind-4, R_386_PC32); | 352 | greloc(S, cur_text_section, sym, S->tccgen_ind-4, R_386_PC32); |
| 356 | } | 353 | } |
| 357 | #endif | 354 | #endif |
| 358 | 355 | ||
| 359 | /* 'is_jmp' is '1' if it is a jump */ | 356 | /* 'is_jmp' is '1' if it is a jump */ |
| 360 | static void gcall_or_jmp(int is_jmp) | 357 | static void gcall_or_jmp(TCCState* S, int is_jmp) |
| 361 | { | 358 | { |
| 362 | int r; | 359 | int r; |
| 363 | if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (vtop->r & VT_SYM)) { | 360 | if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (S->tccgen_vtop->r & VT_SYM)) { |
| 364 | /* constant and relocation case */ | 361 | /* constant and relocation case */ |
| 365 | greloc(cur_text_section, vtop->sym, ind + 1, R_386_PC32); | 362 | greloc(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind + 1, R_386_PC32); |
| 366 | oad(0xe8 + is_jmp, vtop->c.i - 4); /* call/jmp im */ | 363 | oad(S, 0xe8 + is_jmp, S->tccgen_vtop->c.i - 4); /* call/jmp im */ |
| 367 | } else { | 364 | } else { |
| 368 | /* otherwise, indirect call */ | 365 | /* otherwise, indirect call */ |
| 369 | r = gv(RC_INT); | 366 | r = gv(S, RC_INT); |
| 370 | o(0xff); /* call/jmp *r */ | 367 | o(S, 0xff); /* call/jmp *r */ |
| 371 | o(0xd0 + r + (is_jmp << 4)); | 368 | o(S, 0xd0 + r + (is_jmp << 4)); |
| 372 | } | 369 | } |
| 373 | } | 370 | } |
| 374 | 371 | ||
| @@ -405,75 +402,75 @@ ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int · 30 unmodified lines | |||
| 405 | /* Generate function call. The function address is pushed first, then | 402 | /* Generate function call. The function address is pushed first, then |
| 406 | all the parameters in call order. This functions pops all the | 403 | all the parameters in call order. This functions pops all the |
| 407 | parameters and the function address. */ | 404 | parameters and the function address. */ |
| 408 | ST_FUNC void gfunc_call(int nb_args) | 405 | ST_FUNC void gfunc_call(TCCState* S, int nb_args) |
| 409 | { | 406 | { |
| 410 | int size, align, r, args_size, i, func_call; | 407 | int size, align, r, args_size, i, func_call; |
| 411 | Sym *func_sym; | 408 | Sym *func_sym; |
| 412 | 409 | ||
| 413 | #ifdef CONFIG_TCC_BCHECK | 410 | #ifdef CONFIG_TCC_BCHECK |
| 414 | if (tcc_state->do_bounds_check) | 411 | if (S->do_bounds_check) |
| 415 | gbound_args(nb_args); | 412 | gbound_args(S, nb_args); |
| 416 | #endif | 413 | #endif |
| 417 | 414 | ||
| 418 | args_size = 0; | 415 | args_size = 0; |
| 419 | for(i = 0;i < nb_args; i++) { | 416 | for(i = 0;i < nb_args; i++) { |
| 420 | if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) { | 417 | if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_STRUCT) { |
| 421 | size = type_size(&vtop->type, &align); | 418 | size = type_size(&S->tccgen_vtop->type, &align); |
| 422 | /* align to stack align size */ | 419 | /* align to stack align size */ |
| 423 | size = (size + 3) & ~3; | 420 | size = (size + 3) & ~3; |
| 424 | /* allocate the necessary size on stack */ | 421 | /* allocate the necessary size on stack */ |
| 425 | #ifdef TCC_TARGET_PE | 422 | #ifdef TCC_TARGET_PE |
| 426 | if (size >= 4096) { | 423 | if (size >= 4096) { |
| 427 | r = get_reg(RC_EAX); | 424 | r = get_reg(S, RC_EAX); |
| 428 | oad(0x68, size); // push size | 425 | oad(S, 0x68, size); // push size |
| 429 | /* cannot call normal 'alloca' with bound checking */ | 426 | /* cannot call normal 'alloca' with bound checking */ |
| 430 | gen_static_call(tok_alloc_const("__alloca")); | 427 | gen_static_call(S, tok_alloc_const(S, "__alloca")); |
| 431 | gadd_sp(4); | 428 | gadd_sp(S, 4); |
| 432 | } else | 429 | } else |
| 433 | #endif | 430 | #endif |
| 434 | { | 431 | { |
| 435 | oad(0xec81, size); /* sub $xxx, %esp */ | 432 | oad(S, 0xec81, size); /* sub $xxx, %esp */ |
| 436 | /* generate structure store */ | 433 | /* generate structure store */ |
| 437 | r = get_reg(RC_INT); | 434 | r = get_reg(S, RC_INT); |
| 438 | o(0xe089 + (r << 8)); /* mov %esp, r */ | 435 | o(S, 0xe089 + (r << 8)); /* mov %esp, r */ |
| 439 | } | 436 | } |
| 440 | vset(&vtop->type, r | VT_LVAL, 0); | 437 | vset(S, &S->tccgen_vtop->type, r | VT_LVAL, 0); |
| 441 | vswap(); | 438 | vswap(S); |
| 442 | vstore(); | 439 | vstore(S); |
| 443 | args_size += size; | 440 | args_size += size; |
| 444 | } else if (is_float(vtop->type.t)) { | 441 | } else if (is_float(S->tccgen_vtop->type.t)) { |
| 445 | gv(RC_FLOAT); /* only one float register */ | 442 | gv(S, RC_FLOAT); /* only one float register */ |
| 446 | if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) | 443 | if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_FLOAT) |
| 447 | size = 4; | 444 | size = 4; |
| 448 | else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) | 445 | else if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_DOUBLE) |
| 449 | size = 8; | 446 | size = 8; |
| 450 | else | 447 | else |
| 451 | size = 12; | 448 | size = 12; |
| 452 | oad(0xec81, size); /* sub $xxx, %esp */ | 449 | oad(S, 0xec81, size); /* sub $xxx, %esp */ |
| 453 | if (size == 12) | 450 | if (size == 12) |
| 454 | o(0x7cdb); | 451 | o(S, 0x7cdb); |
| 455 | else | 452 | else |
| 456 | o(0x5cd9 + size - 4); /* fstp[s|l] 0(%esp) */ | 453 | o(S, 0x5cd9 + size - 4); /* fstp[s|l] 0(%esp) */ |
| 457 | g(0x24); | 454 | g(S, 0x24); |
| 458 | g(0x00); | 455 | g(S, 0x00); |
| 459 | args_size += size; | 456 | args_size += size; |
| 460 | } else { | 457 | } else { |
| 461 | /* simple type (currently always same size) */ | 458 | /* simple type (currently always same size) */ |
| 462 | /* XXX: implicit cast ? */ | 459 | /* XXX: implicit cast ? */ |
| 463 | r = gv(RC_INT); | 460 | r = gv(S, RC_INT); |
| 464 | if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { | 461 | if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG) { |
| 465 | size = 8; | 462 | size = 8; |
| 466 | o(0x50 + vtop->r2); /* push r */ | 463 | o(S, 0x50 + S->tccgen_vtop->r2); /* push r */ |
| 467 | } else { | 464 | } else { |
| 468 | size = 4; | 465 | size = 4; |
| 469 | } | 466 | } |
| 470 | o(0x50 + r); /* push r */ | 467 | o(S, 0x50 + r); /* push r */ |
| 471 | args_size += size; | 468 | args_size += size; |
| 472 | } | 469 | } |
| 473 | vtop--; | 470 | S->tccgen_vtop--; |
| 474 | } | 471 | } |
| 475 | save_regs(0); /* save used temporary registers */ | 472 | save_regs(S, 0); /* save used temporary registers */ |
| 476 | func_sym = vtop->type.ref; | 473 | func_sym = S->tccgen_vtop->type.ref; |
| 477 | func_call = func_sym->f.func_call; | 474 | func_call = func_sym->f.func_call; |
| 478 | /* fast call case */ | 475 | /* fast call case */ |
| 479 | if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) || | 476 | if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) || |
| @@ -490,21 +487,21 @@ ST_FUNC void gfunc_call(int nb_args) · 10 unmodified lines | |||
| 490 | for(i = 0;i < fastcall_nb_regs; i++) { | 487 | for(i = 0;i < fastcall_nb_regs; i++) { |
| 491 | if (args_size <= 0) | 488 | if (args_size <= 0) |
| 492 | break; | 489 | break; |
| 493 | o(0x58 + fastcall_regs_ptr[i]); /* pop r */ | 490 | o(S, 0x58 + fastcall_regs_ptr[i]); /* pop r */ |
| 494 | /* XXX: incorrect for struct/floats */ | 491 | /* XXX: incorrect for struct/floats */ |
| 495 | args_size -= 4; | 492 | args_size -= 4; |
| 496 | } | 493 | } |
| 497 | } | 494 | } |
| 498 | #if !defined(TCC_TARGET_PE) && !TARGETOS_FreeBSD || TARGETOS_OpenBSD | 495 | #if !defined(TCC_TARGET_PE) && !TARGETOS_FreeBSD || TARGETOS_OpenBSD |
| 499 | else if ((vtop->type.ref->type.t & VT_BTYPE) == VT_STRUCT) | 496 | else if ((S->tccgen_vtop->type.ref->type.t & VT_BTYPE) == VT_STRUCT) |
| 500 | args_size -= 4; | 497 | args_size -= 4; |
| 501 | #endif | 498 | #endif |
| 502 | 499 | ||
| 503 | gcall_or_jmp(0); | 500 | gcall_or_jmp(S, 0); |
| 504 | 501 | ||
| 505 | if (args_size && func_call != FUNC_STDCALL && func_call != FUNC_FASTCALLW) | 502 | if (args_size && func_call != FUNC_STDCALL && func_call != FUNC_FASTCALLW) |
| 506 | gadd_sp(args_size); | 503 | gadd_sp(S, args_size); |
| 507 | vtop--; | 504 | S->tccgen_vtop--; |
| 508 | } | 505 | } |
| 509 | 506 | ||
| 510 | #ifdef TCC_TARGET_PE | 507 | #ifdef TCC_TARGET_PE |
| @@ -514,7 +511,7 @@ ST_FUNC void gfunc_call(int nb_args) · 3 unmodified lines | |||
| 514 | #endif | 511 | #endif |
| 515 | 512 | ||
| 516 | /* generate function prolog of type 't' */ | 513 | /* generate function prolog of type 't' */ |
| 517 | ST_FUNC void gfunc_prolog(Sym *func_sym) | 514 | ST_FUNC void gfunc_prolog(TCCState* S, Sym *func_sym) |
| 518 | { | 515 | { |
| 519 | CType *func_type = &func_sym->type; | 516 | CType *func_type = &func_sym->type; |
| 520 | int addr, align, size, func_call, fastcall_nb_regs; | 517 | int addr, align, size, func_call, fastcall_nb_regs; |
| @@ -526,8 +523,8 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 5 unmodified lines | |||
| 526 | sym = func_type->ref; | 523 | sym = func_type->ref; |
| 527 | func_call = sym->f.func_call; | 524 | func_call = sym->f.func_call; |
| 528 | addr = 8; | 525 | addr = 8; |
| 529 | loc = 0; | 526 | S->tccgen_loc = 0; |
| 530 | func_vc = 0; | 527 | S->tccgen_func_vc = 0; |
| 531 | 528 | ||
| 532 | if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) { | 529 | if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) { |
| 533 | fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1; | 530 | fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1; |
| @@ -541,19 +538,19 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 7 unmodified lines | |||
| 541 | } | 538 | } |
| 542 | param_index = 0; | 539 | param_index = 0; |
| 543 | 540 | ||
| 544 | ind += FUNC_PROLOG_SIZE; | 541 | S->tccgen_ind += FUNC_PROLOG_SIZE; |
| 545 | func_sub_sp_offset = ind; | 542 | func_sub_sp_offset = S->tccgen_ind; |
| 546 | /* if the function returns a structure, then add an | 543 | /* if the function returns a structure, then add an |
| 547 | implicit pointer parameter */ | 544 | implicit pointer parameter */ |
| 548 | #if defined(TCC_TARGET_PE) || TARGETOS_FreeBSD || TARGETOS_OpenBSD | 545 | #if defined(TCC_TARGET_PE) || TARGETOS_FreeBSD || TARGETOS_OpenBSD |
| 549 | size = type_size(&func_vt,&align); | 546 | size = type_size(&S->tccgen_func_vt,&align); |
| 550 | if (((func_vt.t & VT_BTYPE) == VT_STRUCT) | 547 | if (((S->tccgen_func_vt.t & VT_BTYPE) == VT_STRUCT) |
| 551 | && (size > 8 || (size & (size - 1)))) { | 548 | && (size > 8 || (size & (size - 1)))) { |
| 552 | #else | 549 | #else |
| 553 | if ((func_vt.t & VT_BTYPE) == VT_STRUCT) { | 550 | if ((S->tccgen_func_vt.t & VT_BTYPE) == VT_STRUCT) { |
| 554 | #endif | 551 | #endif |
| 555 | /* XXX: fastcall case ? */ | 552 | /* XXX: fastcall case ? */ |
| 556 | func_vc = addr; | 553 | S->tccgen_func_vc = addr; |
| 557 | addr += 4; | 554 | addr += 4; |
| 558 | param_index++; | 555 | param_index++; |
| 559 | } | 556 | } |
| @@ -570,15 +567,15 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 10 unmodified lines | |||
| 570 | #endif | 567 | #endif |
| 571 | if (param_index < fastcall_nb_regs) { | 568 | if (param_index < fastcall_nb_regs) { |
| 572 | /* save FASTCALL register */ | 569 | /* save FASTCALL register */ |
| 573 | loc -= 4; | 570 | S->tccgen_loc -= 4; |
| 574 | o(0x89); /* movl */ | 571 | o(S, 0x89); /* movl */ |
| 575 | gen_modrm(fastcall_regs_ptr[param_index], VT_LOCAL, NULL, loc); | 572 | gen_modrm(S, fastcall_regs_ptr[param_index], VT_LOCAL, NULL, S->tccgen_loc); |
| 576 | param_addr = loc; | 573 | param_addr = S->tccgen_loc; |
| 577 | } else { | 574 | } else { |
| 578 | param_addr = addr; | 575 | param_addr = addr; |
| 579 | addr += size; | 576 | addr += size; |
| 580 | } | 577 | } |
| 581 | sym_push(sym->v & ~SYM_FIELD, type, | 578 | sym_push(S, sym->v & ~SYM_FIELD, type, |
| 582 | VT_LOCAL | VT_LVAL, param_addr); | 579 | VT_LOCAL | VT_LVAL, param_addr); |
| 583 | param_index++; | 580 | param_index++; |
| 584 | } | 581 | } |
| @@ -587,94 +584,94 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 2 unmodified lines | |||
| 587 | if (func_call == FUNC_STDCALL || func_call == FUNC_FASTCALLW) | 584 | if (func_call == FUNC_STDCALL || func_call == FUNC_FASTCALLW) |
| 588 | func_ret_sub = addr - 8; | 585 | func_ret_sub = addr - 8; |
| 589 | #if !defined(TCC_TARGET_PE) && !TARGETOS_FreeBSD || TARGETOS_OpenBSD | 586 | #if !defined(TCC_TARGET_PE) && !TARGETOS_FreeBSD || TARGETOS_OpenBSD |
| 590 | else if (func_vc) | 587 | else if (S->tccgen_func_vc) |
| 591 | func_ret_sub = 4; | 588 | func_ret_sub = 4; |
| 592 | #endif | 589 | #endif |
| 593 | 590 | ||
| 594 | #ifdef CONFIG_TCC_BCHECK | 591 | #ifdef CONFIG_TCC_BCHECK |
| 595 | if (tcc_state->do_bounds_check) | 592 | if (S->do_bounds_check) |
| 596 | gen_bounds_prolog(); | 593 | gen_bounds_prolog(S); |
| 597 | #endif | 594 | #endif |
| 598 | } | 595 | } |
| 599 | 596 | ||
| 600 | /* generate function epilog */ | 597 | /* generate function epilog */ |
| 601 | ST_FUNC void gfunc_epilog(void) | 598 | ST_FUNC void gfunc_epilog(TCCState* S) |
| 602 | { | 599 | { |
| 603 | addr_t v, saved_ind; | 600 | addr_t v, saved_ind; |
| 604 | 601 | ||
| 605 | #ifdef CONFIG_TCC_BCHECK | 602 | #ifdef CONFIG_TCC_BCHECK |
| 606 | if (tcc_state->do_bounds_check) | 603 | if (S->do_bounds_check) |
| 607 | gen_bounds_epilog(); | 604 | gen_bounds_epilog(S); |
| 608 | #endif | 605 | #endif |
| 609 | 606 | ||
| 610 | /* align local size to word & save local variables */ | 607 | /* align local size to word & save local variables */ |
| 611 | v = (-loc + 3) & -4; | 608 | v = (-S->tccgen_loc + 3) & -4; |
| 612 | 609 | ||
| 613 | #if USE_EBX | 610 | #if USE_EBX |
| 614 | o(0x8b); | 611 | o(S, 0x8b); |
| 615 | gen_modrm(TREG_EBX, VT_LOCAL, NULL, -(v+4)); | 612 | gen_modrm(S, TREG_EBX, VT_LOCAL, NULL, -(v+4)); |
| 616 | #endif | 613 | #endif |
| 617 | 614 | ||
| 618 | o(0xc9); /* leave */ | 615 | o(S, 0xc9); /* leave */ |
| 619 | if (func_ret_sub == 0) { | 616 | if (func_ret_sub == 0) { |
| 620 | o(0xc3); /* ret */ | 617 | o(S, 0xc3); /* ret */ |
| 621 | } else { | 618 | } else { |
| 622 | o(0xc2); /* ret n */ | 619 | o(S, 0xc2); /* ret n */ |
| 623 | g(func_ret_sub); | 620 | g(S, func_ret_sub); |
| 624 | g(func_ret_sub >> 8); | 621 | g(S, func_ret_sub >> 8); |
| 625 | } | 622 | } |
| 626 | saved_ind = ind; | 623 | saved_ind = S->tccgen_ind; |
| 627 | ind = func_sub_sp_offset - FUNC_PROLOG_SIZE; | 624 | S->tccgen_ind = func_sub_sp_offset - FUNC_PROLOG_SIZE; |
| 628 | #ifdef TCC_TARGET_PE | 625 | #ifdef TCC_TARGET_PE |
| 629 | if (v >= 4096) { | 626 | if (v >= 4096) { |
| 630 | oad(0xb8, v); /* mov stacksize, %eax */ | 627 | oad(S, 0xb8, v); /* mov stacksize, %eax */ |
| 631 | gen_static_call(TOK___chkstk); /* call __chkstk, (does the stackframe too) */ | 628 | gen_static_call(S, TOK___chkstk); /* call __chkstk, (does the stackframe too) */ |
| 632 | } else | 629 | } else |
| 633 | #endif | 630 | #endif |
| 634 | { | 631 | { |
| 635 | o(0xe58955); /* push %ebp, mov %esp, %ebp */ | 632 | o(S, 0xe58955); /* push %ebp, mov %esp, %ebp */ |
| 636 | o(0xec81); /* sub esp, stacksize */ | 633 | o(S, 0xec81); /* sub esp, stacksize */ |
| 637 | gen_le32(v); | 634 | gen_le32(S, v); |
| 638 | #ifdef TCC_TARGET_PE | 635 | #ifdef TCC_TARGET_PE |
| 639 | o(0x90); /* adjust to FUNC_PROLOG_SIZE */ | 636 | o(S, 0x90); /* adjust to FUNC_PROLOG_SIZE */ |
| 640 | #endif | 637 | #endif |
| 641 | } | 638 | } |
| 642 | o(0x53 * USE_EBX); /* push ebx */ | 639 | o(S, 0x53 * USE_EBX); /* push ebx */ |
| 643 | ind = saved_ind; | 640 | S->tccgen_ind = saved_ind; |
| 644 | } | 641 | } |
| 645 | 642 | ||
| 646 | /* generate a jump to a label */ | 643 | /* generate a jump to a label */ |
| 647 | ST_FUNC int gjmp(int t) | 644 | ST_FUNC int gjmp(TCCState* S, int t) |
| 648 | { | 645 | { |
| 649 | return gjmp2(0xe9, t); | 646 | return gjmp2(S, 0xe9, t); |
| 650 | } | 647 | } |
| 651 | 648 | ||
| 652 | /* generate a jump to a fixed address */ | 649 | /* generate a jump to a fixed address */ |
| 653 | ST_FUNC void gjmp_addr(int a) | 650 | ST_FUNC void gjmp_addr(TCCState* S, int a) |
| 654 | { | 651 | { |
| 655 | int r; | 652 | int r; |
| 656 | r = a - ind - 2; | 653 | r = a - S->tccgen_ind - 2; |
| 657 | if (r == (char)r) { | 654 | if (r == (char)r) { |
| 658 | g(0xeb); | 655 | g(S, 0xeb); |
| 659 | g(r); | 656 | g(S, r); |
| 660 | } else { | 657 | } else { |
| 661 | oad(0xe9, a - ind - 5); | 658 | oad(S, 0xe9, a - S->tccgen_ind - 5); |
| 662 | } | 659 | } |
| 663 | } | 660 | } |
| 664 | 661 | ||
| 665 | #if 0 | 662 | #if 0 |
| 666 | /* generate a jump to a fixed address */ | 663 | /* generate a jump to a fixed address */ |
| 667 | ST_FUNC void gjmp_cond_addr(int a, int op) | 664 | ST_FUNC void gjmp_cond_addr(TCCState* S, int a, int op) |
| 668 | { | 665 | { |
| 669 | int r = a - ind - 2; | 666 | int r = a - S->tccgen_ind - 2; |
| 670 | if (r == (char)r) | 667 | if (r == (char)r) |
| 671 | g(op - 32), g(r); | 668 | g(S, op - 32), g(r); |
| 672 | else | 669 | else |
| 673 | g(0x0f), gjmp2(op - 16, r - 4); | 670 | g(S, 0x0f), gjmp2(S, op - 16, r - 4); |
| 674 | } | 671 | } |
| 675 | #endif | 672 | #endif |
| 676 | 673 | ||
| 677 | ST_FUNC int gjmp_append(int n, int t) | 674 | ST_FUNC int gjmp_append(TCCState* S, int n, int t) |
| 678 | { | 675 | { |
| 679 | void *p; | 676 | void *p; |
| 680 | /* insert vtop->c jump list in t */ | 677 | /* insert vtop->c jump list in t */ |
| @@ -688,14 +685,14 @@ ST_FUNC int gjmp_append(int n, int t) · 7 unmodified lines | |||
| 688 | return t; | 685 | return t; |
| 689 | } | 686 | } |
| 690 | 687 | ||
| 691 | ST_FUNC int gjmp_cond(int op, int t) | 688 | ST_FUNC int gjmp_cond(TCCState* S, int op, int t) |
| 692 | { | 689 | { |
| 693 | g(0x0f); | 690 | g(S, 0x0f); |
| 694 | t = gjmp2(op - 16, t); | 691 | t = gjmp2(S, op - 16, t); |
| 695 | return t; | 692 | return t; |
| 696 | } | 693 | } |
| 697 | 694 | ||
| 698 | ST_FUNC void gen_opi(int op) | 695 | ST_FUNC void gen_opi(TCCState* S, int op) |
| 699 | { | 696 | { |
| 700 | int r, fr, opc, c; | 697 | int r, fr, opc, c; |
| 701 | 698 | ||
| @@ -704,36 +701,36 @@ ST_FUNC void gen_opi(int op) · 2 unmodified lines | |||
| 704 | case TOK_ADDC1: /* add with carry generation */ | 701 | case TOK_ADDC1: /* add with carry generation */ |
| 705 | opc = 0; | 702 | opc = 0; |
| 706 | gen_op8: | 703 | gen_op8: |
| 707 | if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { | 704 | if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { |
| 708 | /* constant case */ | 705 | /* constant case */ |
| 709 | vswap(); | 706 | vswap(S); |
| 710 | r = gv(RC_INT); | 707 | r = gv(S, RC_INT); |
| 711 | vswap(); | 708 | vswap(S); |
| 712 | c = vtop->c.i; | 709 | c = S->tccgen_vtop->c.i; |
| 713 | if (c == (char)c) { | 710 | if (c == (char)c) { |
| 714 | /* generate inc and dec for smaller code */ | 711 | /* generate inc and dec for smaller code */ |
| 715 | if ((c == 1 || c == -1) && (op == '+' || op == '-')) { | 712 | if ((c == 1 || c == -1) && (op == '+' || op == '-')) { |
| 716 | opc = (c == 1) ^ (op == '+'); | 713 | opc = (c == 1) ^ (op == '+'); |
| 717 | o (0x40 | (opc << 3) | r); // inc,dec | 714 | o(S, 0x40 | (opc << 3) | r); // inc,dec |
| 718 | } else { | 715 | } else { |
| 719 | o(0x83); | 716 | o(S, 0x83); |
| 720 | o(0xc0 | (opc << 3) | r); | 717 | o(S, 0xc0 | (opc << 3) | r); |
| 721 | g(c); | 718 | g(S, c); |
| 722 | } | 719 | } |
| 723 | } else { | 720 | } else { |
| 724 | o(0x81); | 721 | o(S, 0x81); |
| 725 | oad(0xc0 | (opc << 3) | r, c); | 722 | oad(S, 0xc0 | (opc << 3) | r, c); |
| 726 | } | 723 | } |
| 727 | } else { | 724 | } else { |
| 728 | gv2(RC_INT, RC_INT); | 725 | gv2(S, RC_INT, RC_INT); |
| 729 | r = vtop[-1].r; | 726 | r = S->tccgen_vtop[-1].r; |
| 730 | fr = vtop[0].r; | 727 | fr = S->tccgen_vtop[0].r; |
| 731 | o((opc << 3) | 0x01); | 728 | o(S, (opc << 3) | 0x01); |
| 732 | o(0xc0 + r + fr * 8); | 729 | o(S, 0xc0 + r + fr * 8); |
| 733 | } | 730 | } |
| 734 | vtop--; | 731 | S->tccgen_vtop--; |
| 735 | if (op >= TOK_ULT && op <= TOK_GT) | 732 | if (op >= TOK_ULT && op <= TOK_GT) |
| 736 | vset_VT_CMP(op); | 733 | vset_VT_CMP(S, op); |
| 737 | break; | 734 | break; |
| 738 | case '-': | 735 | case '-': |
| 739 | case TOK_SUBC1: /* sub with carry generation */ | 736 | case TOK_SUBC1: /* sub with carry generation */ |
| @@ -755,12 +752,12 @@ ST_FUNC void gen_opi(int op) · 15 unmodified lines | |||
| 755 | opc = 1; | 752 | opc = 1; |
| 756 | goto gen_op8; | 753 | goto gen_op8; |
| 757 | case '*': | 754 | case '*': |
| 758 | gv2(RC_INT, RC_INT); | 755 | gv2(S, RC_INT, RC_INT); |
| 759 | r = vtop[-1].r; | 756 | r = S->tccgen_vtop[-1].r; |
| 760 | fr = vtop[0].r; | 757 | fr = S->tccgen_vtop[0].r; |
| 761 | vtop--; | 758 | S->tccgen_vtop--; |
| 762 | o(0xaf0f); /* imul fr, r */ | 759 | o(S, 0xaf0f); /* imul fr, r */ |
| 763 | o(0xc0 + fr + r * 8); | 760 | o(S, 0xc0 + fr + r * 8); |
| 764 | break; | 761 | break; |
| 765 | case TOK_SHL: | 762 | case TOK_SHL: |
| 766 | opc = 4; | 763 | opc = 4; |
| @@ -772,23 +769,23 @@ ST_FUNC void gen_opi(int op) · 5 unmodified lines | |||
| 772 | opc = 7; | 769 | opc = 7; |
| 773 | gen_shift: | 770 | gen_shift: |
| 774 | opc = 0xc0 | (opc << 3); | 771 | opc = 0xc0 | (opc << 3); |
| 775 | if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { | 772 | if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { |
| 776 | /* constant case */ | 773 | /* constant case */ |
| 777 | vswap(); | 774 | vswap(S); |
| 778 | r = gv(RC_INT); | 775 | r = gv(S, RC_INT); |
| 779 | vswap(); | 776 | vswap(S); |
| 780 | c = vtop->c.i & 0x1f; | 777 | c = S->tccgen_vtop->c.i & 0x1f; |
| 781 | o(0xc1); /* shl/shr/sar $xxx, r */ | 778 | o(S, 0xc1); /* shl/shr/sar $xxx, r */ |
| 782 | o(opc | r); | 779 | o(S, opc | r); |
| 783 | g(c); | 780 | g(S, c); |
| 784 | } else { | 781 | } else { |
| 785 | /* we generate the shift in ecx */ | 782 | /* we generate the shift in ecx */ |
| 786 | gv2(RC_INT, RC_ECX); | 783 | gv2(S, RC_INT, RC_ECX); |
| 787 | r = vtop[-1].r; | 784 | r = S->tccgen_vtop[-1].r; |
| 788 | o(0xd3); /* shl/shr/sar %cl, r */ | 785 | o(S, 0xd3); /* shl/shr/sar %cl, r */ |
| 789 | o(opc | r); | 786 | o(S, opc | r); |
| 790 | } | 787 | } |
| 791 | vtop--; | 788 | S->tccgen_vtop--; |
| 792 | break; | 789 | break; |
| 793 | case '/': | 790 | case '/': |
| 794 | case TOK_UDIV: | 791 | case TOK_UDIV: |
| @@ -798,32 +795,32 @@ ST_FUNC void gen_opi(int op) · 3 unmodified lines | |||
| 798 | case TOK_UMULL: | 795 | case TOK_UMULL: |
| 799 | /* first operand must be in eax */ | 796 | /* first operand must be in eax */ |
| 800 | /* XXX: need better constraint for second operand */ | 797 | /* XXX: need better constraint for second operand */ |
| 801 | gv2(RC_EAX, RC_ECX); | 798 | gv2(S, RC_EAX, RC_ECX); |
| 802 | r = vtop[-1].r; | 799 | r = S->tccgen_vtop[-1].r; |
| 803 | fr = vtop[0].r; | 800 | fr = S->tccgen_vtop[0].r; |
| 804 | vtop--; | 801 | S->tccgen_vtop--; |
| 805 | save_reg(TREG_EDX); | 802 | save_reg(S, TREG_EDX); |
| 806 | /* save EAX too if used otherwise */ | 803 | /* save EAX too if used otherwise */ |
| 807 | save_reg_upstack(TREG_EAX, 1); | 804 | save_reg_upstack(S, TREG_EAX, 1); |
| 808 | if (op == TOK_UMULL) { | 805 | if (op == TOK_UMULL) { |
| 809 | o(0xf7); /* mul fr */ | 806 | o(S, 0xf7); /* mul fr */ |
| 810 | o(0xe0 + fr); | 807 | o(S, 0xe0 + fr); |
| 811 | vtop->r2 = TREG_EDX; | 808 | S->tccgen_vtop->r2 = TREG_EDX; |
| 812 | r = TREG_EAX; | 809 | r = TREG_EAX; |
| 813 | } else { | 810 | } else { |
| 814 | if (op == TOK_UDIV || op == TOK_UMOD) { | 811 | if (op == TOK_UDIV || op == TOK_UMOD) { |
| 815 | o(0xf7d231); /* xor %edx, %edx, div fr, %eax */ | 812 | o(S, 0xf7d231); /* xor %edx, %edx, div fr, %eax */ |
| 816 | o(0xf0 + fr); | 813 | o(S, 0xf0 + fr); |
| 817 | } else { | 814 | } else { |
| 818 | o(0xf799); /* cltd, idiv fr, %eax */ | 815 | o(S, 0xf799); /* cltd, idiv fr, %eax */ |
| 819 | o(0xf8 + fr); | 816 | o(S, 0xf8 + fr); |
| 820 | } | 817 | } |
| 821 | if (op == '%' || op == TOK_UMOD) | 818 | if (op == '%' || op == TOK_UMOD) |
| 822 | r = TREG_EDX; | 819 | r = TREG_EDX; |
| 823 | else | 820 | else |
| 824 | r = TREG_EAX; | 821 | r = TREG_EAX; |
| 825 | } | 822 | } |
| 826 | vtop->r = r; | 823 | S->tccgen_vtop->r = r; |
| 827 | break; | 824 | break; |
| 828 | default: | 825 | default: |
| 829 | opc = 7; | 826 | opc = 7; |
| @@ -834,74 +831,74 @@ ST_FUNC void gen_opi(int op) · 4 unmodified lines | |||
| 834 | /* generate a floating point operation 'v = t1 op t2' instruction. The | 831 | /* generate a floating point operation 'v = t1 op t2' instruction. The |
| 835 | two operands are guaranteed to have the same floating point type */ | 832 | two operands are guaranteed to have the same floating point type */ |
| 836 | /* XXX: need to use ST1 too */ | 833 | /* XXX: need to use ST1 too */ |
| 837 | ST_FUNC void gen_opf(int op) | 834 | ST_FUNC void gen_opf(TCCState* S, int op) |
| 838 | { | 835 | { |
| 839 | int a, ft, fc, swapped, r; | 836 | int a, ft, fc, swapped, r; |
| 840 | 837 | ||
| 841 | if (op == TOK_NEG) { /* unary minus */ | 838 | if (op == TOK_NEG) { /* unary minus */ |
| 842 | gv(RC_FLOAT); | 839 | gv(S, RC_FLOAT); |
| 843 | o(0xe0d9); /* fchs */ | 840 | o(S, 0xe0d9); /* fchs */ |
| 844 | return; | 841 | return; |
| 845 | } | 842 | } |
| 846 | 843 | ||
| 847 | /* convert constants to memory references */ | 844 | /* convert constants to memory references */ |
| 848 | if ((vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { | 845 | if ((S->tccgen_vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { |
| 849 | vswap(); | 846 | vswap(S); |
| 850 | gv(RC_FLOAT); | 847 | gv(S, RC_FLOAT); |
| 851 | vswap(); | 848 | vswap(S); |
| 852 | } | 849 | } |
| 853 | if ((vtop[0].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) | 850 | if ((S->tccgen_vtop[0].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) |
| 854 | gv(RC_FLOAT); | 851 | gv(S, RC_FLOAT); |
| 855 | 852 | ||
| 856 | /* must put at least one value in the floating point register */ | 853 | /* must put at least one value in the floating point register */ |
| 857 | if ((vtop[-1].r & VT_LVAL) && | 854 | if ((S->tccgen_vtop[-1].r & VT_LVAL) && |
| 858 | (vtop[0].r & VT_LVAL)) { | 855 | (S->tccgen_vtop[0].r & VT_LVAL)) { |
| 859 | vswap(); | 856 | vswap(S); |
| 860 | gv(RC_FLOAT); | 857 | gv(S, RC_FLOAT); |
| 861 | vswap(); | 858 | vswap(S); |
| 862 | } | 859 | } |
| 863 | swapped = 0; | 860 | swapped = 0; |
| 864 | /* swap the stack if needed so that t1 is the register and t2 is | 861 | /* swap the stack if needed so that t1 is the register and t2 is |
| 865 | the memory reference */ | 862 | the memory reference */ |
| 866 | if (vtop[-1].r & VT_LVAL) { | 863 | if (S->tccgen_vtop[-1].r & VT_LVAL) { |
| 867 | vswap(); | 864 | vswap(S); |
| 868 | swapped = 1; | 865 | swapped = 1; |
| 869 | } | 866 | } |
| 870 | if (op >= TOK_ULT && op <= TOK_GT) { | 867 | if (op >= TOK_ULT && op <= TOK_GT) { |
| 871 | /* load on stack second operand */ | 868 | /* load on stack second operand */ |
| 872 | load(TREG_ST0, vtop); | 869 | load(S, TREG_ST0, S->tccgen_vtop); |
| 873 | save_reg(TREG_EAX); /* eax is used by FP comparison code */ | 870 | save_reg(S, TREG_EAX); /* eax is used by FP comparison code */ |
| 874 | if (op == TOK_GE || op == TOK_GT) | 871 | if (op == TOK_GE || op == TOK_GT) |
| 875 | swapped = !swapped; | 872 | swapped = !swapped; |
| 876 | else if (op == TOK_EQ || op == TOK_NE) | 873 | else if (op == TOK_EQ || op == TOK_NE) |
| 877 | swapped = 0; | 874 | swapped = 0; |
| 878 | if (swapped) | 875 | if (swapped) |
| 879 | o(0xc9d9); /* fxch %st(1) */ | 876 | o(S, 0xc9d9); /* fxch %st(1) */ |
| 880 | if (op == TOK_EQ || op == TOK_NE) | 877 | if (op == TOK_EQ || op == TOK_NE) |
| 881 | o(0xe9da); /* fucompp */ | 878 | o(S, 0xe9da); /* fucompp */ |
| 882 | else | 879 | else |
| 883 | o(0xd9de); /* fcompp */ | 880 | o(S, 0xd9de); /* fcompp */ |
| 884 | o(0xe0df); /* fnstsw %ax */ | 881 | o(S, 0xe0df); /* fnstsw %ax */ |
| 885 | if (op == TOK_EQ) { | 882 | if (op == TOK_EQ) { |
| 886 | o(0x45e480); /* and $0x45, %ah */ | 883 | o(S, 0x45e480); /* and $0x45, %ah */ |
| 887 | o(0x40fC80); /* cmp $0x40, %ah */ | 884 | o(S, 0x40fC80); /* cmp $0x40, %ah */ |
| 888 | } else if (op == TOK_NE) { | 885 | } else if (op == TOK_NE) { |
| 889 | o(0x45e480); /* and $0x45, %ah */ | 886 | o(S, 0x45e480); /* and $0x45, %ah */ |
| 890 | o(0x40f480); /* xor $0x40, %ah */ | 887 | o(S, 0x40f480); /* xor $0x40, %ah */ |
| 891 | op = TOK_NE; | 888 | op = TOK_NE; |
| 892 | } else if (op == TOK_GE || op == TOK_LE) { | 889 | } else if (op == TOK_GE || op == TOK_LE) { |
| 893 | o(0x05c4f6); /* test $0x05, %ah */ | 890 | o(S, 0x05c4f6); /* test $0x05, %ah */ |
| 894 | op = TOK_EQ; | 891 | op = TOK_EQ; |
| 895 | } else { | 892 | } else { |
| 896 | o(0x45c4f6); /* test $0x45, %ah */ | 893 | o(S, 0x45c4f6); /* test $0x45, %ah */ |
| 897 | op = TOK_EQ; | 894 | op = TOK_EQ; |
| 898 | } | 895 | } |
| 899 | vtop--; | 896 | S->tccgen_vtop--; |
| 900 | vset_VT_CMP(op); | 897 | vset_VT_CMP(S, op); |
| 901 | } else { | 898 | } else { |
| 902 | /* no memory reference possible for long double operations */ | 899 | /* no memory reference possible for long double operations */ |
| 903 | if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { | 900 | if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { |
| 904 | load(TREG_ST0, vtop); | 901 | load(S, TREG_ST0, S->tccgen_vtop); |
| 905 | swapped = !swapped; | 902 | swapped = !swapped; |
| 906 | } | 903 | } |
| 907 | 904 | ||
| @@ -924,213 +921,213 @@ ST_FUNC void gen_opf(int op) · 16 unmodified lines | |||
| 924 | a++; | 921 | a++; |
| 925 | break; | 922 | break; |
| 926 | } | 923 | } |
| 927 | ft = vtop->type.t; | 924 | ft = S->tccgen_vtop->type.t; |
| 928 | fc = vtop->c.i; | 925 | fc = S->tccgen_vtop->c.i; |
| 929 | if ((ft & VT_BTYPE) == VT_LDOUBLE) { | 926 | if ((ft & VT_BTYPE) == VT_LDOUBLE) { |
| 930 | o(0xde); /* fxxxp %st, %st(1) */ | 927 | o(S, 0xde); /* fxxxp %st, %st(1) */ |
| 931 | o(0xc1 + (a << 3)); | 928 | o(S, 0xc1 + (a << 3)); |
| 932 | } else { | 929 | } else { |
| 933 | /* if saved lvalue, then we must reload it */ | 930 | /* if saved lvalue, then we must reload it */ |
| 934 | r = vtop->r; | 931 | r = S->tccgen_vtop->r; |
| 935 | if ((r & VT_VALMASK) == VT_LLOCAL) { | 932 | if ((r & VT_VALMASK) == VT_LLOCAL) { |
| 936 | SValue v1; | 933 | SValue v1; |
| 937 | r = get_reg(RC_INT); | 934 | r = get_reg(S, RC_INT); |
| 938 | v1.type.t = VT_INT; | 935 | v1.type.t = VT_INT; |
| 939 | v1.r = VT_LOCAL | VT_LVAL; | 936 | v1.r = VT_LOCAL | VT_LVAL; |
| 940 | v1.c.i = fc; | 937 | v1.c.i = fc; |
| 941 | v1.sym = NULL; | 938 | v1.sym = NULL; |
| 942 | load(r, &v1); | 939 | load(S, r, &v1); |
| 943 | fc = 0; | 940 | fc = 0; |
| 944 | } | 941 | } |
| 945 | 942 | ||
| 946 | if ((ft & VT_BTYPE) == VT_DOUBLE) | 943 | if ((ft & VT_BTYPE) == VT_DOUBLE) |
| 947 | o(0xdc); | 944 | o(S, 0xdc); |
| 948 | else | 945 | else |
| 949 | o(0xd8); | 946 | o(S, 0xd8); |
| 950 | gen_modrm(a, r, vtop->sym, fc); | 947 | gen_modrm(S, a, r, S->tccgen_vtop->sym, fc); |
| 951 | } | 948 | } |
| 952 | vtop--; | 949 | S->tccgen_vtop--; |
| 953 | } | 950 | } |
| 954 | } | 951 | } |
| 955 | 952 | ||
| 956 | /* convert integers to fp 't' type. Must handle 'int', 'unsigned int' | 953 | /* convert integers to fp 't' type. Must handle 'int', 'unsigned int' |
| 957 | and 'long long' cases. */ | 954 | and 'long long' cases. */ |
| 958 | ST_FUNC void gen_cvt_itof(int t) | 955 | ST_FUNC void gen_cvt_itof(TCCState* S, int t) |
| 959 | { | 956 | { |
| 960 | save_reg(TREG_ST0); | 957 | save_reg(S, TREG_ST0); |
| 961 | gv(RC_INT); | 958 | gv(S, RC_INT); |
| 962 | if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { | 959 | if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG) { |
| 963 | /* signed long long to float/double/long double (unsigned case | 960 | /* signed long long to float/double/long double (unsigned case |
| 964 | is handled generically) */ | 961 | is handled generically) */ |
| 965 | o(0x50 + vtop->r2); /* push r2 */ | 962 | o(S, 0x50 + S->tccgen_vtop->r2); /* push r2 */ |
| 966 | o(0x50 + (vtop->r & VT_VALMASK)); /* push r */ | 963 | o(S, 0x50 + (S->tccgen_vtop->r & VT_VALMASK)); /* push r */ |
| 967 | o(0x242cdf); /* fildll (%esp) */ | 964 | o(S, 0x242cdf); /* fildll (%esp) */ |
| 968 | o(0x08c483); /* add $8, %esp */ | 965 | o(S, 0x08c483); /* add $8, %esp */ |
| 969 | vtop->r2 = VT_CONST; | 966 | S->tccgen_vtop->r2 = VT_CONST; |
| 970 | } else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == | 967 | } else if ((S->tccgen_vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == |
| 971 | (VT_INT | VT_UNSIGNED)) { | 968 | (VT_INT | VT_UNSIGNED)) { |
| 972 | /* unsigned int to float/double/long double */ | 969 | /* unsigned int to float/double/long double */ |
| 973 | o(0x6a); /* push $0 */ | 970 | o(S, 0x6a); /* push $0 */ |
| 974 | g(0x00); | 971 | g(S, 0x00); |
| 975 | o(0x50 + (vtop->r & VT_VALMASK)); /* push r */ | 972 | o(S, 0x50 + (S->tccgen_vtop->r & VT_VALMASK)); /* push r */ |
| 976 | o(0x242cdf); /* fildll (%esp) */ | 973 | o(S, 0x242cdf); /* fildll (%esp) */ |
| 977 | o(0x08c483); /* add $8, %esp */ | 974 | o(S, 0x08c483); /* add $8, %esp */ |
| 978 | } else { | 975 | } else { |
| 979 | /* int to float/double/long double */ | 976 | /* int to float/double/long double */ |
| 980 | o(0x50 + (vtop->r & VT_VALMASK)); /* push r */ | 977 | o(S, 0x50 + (S->tccgen_vtop->r & VT_VALMASK)); /* push r */ |
| 981 | o(0x2404db); /* fildl (%esp) */ | 978 | o(S, 0x2404db); /* fildl (%esp) */ |
| 982 | o(0x04c483); /* add $4, %esp */ | 979 | o(S, 0x04c483); /* add $4, %esp */ |
| 983 | } | 980 | } |
| 984 | vtop->r2 = VT_CONST; | 981 | S->tccgen_vtop->r2 = VT_CONST; |
| 985 | vtop->r = TREG_ST0; | 982 | S->tccgen_vtop->r = TREG_ST0; |
| 986 | } | 983 | } |
| 987 | 984 | ||
| 988 | /* convert fp to int 't' type */ | 985 | /* convert fp to int 't' type */ |
| 989 | ST_FUNC void gen_cvt_ftoi(int t) | 986 | ST_FUNC void gen_cvt_ftoi(TCCState* S, int t) |
| 990 | { | 987 | { |
| 991 | int bt = vtop->type.t & VT_BTYPE; | 988 | int bt = S->tccgen_vtop->type.t & VT_BTYPE; |
| 992 | if (bt == VT_FLOAT) | 989 | if (bt == VT_FLOAT) |
| 993 | vpush_helper_func(TOK___fixsfdi); | 990 | vpush_helper_func(S, TOK___fixsfdi); |
| 994 | else if (bt == VT_LDOUBLE) | 991 | else if (bt == VT_LDOUBLE) |
| 995 | vpush_helper_func(TOK___fixxfdi); | 992 | vpush_helper_func(S, TOK___fixxfdi); |
| 996 | else | 993 | else |
| 997 | vpush_helper_func(TOK___fixdfdi); | 994 | vpush_helper_func(S, TOK___fixdfdi); |
| 998 | vswap(); | 995 | vswap(S); |
| 999 | gfunc_call(1); | 996 | gfunc_call(S, 1); |
| 1000 | vpushi(0); | 997 | vpushi(S, 0); |
| 1001 | vtop->r = REG_IRET; | 998 | S->tccgen_vtop->r = REG_IRET; |
| 1002 | if ((t & VT_BTYPE) == VT_LLONG) | 999 | if ((t & VT_BTYPE) == VT_LLONG) |
| 1003 | vtop->r2 = REG_IRE2; | 1000 | S->tccgen_vtop->r2 = REG_IRE2; |
| 1004 | } | 1001 | } |
| 1005 | 1002 | ||
| 1006 | /* convert from one floating point type to another */ | 1003 | /* convert from one floating point type to another */ |
| 1007 | ST_FUNC void gen_cvt_ftof(int t) | 1004 | ST_FUNC void gen_cvt_ftof(TCCState* S, int t) |
| 1008 | { | 1005 | { |
| 1009 | /* all we have to do on i386 is to put the float in a register */ | 1006 | /* all we have to do on i386 is to put the float in a register */ |
| 1010 | gv(RC_FLOAT); | 1007 | gv(S, RC_FLOAT); |
| 1011 | } | 1008 | } |
| 1012 | 1009 | ||
| 1013 | /* char/short to int conversion */ | 1010 | /* char/short to int conversion */ |
| 1014 | ST_FUNC void gen_cvt_csti(int t) | 1011 | ST_FUNC void gen_cvt_csti(TCCState* S, int t) |
| 1015 | { | 1012 | { |
| 1016 | int r, sz, xl; | 1013 | int r, sz, xl; |
| 1017 | r = gv(RC_INT); | 1014 | r = gv(S, RC_INT); |
| 1018 | sz = !(t & VT_UNSIGNED); | 1015 | sz = !(t & VT_UNSIGNED); |
| 1019 | xl = (t & VT_BTYPE) == VT_SHORT; | 1016 | xl = (t & VT_BTYPE) == VT_SHORT; |
| 1020 | o(0xc0b60f /* mov[sz] %a[xl], %eax */ | 1017 | o(S, 0xc0b60f /* mov[sz] %a[xl], %eax */ |
| 1021 | | (sz << 3 | xl) << 8 | 1018 | | (sz << 3 | xl) << 8 |
| 1022 | | (r << 3 | r) << 16 | 1019 | | (r << 3 | r) << 16 |
| 1023 | ); | 1020 | ); |
| 1024 | } | 1021 | } |
| 1025 | 1022 | ||
| 1026 | /* increment tcov counter */ | 1023 | /* increment tcov counter */ |
| 1027 | ST_FUNC void gen_increment_tcov (SValue *sv) | 1024 | ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv) |
| 1028 | { | 1025 | { |
| 1029 | o(0x0583); /* addl $1, xxx */ | 1026 | o(S, 0x0583); /* addl $1, xxx */ |
| 1030 | greloc(cur_text_section, sv->sym, ind, R_386_32); | 1027 | greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_386_32); |
| 1031 | gen_le32(0); | 1028 | gen_le32(S, 0); |
| 1032 | o(1); | 1029 | o(S, 1); |
| 1033 | o(0x1583); /* addcl $0, xxx */ | 1030 | o(S, 0x1583); /* addcl $0, xxx */ |
| 1034 | greloc(cur_text_section, sv->sym, ind, R_386_32); | 1031 | greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_386_32); |
| 1035 | gen_le32(4); | 1032 | gen_le32(S, 4); |
| 1036 | g(0); | 1033 | g(S, 0); |
| 1037 | } | 1034 | } |
| 1038 | 1035 | ||
| 1039 | /* computed goto support */ | 1036 | /* computed goto support */ |
| 1040 | ST_FUNC void ggoto(void) | 1037 | ST_FUNC void ggoto(TCCState* S) |
| 1041 | { | 1038 | { |
| 1042 | gcall_or_jmp(1); | 1039 | gcall_or_jmp(S, 1); |
| 1043 | vtop--; | 1040 | S->tccgen_vtop--; |
| 1044 | } | 1041 | } |
| 1045 | 1042 | ||
| 1046 | /* bound check support functions */ | 1043 | /* bound check support functions */ |
| 1047 | #ifdef CONFIG_TCC_BCHECK | 1044 | #ifdef CONFIG_TCC_BCHECK |
| 1048 | 1045 | ||
| 1049 | static void gen_bounds_prolog(void) | 1046 | static void gen_bounds_prolog(TCCState* S) |
| 1050 | { | 1047 | { |
| 1051 | /* leave some room for bound checking code */ | 1048 | /* leave some room for bound checking code */ |
| 1052 | func_bound_offset = lbounds_section->data_offset; | 1049 | S->func_bound_offset = lbounds_section->data_offset; |
| 1053 | func_bound_ind = ind; | 1050 | S->func_bound_ind = S->tccgen_ind; |
| 1054 | func_bound_add_epilog = 0; | 1051 | S->func_bound_add_epilog = 0; |
| 1055 | oad(0xb8, 0); /* lbound section pointer */ | 1052 | oad(S, 0xb8, 0); /* lbound section pointer */ |
| 1056 | oad(0xb8, 0); /* call to function */ | 1053 | oad(S, 0xb8, 0); /* call to function */ |
| 1057 | } | 1054 | } |
| 1058 | 1055 | ||
| 1059 | static void gen_bounds_epilog(void) | 1056 | static void gen_bounds_epilog(TCCState* S) |
| 1060 | { | 1057 | { |
| 1061 | addr_t saved_ind; | 1058 | addr_t saved_ind; |
| 1062 | addr_t *bounds_ptr; | 1059 | addr_t *bounds_ptr; |
| 1063 | Sym *sym_data; | 1060 | Sym *sym_data; |
| 1064 | int offset_modified = func_bound_offset != lbounds_section->data_offset; | 1061 | int offset_modified = S->func_bound_offset != lbounds_section->data_offset; |
| 1065 | 1062 | ||
| 1066 | if (!offset_modified && !func_bound_add_epilog) | 1063 | if (!offset_modified && !S->func_bound_add_epilog) |
| 1067 | return; | 1064 | return; |
| 1068 | 1065 | ||
| 1069 | /* add end of table info */ | 1066 | /* add end of table info */ |
| 1070 | bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t)); | 1067 | bounds_ptr = section_ptr_add(S, lbounds_section, sizeof(addr_t)); |
| 1071 | *bounds_ptr = 0; | 1068 | *bounds_ptr = 0; |
| 1072 | 1069 | ||
| 1073 | sym_data = get_sym_ref(&char_pointer_type, lbounds_section, | 1070 | sym_data = get_sym_ref(S, &S->tccgen_char_pointer_type, lbounds_section, |
| 1074 | func_bound_offset, lbounds_section->data_offset); | 1071 | S->func_bound_offset, lbounds_section->data_offset); |
| 1075 | 1072 | ||
| 1076 | /* generate bound local allocation */ | 1073 | /* generate bound local allocation */ |
| 1077 | if (offset_modified) { | 1074 | if (offset_modified) { |
| 1078 | saved_ind = ind; | 1075 | saved_ind = S->tccgen_ind; |
| 1079 | ind = func_bound_ind; | 1076 | S->tccgen_ind = S->func_bound_ind; |
| 1080 | greloc(cur_text_section, sym_data, ind + 1, R_386_32); | 1077 | greloc(S, cur_text_section, sym_data, S->tccgen_ind + 1, R_386_32); |
| 1081 | ind = ind + 5; | 1078 | S->tccgen_ind = S->tccgen_ind + 5; |
| 1082 | gen_static_call(TOK___bound_local_new); | 1079 | gen_static_call(S, TOK___bound_local_new); |
| 1083 | ind = saved_ind; | 1080 | S->tccgen_ind = saved_ind; |
| 1084 | } | 1081 | } |
| 1085 | 1082 | ||
| 1086 | /* generate bound check local freeing */ | 1083 | /* generate bound check local freeing */ |
| 1087 | o(0x5250); /* save returned value, if any */ | 1084 | o(S, 0x5250); /* save returned value, if any */ |
| 1088 | greloc(cur_text_section, sym_data, ind + 1, R_386_32); | 1085 | greloc(S, cur_text_section, sym_data, S->tccgen_ind + 1, R_386_32); |
| 1089 | oad(0xb8, 0); /* mov %eax, xxx */ | 1086 | oad(S, 0xb8, 0); /* mov %eax, xxx */ |
| 1090 | gen_static_call(TOK___bound_local_delete); | 1087 | gen_static_call(S, TOK___bound_local_delete); |
| 1091 | o(0x585a); /* restore returned value, if any */ | 1088 | o(S, 0x585a); /* restore returned value, if any */ |
| 1092 | } | 1089 | } |
| 1093 | #endif | 1090 | #endif |
| 1094 | 1091 | ||
| 1095 | /* Save the stack pointer onto the stack */ | 1092 | /* Save the stack pointer onto the stack */ |
| 1096 | ST_FUNC void gen_vla_sp_save(int addr) { | 1093 | ST_FUNC void gen_vla_sp_save(TCCState* S, int addr) { |
| 1097 | /* mov %esp,addr(%ebp)*/ | 1094 | /* mov %esp,addr(%ebp)*/ |
| 1098 | o(0x89); | 1095 | o(S, 0x89); |
| 1099 | gen_modrm(TREG_ESP, VT_LOCAL, NULL, addr); | 1096 | gen_modrm(S, TREG_ESP, VT_LOCAL, NULL, addr); |
| 1100 | } | 1097 | } |
| 1101 | 1098 | ||
| 1102 | /* Restore the SP from a location on the stack */ | 1099 | /* Restore the SP from a location on the stack */ |
| 1103 | ST_FUNC void gen_vla_sp_restore(int addr) { | 1100 | ST_FUNC void gen_vla_sp_restore(TCCState* S, int addr) { |
| 1104 | o(0x8b); | 1101 | o(S, 0x8b); |
| 1105 | gen_modrm(TREG_ESP, VT_LOCAL, NULL, addr); | 1102 | gen_modrm(S, TREG_ESP, VT_LOCAL, NULL, addr); |
| 1106 | } | 1103 | } |
| 1107 | 1104 | ||
| 1108 | /* Subtract from the stack pointer, and push the resulting value onto the stack */ | 1105 | /* Subtract from the stack pointer, and push the resulting value onto the stack */ |
| 1109 | ST_FUNC void gen_vla_alloc(CType *type, int align) { | 1106 | ST_FUNC void gen_vla_alloc(TCCState* S, CType *type, int align) { |
| 1110 | int use_call = 0; | 1107 | int use_call = 0; |
| 1111 | 1108 | ||
| 1112 | #if defined(CONFIG_TCC_BCHECK) | 1109 | #if defined(CONFIG_TCC_BCHECK) |
| 1113 | use_call = tcc_state->do_bounds_check; | 1110 | use_call = S->do_bounds_check; |
| 1114 | #endif | 1111 | #endif |
| 1115 | #ifdef TCC_TARGET_PE /* alloca does more than just adjust %rsp on Windows */ | 1112 | #ifdef TCC_TARGET_PE /* alloca does more than just adjust %rsp on Windows */ |
| 1116 | use_call = 1; | 1113 | use_call = 1; |
| 1117 | #endif | 1114 | #endif |
| 1118 | if (use_call) | 1115 | if (use_call) |
| 1119 | { | 1116 | { |
| 1120 | vpush_helper_func(TOK_alloca); | 1117 | vpush_helper_func(S, TOK_alloca); |
| 1121 | vswap(); /* Move alloca ref past allocation size */ | 1118 | vswap(S); /* Move alloca ref past allocation size */ |
| 1122 | gfunc_call(1); | 1119 | gfunc_call(S, 1); |
| 1123 | } | 1120 | } |
| 1124 | else { | 1121 | else { |
| 1125 | int r; | 1122 | int r; |
| 1126 | r = gv(RC_INT); /* allocation size */ | 1123 | r = gv(S, RC_INT); /* allocation size */ |
| 1127 | /* sub r,%rsp */ | 1124 | /* sub r,%rsp */ |
| 1128 | o(0x2b); | 1125 | o(S, 0x2b); |
| 1129 | o(0xe0 | r); | 1126 | o(S, 0xe0 | r); |
| 1130 | /* We align to 16 bytes rather than align */ | 1127 | /* We align to 16 bytes rather than align */ |
| 1131 | /* and ~15, %esp */ | 1128 | /* and ~15, %esp */ |
| 1132 | o(0xf0e483); | 1129 | o(S, 0xf0e483); |
| 1133 | vpop(); | 1130 | vpop(S); |
| 1134 | } | 1131 | } |
| 1135 | } | 1132 | } |
| 1136 | 1133 | ||
| @@ -91,15 +91,15 @@ int gotplt_entry_type (int reloc_type) · 90 unmodified lines | |||
| 91 | return -1; | 91 | return -1; |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr) | 94 | ST_FUNC unsigned create_plt_entry(TCCState *S, unsigned got_offset, struct sym_attr *attr) |
| 95 | { | 95 | { |
| 96 | Section *plt = s1->plt; | 96 | Section *plt = S->plt; |
| 97 | uint8_t *p; | 97 | uint8_t *p; |
| 98 | int modrm; | 98 | int modrm; |
| 99 | unsigned plt_offset, relofs; | 99 | unsigned plt_offset, relofs; |
| 100 | 100 | ||
| 101 | /* on i386 if we build a DLL, we add a %ebx offset */ | 101 | /* on i386 if we build a DLL, we add a %ebx offset */ |
| 102 | if (s1->output_type == TCC_OUTPUT_DLL) | 102 | if (S->output_type == TCC_OUTPUT_DLL) |
| 103 | modrm = 0xa3; | 103 | modrm = 0xa3; |
| 104 | else | 104 | else |
| 105 | modrm = 0x25; | 105 | modrm = 0x25; |
| @@ -108,7 +108,7 @@ ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_ · 2 unmodified lines | |||
| 108 | (GOT + PTR_SIZE) and jumps to ld.so resolution routine | 108 | (GOT + PTR_SIZE) and jumps to ld.so resolution routine |
| 109 | (GOT + 2 * PTR_SIZE) */ | 109 | (GOT + 2 * PTR_SIZE) */ |
| 110 | if (plt->data_offset == 0) { | 110 | if (plt->data_offset == 0) { |
| 111 | p = section_ptr_add(plt, 16); | 111 | p = section_ptr_add(S, plt, 16); |
| 112 | p[0] = 0xff; /* pushl got + PTR_SIZE */ | 112 | p[0] = 0xff; /* pushl got + PTR_SIZE */ |
| 113 | p[1] = modrm + 0x10; | 113 | p[1] = modrm + 0x10; |
| 114 | write32le(p + 2, PTR_SIZE); | 114 | write32le(p + 2, PTR_SIZE); |
| @@ -121,10 +121,10 @@ ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_ · 6 unmodified lines | |||
| 121 | /* The PLT slot refers to the relocation entry it needs via offset. | 121 | /* The PLT slot refers to the relocation entry it needs via offset. |
| 122 | The reloc entry is created below, so its offset is the current | 122 | The reloc entry is created below, so its offset is the current |
| 123 | data_offset */ | 123 | data_offset */ |
| 124 | relofs = s1->plt->reloc ? s1->plt->reloc->data_offset : 0; | 124 | relofs = S->plt->reloc ? S->plt->reloc->data_offset : 0; |
| 125 | 125 | ||
| 126 | /* Jump to GOT entry where ld.so initially put the address of ip + 4 */ | 126 | /* Jump to GOT entry where ld.so initially put the address of ip + 4 */ |
| 127 | p = section_ptr_add(plt, 16); | 127 | p = section_ptr_add(S, plt, 16); |
| 128 | p[0] = 0xff; /* jmp *(got + x) */ | 128 | p[0] = 0xff; /* jmp *(got + x) */ |
| 129 | p[1] = modrm; | 129 | p[1] = modrm; |
| 130 | write32le(p + 2, got_offset); | 130 | write32le(p + 2, got_offset); |
| @@ -137,31 +137,31 @@ ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_ · 6 unmodified lines | |||
| 137 | 137 | ||
| 138 | /* relocate the PLT: compute addresses and offsets in the PLT now that final | 138 | /* relocate the PLT: compute addresses and offsets in the PLT now that final |
| 139 | address for PLT and GOT are known (see fill_program_header) */ | 139 | address for PLT and GOT are known (see fill_program_header) */ |
| 140 | ST_FUNC void relocate_plt(TCCState *s1) | 140 | ST_FUNC void relocate_plt(TCCState *S) |
| 141 | { | 141 | { |
| 142 | uint8_t *p, *p_end; | 142 | uint8_t *p, *p_end; |
| 143 | 143 | ||
| 144 | if (!s1->plt) | 144 | if (!S->plt) |
| 145 | return; | 145 | return; |
| 146 | 146 | ||
| 147 | p = s1->plt->data; | 147 | p = S->plt->data; |
| 148 | p_end = p + s1->plt->data_offset; | 148 | p_end = p + S->plt->data_offset; |
| 149 | 149 | ||
| 150 | if (s1->output_type != TCC_OUTPUT_DLL && p < p_end) { | 150 | if (S->output_type != TCC_OUTPUT_DLL && p < p_end) { |
| 151 | add32le(p + 2, s1->got->sh_addr); | 151 | add32le(p + 2, S->got->sh_addr); |
| 152 | add32le(p + 8, s1->got->sh_addr); | 152 | add32le(p + 8, S->got->sh_addr); |
| 153 | p += 16; | 153 | p += 16; |
| 154 | while (p < p_end) { | 154 | while (p < p_end) { |
| 155 | add32le(p + 2, s1->got->sh_addr); | 155 | add32le(p + 2, S->got->sh_addr); |
| 156 | p += 16; | 156 | p += 16; |
| 157 | } | 157 | } |
| 158 | } | 158 | } |
| 159 | 159 | ||
| 160 | if (s1->plt->reloc) { | 160 | if (S->plt->reloc) { |
| 161 | ElfW_Rel *rel; | 161 | ElfW_Rel *rel; |
| 162 | int x = s1->plt->sh_addr + 16 + 6; | 162 | int x = S->plt->sh_addr + 16 + 6; |
| 163 | p = s1->got->data; | 163 | p = S->got->data; |
| 164 | for_each_elem(s1->plt->reloc, 0, rel, ElfW_Rel) { | 164 | for_each_elem(S->plt->reloc, 0, rel, ElfW_Rel) { |
| 165 | write32le(p + rel->r_offset, x); | 165 | write32le(p + rel->r_offset, x); |
| 166 | x += 16; | 166 | x += 16; |
| 167 | } | 167 | } |
| @@ -169,7 +169,7 @@ ST_FUNC void relocate_plt(TCCState *s1) · 1 unmodified line | |||
| 169 | } | 169 | } |
| 170 | #endif | 170 | #endif |
| 171 | 171 | ||
| 172 | void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val) | 172 | void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val) |
| 173 | { | 173 | { |
| 174 | int sym_index, esym_index; | 174 | int sym_index, esym_index; |
| 175 | 175 | ||
| @@ -177,8 +177,8 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 1 unmodified line | |||
| 177 | 177 | ||
| 178 | switch (type) { | 178 | switch (type) { |
| 179 | case R_386_32: | 179 | case R_386_32: |
| 180 | if (s1->output_type == TCC_OUTPUT_DLL) { | 180 | if (S->output_type == TCC_OUTPUT_DLL) { |
| 181 | esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index; | 181 | esym_index = get_sym_attr(S, sym_index, 0)->dyn_index; |
| 182 | qrel->r_offset = rel->r_offset; | 182 | qrel->r_offset = rel->r_offset; |
| 183 | if (esym_index) { | 183 | if (esym_index) { |
| 184 | qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32); | 184 | qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32); |
| @@ -192,9 +192,9 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 7 unmodified lines | |||
| 192 | add32le(ptr, val); | 192 | add32le(ptr, val); |
| 193 | return; | 193 | return; |
| 194 | case R_386_PC32: | 194 | case R_386_PC32: |
| 195 | if (s1->output_type == TCC_OUTPUT_DLL) { | 195 | if (S->output_type == TCC_OUTPUT_DLL) { |
| 196 | /* DLL relocation */ | 196 | /* DLL relocation */ |
| 197 | esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index; | 197 | esym_index = get_sym_attr(S, sym_index, 0)->dyn_index; |
| 198 | if (esym_index) { | 198 | if (esym_index) { |
| 199 | qrel->r_offset = rel->r_offset; | 199 | qrel->r_offset = rel->r_offset; |
| 200 | qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32); | 200 | qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32); |
| @@ -212,31 +212,31 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 11 unmodified lines | |||
| 212 | write32le(ptr, val); | 212 | write32le(ptr, val); |
| 213 | return; | 213 | return; |
| 214 | case R_386_GOTPC: | 214 | case R_386_GOTPC: |
| 215 | add32le(ptr, s1->got->sh_addr - addr); | 215 | add32le(ptr, S->got->sh_addr - addr); |
| 216 | return; | 216 | return; |
| 217 | case R_386_GOTOFF: | 217 | case R_386_GOTOFF: |
| 218 | add32le(ptr, val - s1->got->sh_addr); | 218 | add32le(ptr, val - S->got->sh_addr); |
| 219 | return; | 219 | return; |
| 220 | case R_386_GOT32: | 220 | case R_386_GOT32: |
| 221 | case R_386_GOT32X: | 221 | case R_386_GOT32X: |
| 222 | /* we load the got offset */ | 222 | /* we load the got offset */ |
| 223 | add32le(ptr, get_sym_attr(s1, sym_index, 0)->got_offset); | 223 | add32le(ptr, get_sym_attr(S, sym_index, 0)->got_offset); |
| 224 | return; | 224 | return; |
| 225 | case R_386_16: | 225 | case R_386_16: |
| 226 | if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) { | 226 | if (S->output_format != TCC_OUTPUT_FORMAT_BINARY) { |
| 227 | output_file: | 227 | output_file: |
| 228 | tcc_error("can only produce 16-bit binary files"); | 228 | tcc_error(S, "can only produce 16-bit binary files"); |
| 229 | } | 229 | } |
| 230 | write16le(ptr, read16le(ptr) + val); | 230 | write16le(ptr, read16le(ptr) + val); |
| 231 | return; | 231 | return; |
| 232 | case R_386_PC16: | 232 | case R_386_PC16: |
| 233 | if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) | 233 | if (S->output_format != TCC_OUTPUT_FORMAT_BINARY) |
| 234 | goto output_file; | 234 | goto output_file; |
| 235 | write16le(ptr, read16le(ptr) + val - addr); | 235 | write16le(ptr, read16le(ptr) + val - addr); |
| 236 | return; | 236 | return; |
| 237 | case R_386_RELATIVE: | 237 | case R_386_RELATIVE: |
| 238 | #ifdef TCC_TARGET_PE | 238 | #ifdef TCC_TARGET_PE |
| 239 | add32le(ptr, val - s1->pe_imagebase); | 239 | add32le(ptr, val - S->pe_imagebase); |
| 240 | #endif | 240 | #endif |
| 241 | /* do nothing */ | 241 | /* do nothing */ |
| 242 | return; | 242 | return; |
| @@ -267,12 +267,12 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 24 unmodified lines | |||
| 267 | memcpy(ptr-3, replace, sizeof(replace)); | 267 | memcpy(ptr-3, replace, sizeof(replace)); |
| 268 | rel[1].r_info = ELFW(R_INFO)(0, R_386_NONE); | 268 | rel[1].r_info = ELFW(R_INFO)(0, R_386_NONE); |
| 269 | sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; | 269 | sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; |
| 270 | sec = s1->sections[sym->st_shndx]; | 270 | sec = S->sections[sym->st_shndx]; |
| 271 | x = sym->st_value - sec->sh_addr - sec->data_offset; | 271 | x = sym->st_value - sec->sh_addr - sec->data_offset; |
| 272 | add32le(ptr + 5, -x); | 272 | add32le(ptr + 5, -x); |
| 273 | } | 273 | } |
| 274 | else | 274 | else |
| 275 | tcc_error("unexpected R_386_TLS_GD pattern"); | 275 | tcc_error(S, "unexpected R_386_TLS_GD pattern"); |
| 276 | } | 276 | } |
| 277 | return; | 277 | return; |
| 278 | case R_386_TLS_LDM: | 278 | case R_386_TLS_LDM: |
| @@ -295,7 +295,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 16 unmodified lines | |||
| 295 | rel[1].r_info = ELFW(R_INFO)(0, R_386_NONE); | 295 | rel[1].r_info = ELFW(R_INFO)(0, R_386_NONE); |
| 296 | } | 296 | } |
| 297 | else | 297 | else |
| 298 | tcc_error("unexpected R_386_TLS_LDM pattern"); | 298 | tcc_error(S, "unexpected R_386_TLS_LDM pattern"); |
| 299 | } | 299 | } |
| 300 | return; | 300 | return; |
| 301 | case R_386_TLS_LDO_32: | 301 | case R_386_TLS_LDO_32: |
| @@ -306,7 +306,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 4 unmodified lines | |||
| 306 | int32_t x; | 306 | int32_t x; |
| 307 | 307 | ||
| 308 | sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; | 308 | sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; |
| 309 | sec = s1->sections[sym->st_shndx]; | 309 | sec = S->sections[sym->st_shndx]; |
| 310 | x = val - sec->sh_addr - sec->data_offset; | 310 | x = val - sec->sh_addr - sec->data_offset; |
| 311 | add32le(ptr, x); | 311 | add32le(ptr, x); |
| 312 | } | 312 | } |
| @@ -65,7 +65,6 @@ · 64 unmodified lines | |||
| 65 | /* global variables */ | 65 | /* global variables */ |
| 66 | 66 | ||
| 67 | /* XXX: get rid of this ASAP (or maybe not) */ | 67 | /* XXX: get rid of this ASAP (or maybe not) */ |
| 68 | ST_DATA struct TCCState *tcc_state; | ||
| 69 | TCC_SEM(static tcc_compile_sem); | 68 | TCC_SEM(static tcc_compile_sem); |
| 70 | 69 | ||
| 71 | #ifdef MEM_DEBUG | 70 | #ifdef MEM_DEBUG |
| @@ -111,11 +110,11 @@ static inline char *config_tccdir_w32(char *path) · 39 unmodified lines | |||
| 111 | #endif | 110 | #endif |
| 112 | 111 | ||
| 113 | #ifdef TCC_TARGET_PE | 112 | #ifdef TCC_TARGET_PE |
| 114 | static void tcc_add_systemdir(TCCState *s) | 113 | static void tcc_add_systemdir(TCCState *S) |
| 115 | { | 114 | { |
| 116 | char buf[1000]; | 115 | char buf[1000]; |
| 117 | GetSystemDirectory(buf, sizeof buf); | 116 | GetSystemDirectory(buf, sizeof buf); |
| 118 | tcc_add_library_path(s, normalize_slashes(buf)); | 117 | tcc_add_library_path(S, normalize_slashes(buf)); |
| 119 | } | 118 | } |
| 120 | #endif | 119 | #endif |
| 121 | #endif | 120 | #endif |
| @@ -160,19 +159,19 @@ ST_FUNC void post_sem(TCCSem *p) · 38 unmodified lines | |||
| 160 | #endif | 159 | #endif |
| 161 | #endif | 160 | #endif |
| 162 | 161 | ||
| 163 | PUB_FUNC void tcc_enter_state(TCCState *s1) | 162 | PUB_FUNC void tcc_enter_state(TCCState *S) |
| 164 | { | 163 | { |
| 165 | if (s1->error_set_jmp_enabled) | 164 | if (S->error_set_jmp_enabled) |
| 166 | return; | 165 | return; |
| 167 | WAIT_SEM(&tcc_compile_sem); | 166 | WAIT_SEM(&tcc_compile_sem); |
| 168 | tcc_state = s1; | 167 | /*S = S;*/ |
| 169 | } | 168 | } |
| 170 | 169 | ||
| 171 | PUB_FUNC void tcc_exit_state(TCCState *s1) | 170 | PUB_FUNC void tcc_exit_state(TCCState *S) |
| 172 | { | 171 | { |
| 173 | if (s1->error_set_jmp_enabled) | 172 | if (S->error_set_jmp_enabled) |
| 174 | return; | 173 | return; |
| 175 | tcc_state = NULL; | 174 | S = NULL; |
| 176 | POST_SEM(&tcc_compile_sem); | 175 | POST_SEM(&tcc_compile_sem); |
| 177 | } | 176 | } |
| 178 | 177 | ||
| @@ -234,10 +233,10 @@ PUB_FUNC char *tcc_fileextension (const char *name) · 55 unmodified lines | |||
| 234 | return e ? e : strchr(b, 0); | 233 | return e ? e : strchr(b, 0); |
| 235 | } | 234 | } |
| 236 | 235 | ||
| 237 | ST_FUNC char *tcc_load_text(int fd) | 236 | ST_FUNC char *tcc_load_text(TCCState* S, int fd) |
| 238 | { | 237 | { |
| 239 | int len = lseek(fd, 0, SEEK_END); | 238 | int len = lseek(fd, 0, SEEK_END); |
| 240 | char *buf = load_data(fd, 0, len + 1); | 239 | char *buf = load_data(S, fd, 0, len + 1); |
| 241 | buf[len] = 0; | 240 | buf[len] = 0; |
| 242 | return buf; | 241 | return buf; |
| 243 | } | 242 | } |
| @@ -249,44 +248,69 @@ ST_FUNC char *tcc_load_text(int fd) · 5 unmodified lines | |||
| 249 | #undef malloc | 248 | #undef malloc |
| 250 | #undef realloc | 249 | #undef realloc |
| 251 | 250 | ||
| 251 | PUB_FUNC void tcc_free_base(void *ptr) | ||
| 252 | { | ||
| 253 | free(ptr); | ||
| 254 | } | ||
| 255 | |||
| 256 | PUB_FUNC void *tcc_malloc_base(unsigned long size) | ||
| 257 | { | ||
| 258 | void *ptr; | ||
| 259 | ptr = malloc(size); | ||
| 260 | if (!ptr && size) { | ||
| 261 | printf("memory full (malloc)\n"); | ||
| 262 | exit(1); | ||
| 263 | } | ||
| 264 | return ptr; | ||
| 265 | } | ||
| 266 | |||
| 267 | PUB_FUNC void *tcc_mallocz_base(unsigned long size) | ||
| 268 | { | ||
| 269 | void *ptr; | ||
| 270 | ptr = tcc_malloc_base(size); | ||
| 271 | if (size) | ||
| 272 | memset(ptr, 0, size); | ||
| 273 | return ptr; | ||
| 274 | } | ||
| 275 | |||
| 252 | #ifndef MEM_DEBUG | 276 | #ifndef MEM_DEBUG |
| 253 | 277 | ||
| 254 | PUB_FUNC void tcc_free(void *ptr) | 278 | PUB_FUNC void tcc_free(TCCState* S, void *ptr) |
| 255 | { | 279 | { |
| 256 | free(ptr); | 280 | free(ptr); |
| 257 | } | 281 | } |
| 258 | 282 | ||
| 259 | PUB_FUNC void *tcc_malloc(unsigned long size) | 283 | PUB_FUNC void *tcc_malloc(TCCState* S, unsigned long size) |
| 260 | { | 284 | { |
| 261 | void *ptr; | 285 | void *ptr; |
| 262 | ptr = malloc(size); | 286 | ptr = malloc(size); |
| 263 | if (!ptr && size) | 287 | if (!ptr && size) |
| 264 | _tcc_error("memory full (malloc)"); | 288 | _tcc_error(S, "memory full (malloc)"); |
| 265 | return ptr; | 289 | return ptr; |
| 266 | } | 290 | } |
| 267 | 291 | ||
| 268 | PUB_FUNC void *tcc_mallocz(unsigned long size) | 292 | PUB_FUNC void *tcc_mallocz(TCCState* S, unsigned long size) |
| 269 | { | 293 | { |
| 270 | void *ptr; | 294 | void *ptr; |
| 271 | ptr = tcc_malloc(size); | 295 | ptr = tcc_malloc(S, size); |
| 272 | if (size) | 296 | if (size) |
| 273 | memset(ptr, 0, size); | 297 | memset(ptr, 0, size); |
| 274 | return ptr; | 298 | return ptr; |
| 275 | } | 299 | } |
| 276 | 300 | ||
| 277 | PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size) | 301 | PUB_FUNC void *tcc_realloc(TCCState* S, void *ptr, unsigned long size) |
| 278 | { | 302 | { |
| 279 | void *ptr1; | 303 | void *ptr1; |
| 280 | ptr1 = realloc(ptr, size); | 304 | ptr1 = realloc(ptr, size); |
| 281 | if (!ptr1 && size) | 305 | if (!ptr1 && size) |
| 282 | _tcc_error("memory full (realloc)"); | 306 | _tcc_error(S, "memory full (realloc)"); |
| 283 | return ptr1; | 307 | return ptr1; |
| 284 | } | 308 | } |
| 285 | 309 | ||
| 286 | PUB_FUNC char *tcc_strdup(const char *str) | 310 | PUB_FUNC char *tcc_strdup(TCCState* S, const char *str) |
| 287 | { | 311 | { |
| 288 | char *ptr; | 312 | char *ptr; |
| 289 | ptr = tcc_malloc(strlen(str) + 1); | 313 | ptr = tcc_malloc(S, strlen(str) + 1); |
| 290 | strcpy(ptr, str); | 314 | strcpy(ptr, str); |
| 291 | return ptr; | 315 | return ptr; |
| 292 | } | 316 | } |
| @@ -337,14 +361,14 @@ static mem_debug_header_t *malloc_check(void *ptr, const char *msg) · 44 unmodified lines | |||
| 337 | return header; | 361 | return header; |
| 338 | } | 362 | } |
| 339 | 363 | ||
| 340 | PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line) | 364 | PUB_FUNC void *tcc_malloc_debug(TCCState* S, unsigned long size, const char *file, int line) |
| 341 | { | 365 | { |
| 342 | int ofs; | 366 | int ofs; |
| 343 | mem_debug_header_t *header; | 367 | mem_debug_header_t *header; |
| 344 | 368 | ||
| 345 | header = malloc(sizeof(mem_debug_header_t) + size); | 369 | header = malloc(sizeof(mem_debug_header_t) + size); |
| 346 | if (!header) | 370 | if (!header) |
| 347 | _tcc_error("memory full (malloc)"); | 371 | _tcc_error(S, "memory full (malloc)"); |
| 348 | 372 | ||
| 349 | header->magic1 = MEM_DEBUG_MAGIC1; | 373 | header->magic1 = MEM_DEBUG_MAGIC1; |
| 350 | header->magic2 = MEM_DEBUG_MAGIC2; | 374 | header->magic2 = MEM_DEBUG_MAGIC2; |
| @@ -368,7 +392,7 @@ PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line) · 17 unmodified lines | |||
| 368 | return MEM_USER_PTR(header); | 392 | return MEM_USER_PTR(header); |
| 369 | } | 393 | } |
| 370 | 394 | ||
| 371 | PUB_FUNC void tcc_free_debug(void *ptr) | 395 | PUB_FUNC void tcc_free_debug(TCCState* S, void *ptr) |
| 372 | { | 396 | { |
| 373 | mem_debug_header_t *header; | 397 | mem_debug_header_t *header; |
| 374 | if (!ptr) | 398 | if (!ptr) |
| @@ -385,26 +409,26 @@ PUB_FUNC void tcc_free_debug(void *ptr) · 10 unmodified lines | |||
| 385 | free(header); | 409 | free(header); |
| 386 | } | 410 | } |
| 387 | 411 | ||
| 388 | PUB_FUNC void *tcc_mallocz_debug(unsigned long size, const char *file, int line) | 412 | PUB_FUNC void *tcc_mallocz_debug(TCCState* S, unsigned long size, const char *file, int line) |
| 389 | { | 413 | { |
| 390 | void *ptr; | 414 | void *ptr; |
| 391 | ptr = tcc_malloc_debug(size,file,line); | 415 | ptr = tcc_malloc_debug(S, size,file,line); |
| 392 | memset(ptr, 0, size); | 416 | memset(ptr, 0, size); |
| 393 | return ptr; | 417 | return ptr; |
| 394 | } | 418 | } |
| 395 | 419 | ||
| 396 | PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file, int line) | 420 | PUB_FUNC void *tcc_realloc_debug(TCCState* S, void *ptr, unsigned long size, const char *file, int line) |
| 397 | { | 421 | { |
| 398 | mem_debug_header_t *header; | 422 | mem_debug_header_t *header; |
| 399 | int mem_debug_chain_update = 0; | 423 | int mem_debug_chain_update = 0; |
| 400 | if (!ptr) | 424 | if (!ptr) |
| 401 | return tcc_malloc_debug(size, file, line); | 425 | return tcc_malloc_debug(S, size, file, line); |
| 402 | header = malloc_check(ptr, "tcc_realloc"); | 426 | header = malloc_check(ptr, "tcc_realloc"); |
| 403 | mem_cur_size -= header->size; | 427 | mem_cur_size -= header->size; |
| 404 | mem_debug_chain_update = (header == mem_debug_chain); | 428 | mem_debug_chain_update = (header == mem_debug_chain); |
| 405 | header = realloc(header, sizeof(mem_debug_header_t) + size); | 429 | header = realloc(header, sizeof(mem_debug_header_t) + size); |
| 406 | if (!header) | 430 | if (!header) |
| 407 | _tcc_error("memory full (realloc)"); | 431 | _tcc_error(S, "memory full (realloc)"); |
| 408 | header->size = size; | 432 | header->size = size; |
| 409 | write32le(MEM_DEBUG_CHECK3(header), MEM_DEBUG_MAGIC3); | 433 | write32le(MEM_DEBUG_CHECK3(header), MEM_DEBUG_MAGIC3); |
| 410 | if (header->next) | 434 | if (header->next) |
| @@ -419,10 +443,10 @@ PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file · 8 unmodified lines | |||
| 419 | return MEM_USER_PTR(header); | 443 | return MEM_USER_PTR(header); |
| 420 | } | 444 | } |
| 421 | 445 | ||
| 422 | PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line) | 446 | PUB_FUNC char *tcc_strdup_debug(TCCState* S, const char *str, const char *file, int line) |
| 423 | { | 447 | { |
| 424 | char *ptr; | 448 | char *ptr; |
| 425 | ptr = tcc_malloc_debug(strlen(str) + 1, file, line); | 449 | ptr = tcc_malloc_debug(S, strlen(str) + 1, file, line); |
| 426 | strcpy(ptr, str); | 450 | strcpy(ptr, str); |
| 427 | return ptr; | 451 | return ptr; |
| 428 | } | 452 | } |
| @@ -449,10 +473,66 @@ PUB_FUNC void tcc_memcheck(void) · 20 unmodified lines | |||
| 449 | #define malloc(s) use_tcc_malloc(s) | 473 | #define malloc(s) use_tcc_malloc(s) |
| 450 | #define realloc(p, s) use_tcc_realloc(p, s) | 474 | #define realloc(p, s) use_tcc_realloc(p, s) |
| 451 | 475 | ||
| 476 | /********************************************************/ | ||
| 477 | /* virtual io */ | ||
| 478 | |||
| 479 | LIBTCCAPI void tcc_set_vio_module(TCCState *S, vio_module_t *vio_module){ | ||
| 480 | S->vio_module = vio_module; | ||
| 481 | vio_module->S = S; | ||
| 482 | } | ||
| 483 | |||
| 484 | void vio_initialize(vio_fd *fd) { | ||
| 485 | fd->fd = -1; | ||
| 486 | fd->vio_udata = NULL; | ||
| 487 | fd->vio_module = NULL; | ||
| 488 | } | ||
| 489 | |||
| 490 | int vio_open(struct TCCState *S, vio_fd *fd, const char *fn, int oflag) { | ||
| 491 | int rc; | ||
| 492 | vio_initialize(fd); | ||
| 493 | fd->vio_module = S->vio_module; | ||
| 494 | if(S->vio_module && (S->vio_module->call_vio_open_flags & CALL_VIO_OPEN_FIRST)) { | ||
| 495 | rc = S->vio_module->vio_open(fd, fn, oflag); | ||
| 496 | if(rc >= 0) return rc; | ||
| 497 | } | ||
| 498 | |||
| 499 | fd->fd = open(fn, oflag); | ||
| 500 | |||
| 501 | if(fd->fd < 0 && S->vio_module && (S->vio_module->call_vio_open_flags & CALL_VIO_OPEN_LAST)) { | ||
| 502 | rc = S->vio_module->vio_open(fd, fn, oflag); | ||
| 503 | if(rc >= 0) return rc; | ||
| 504 | } | ||
| 505 | //printf("vio_open = %d %s\n", fd->fd, fn); | ||
| 506 | return fd->fd; | ||
| 507 | } | ||
| 508 | |||
| 509 | off_t vio_lseek(vio_fd fd, off_t offset, int whence) { | ||
| 510 | if(fd.vio_udata) { | ||
| 511 | return fd.vio_module->vio_lseek(fd, offset, whence); | ||
| 512 | } | ||
| 513 | return lseek(fd.fd, offset, whence); | ||
| 514 | } | ||
| 515 | |||
| 516 | size_t vio_read(vio_fd fd, void *buf, size_t bytes) { | ||
| 517 | if(fd.vio_udata) { | ||
| 518 | return fd.vio_module->vio_read(fd, buf, bytes); | ||
| 519 | } | ||
| 520 | return read(fd.fd, buf, bytes); | ||
| 521 | } | ||
| 522 | |||
| 523 | int vio_close(vio_fd *fd) { | ||
| 524 | int rc = 0; | ||
| 525 | if(fd->vio_udata){ | ||
| 526 | fd->vio_module->vio_close(fd); | ||
| 527 | } else rc = close(fd->fd); | ||
| 528 | vio_initialize(fd); | ||
| 529 | return rc; | ||
| 530 | } | ||
| 531 | |||
| 452 | /********************************************************/ | 532 | /********************************************************/ |
| 453 | /* dynarrays */ | 533 | /* dynarrays */ |
| 454 | 534 | ||
| 455 | ST_FUNC void dynarray_add(void *ptab, int *nb_ptr, void *data) | 535 | ST_FUNC void dynarray_add(TCCState* S, void *ptab, int *nb_ptr, void *data) |
| 456 | { | 536 | { |
| 457 | int nb, nb_alloc; | 537 | int nb, nb_alloc; |
| 458 | void **pp; | 538 | void **pp; |
| @@ -465,54 +545,54 @@ ST_FUNC void dynarray_add(void *ptab, int *nb_ptr, void *data) · 6 unmodified lines | |||
| 465 | nb_alloc = 1; | 545 | nb_alloc = 1; |
| 466 | else | 546 | else |
| 467 | nb_alloc = nb * 2; | 547 | nb_alloc = nb * 2; |
| 468 | pp = tcc_realloc(pp, nb_alloc * sizeof(void *)); | 548 | pp = tcc_realloc(S, pp, nb_alloc * sizeof(void *)); |
| 469 | *(void***)ptab = pp; | 549 | *(void***)ptab = pp; |
| 470 | } | 550 | } |
| 471 | pp[nb++] = data; | 551 | pp[nb++] = data; |
| 472 | *nb_ptr = nb; | 552 | *nb_ptr = nb; |
| 473 | } | 553 | } |
| 474 | 554 | ||
| 475 | ST_FUNC void dynarray_reset(void *pp, int *n) | 555 | ST_FUNC void dynarray_reset(TCCState* S, void *pp, int *n) |
| 476 | { | 556 | { |
| 477 | void **p; | 557 | void **p; |
| 478 | for (p = *(void***)pp; *n; ++p, --*n) | 558 | for (p = *(void***)pp; *n; ++p, --*n) |
| 479 | if (*p) | 559 | if (*p) |
| 480 | tcc_free(*p); | 560 | tcc_free(S, *p); |
| 481 | tcc_free(*(void**)pp); | 561 | tcc_free(S, *(void**)pp); |
| 482 | *(void**)pp = NULL; | 562 | *(void**)pp = NULL; |
| 483 | } | 563 | } |
| 484 | 564 | ||
| 485 | static void tcc_split_path(TCCState *s, void *p_ary, int *p_nb_ary, const char *in) | 565 | static void tcc_split_path(TCCState *S, void *p_ary, int *p_nb_ary, const char *in) |
| 486 | { | 566 | { |
| 487 | const char *p; | 567 | const char *p; |
| 488 | do { | 568 | do { |
| 489 | int c; | 569 | int c; |
| 490 | CString str; | 570 | CString str; |
| 491 | 571 | ||
| 492 | cstr_new(&str); | 572 | cstr_new(S, &str); |
| 493 | for (p = in; c = *p, c != '\0' && c != PATHSEP[0]; ++p) { | 573 | for (p = in; c = *p, c != '\0' && c != PATHSEP[0]; ++p) { |
| 494 | if (c == '{' && p[1] && p[2] == '}') { | 574 | if (c == '{' && p[1] && p[2] == '}') { |
| 495 | c = p[1], p += 2; | 575 | c = p[1], p += 2; |
| 496 | if (c == 'B') | 576 | if (c == 'B') |
| 497 | cstr_cat(&str, s->tcc_lib_path, -1); | 577 | cstr_cat(S, &str, S->tcc_lib_path, -1); |
| 498 | if (c == 'f' && file) { | 578 | if (c == 'f' && S->tccpp_file) { |
| 499 | /* substitute current file's dir */ | 579 | /* substitute current file's dir */ |
| 500 | const char *f = file->true_filename; | 580 | const char *f = S->tccpp_file->true_filename; |
| 501 | const char *b = tcc_basename(f); | 581 | const char *b = tcc_basename(f); |
| 502 | if (b > f) | 582 | if (b > f) |
| 503 | cstr_cat(&str, f, b - f - 1); | 583 | cstr_cat(S, &str, f, b - f - 1); |
| 504 | else | 584 | else |
| 505 | cstr_cat(&str, ".", 1); | 585 | cstr_cat(S, &str, ".", 1); |
| 506 | } | 586 | } |
| 507 | } else { | 587 | } else { |
| 508 | cstr_ccat(&str, c); | 588 | cstr_ccat(S, &str, c); |
| 509 | } | 589 | } |
| 510 | } | 590 | } |
| 511 | if (str.size) { | 591 | if (str.size) { |
| 512 | cstr_ccat(&str, '\0'); | 592 | cstr_ccat(S, &str, '\0'); |
| 513 | dynarray_add(p_ary, p_nb_ary, tcc_strdup(str.data)); | 593 | dynarray_add(S, p_ary, p_nb_ary, tcc_strdup(S, str.data)); |
| 514 | } | 594 | } |
| 515 | cstr_free(&str); | 595 | cstr_free(S, &str); |
| 516 | in = p+1; | 596 | in = p+1; |
| 517 | } while (*p); | 597 | } while (*p); |
| 518 | } | 598 | } |
| @@ -528,27 +608,26 @@ static void tcc_split_path(TCCState *s, void *p_ary, int *p_nb_ary, const char * · 9 unmodified lines | |||
| 528 | /* error1() modes */ | 608 | /* error1() modes */ |
| 529 | enum { ERROR_WARN, ERROR_NOABORT, ERROR_ERROR }; | 609 | enum { ERROR_WARN, ERROR_NOABORT, ERROR_ERROR }; |
| 530 | 610 | ||
| 531 | static void error1(int mode, const char *fmt, va_list ap) | 611 | static void error1(TCCState* S, int mode, const char *fmt, va_list ap) |
| 532 | { | 612 | { |
| 533 | BufferedFile **pf, *f; | 613 | BufferedFile **pf, *f; |
| 534 | TCCState *s1 = tcc_state; | ||
| 535 | CString cs; | 614 | CString cs; |
| 536 | 615 | ||
| 537 | cstr_new(&cs); | 616 | cstr_new(S, &cs); |
| 538 | 617 | ||
| 539 | if (s1 == NULL) | 618 | if (S == NULL) |
| 540 | /* can happen only if called from tcc_malloc(): 'out of memory' */ | 619 | /* can happen only if called from tcc_malloc(): 'out of memory' */ |
| 541 | goto no_file; | 620 | goto no_file; |
| 542 | 621 | ||
| 543 | tcc_exit_state(s1); | 622 | tcc_exit_state(S); |
| 544 | 623 | ||
| 545 | if (mode == ERROR_WARN) { | 624 | if (mode == ERROR_WARN) { |
| 546 | if (s1->warn_error) | 625 | if (S->warn_error) |
| 547 | mode = ERROR_ERROR; | 626 | mode = ERROR_ERROR; |
| 548 | if (s1->warn_num) { | 627 | if (S->warn_num) { |
| 549 | /* handle tcc_warning_c(warn_option)(fmt, ...) */ | 628 | /* handle tcc_warning_c(warn_option)(fmt, ...) */ |
| 550 | int wopt = *(&s1->warn_none + s1->warn_num); | 629 | int wopt = *(&S->warn_none + S->warn_num); |
| 551 | s1->warn_num = 0; | 630 | S->warn_num = 0; |
| 552 | if (0 == (wopt & WARN_ON)) | 631 | if (0 == (wopt & WARN_ON)) |
| 553 | return; | 632 | return; |
| 554 | if (wopt & WARN_ERR) | 633 | if (wopt & WARN_ERR) |
| @@ -556,102 +635,102 @@ static void error1(int mode, const char *fmt, va_list ap) · 1 unmodified line | |||
| 556 | if (wopt & WARN_NOE) | 635 | if (wopt & WARN_NOE) |
| 557 | mode = ERROR_WARN; | 636 | mode = ERROR_WARN; |
| 558 | } | 637 | } |
| 559 | if (s1->warn_none) | 638 | if (S->warn_none) |
| 560 | return; | 639 | return; |
| 561 | } | 640 | } |
| 562 | 641 | ||
| 563 | f = NULL; | 642 | f = NULL; |
| 564 | if (s1->error_set_jmp_enabled) { /* we're called while parsing a file */ | 643 | if (S->error_set_jmp_enabled) { /* we're called while parsing a file */ |
| 565 | /* use upper file if inline ":asm:" or token ":paste:" */ | 644 | /* use upper file if inline ":asm:" or token ":paste:" */ |
| 566 | for (f = file; f && f->filename[0] == ':'; f = f->prev) | 645 | for (f = S->tccpp_file; f && f->filename[0] == ':'; f = f->prev) |
| 567 | ; | 646 | ; |
| 568 | } | 647 | } |
| 569 | if (f) { | 648 | if (f) { |
| 570 | for(pf = s1->include_stack; pf < s1->include_stack_ptr; pf++) | 649 | for(pf = S->include_stack; pf < S->include_stack_ptr; pf++) |
| 571 | cstr_printf(&cs, "In file included from %s:%d:\n", | 650 | cstr_printf(S, &cs, "In file included from %s:%d:\n", |
| 572 | (*pf)->filename, (*pf)->line_num); | 651 | (*pf)->filename, (*pf)->line_num); |
| 573 | cstr_printf(&cs, "%s:%d: ", | 652 | cstr_printf(S, &cs, "%s:%d: ", |
| 574 | f->filename, f->line_num - !!(tok_flags & TOK_FLAG_BOL)); | 653 | f->filename, (*pf)->line_num - !!(S->tccpp_tok_flags & TOK_FLAG_BOL)); |
| 575 | } else if (s1->current_filename) { | 654 | } else if (S->current_filename) { |
| 576 | cstr_printf(&cs, "%s: ", s1->current_filename); | 655 | cstr_printf(S, &cs, "%s: ", S->current_filename); |
| 577 | } | 656 | } |
| 578 | 657 | ||
| 579 | no_file: | 658 | no_file: |
| 580 | if (0 == cs.size) | 659 | if (0 == cs.size) |
| 581 | cstr_printf(&cs, "tcc: "); | 660 | cstr_printf(S, &cs, "tcc: "); |
| 582 | cstr_printf(&cs, mode == ERROR_WARN ? "warning: " : "error: "); | 661 | cstr_printf(S, &cs, mode == ERROR_WARN ? "warning: " : "error: "); |
| 583 | cstr_vprintf(&cs, fmt, ap); | 662 | cstr_vprintf(S, &cs, fmt, ap); |
| 584 | if (!s1 || !s1->error_func) { | 663 | if (!S || !S->error_func) { |
| 585 | /* default case: stderr */ | 664 | /* default case: stderr */ |
| 586 | if (s1 && s1->output_type == TCC_OUTPUT_PREPROCESS && s1->ppfp == stdout) | 665 | if (S && S->output_type == TCC_OUTPUT_PREPROCESS && S->ppfp == stdout) |
| 587 | printf("\n"); /* print a newline during tcc -E */ | 666 | printf("\n"); /* print a newline during tcc -E */ |
| 588 | fflush(stdout); /* flush -v output */ | 667 | fflush(stdout); /* flush -v output */ |
| 589 | fprintf(stderr, "%s\n", (char*)cs.data); | 668 | fprintf(stderr, "%s\n", (char*)cs.data); |
| 590 | fflush(stderr); /* print error/warning now (win32) */ | 669 | fflush(stderr); /* print error/warning now (win32) */ |
| 591 | } else { | 670 | } else { |
| 592 | s1->error_func(s1->error_opaque, (char*)cs.data); | 671 | S->error_func(S->error_opaque, (char*)cs.data); |
| 593 | } | 672 | } |
| 594 | cstr_free(&cs); | 673 | cstr_free(S, &cs); |
| 595 | if (s1) { | 674 | if (S) { |
| 596 | if (mode != ERROR_WARN) | 675 | if (mode != ERROR_WARN) |
| 597 | s1->nb_errors++; | 676 | S->nb_errors++; |
| 598 | if (mode != ERROR_ERROR) | 677 | if (mode != ERROR_ERROR) |
| 599 | return; | 678 | return; |
| 600 | if (s1->error_set_jmp_enabled) | 679 | if (S->error_set_jmp_enabled) |
| 601 | longjmp(s1->error_jmp_buf, 1); | 680 | longjmp(S->error_jmp_buf, 1); |
| 602 | } | 681 | } |
| 603 | exit(1); | 682 | exit(1); |
| 604 | } | 683 | } |
| 605 | 684 | ||
| 606 | LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque, TCCErrorFunc error_func) | 685 | LIBTCCAPI void tcc_set_error_func(TCCState *S, void *error_opaque, TCCErrorFunc error_func) |
| 607 | { | 686 | { |
| 608 | s->error_opaque = error_opaque; | 687 | S->error_opaque = error_opaque; |
| 609 | s->error_func = error_func; | 688 | S->error_func = error_func; |
| 610 | } | 689 | } |
| 611 | 690 | ||
| 612 | LIBTCCAPI TCCErrorFunc tcc_get_error_func(TCCState *s) | 691 | LIBTCCAPI TCCErrorFunc tcc_get_error_func(TCCState *S) |
| 613 | { | 692 | { |
| 614 | return s->error_func; | 693 | return S->error_func; |
| 615 | } | 694 | } |
| 616 | 695 | ||
| 617 | LIBTCCAPI void *tcc_get_error_opaque(TCCState *s) | 696 | LIBTCCAPI void *tcc_get_error_opaque(TCCState *S) |
| 618 | { | 697 | { |
| 619 | return s->error_opaque; | 698 | return S->error_opaque; |
| 620 | } | 699 | } |
| 621 | 700 | ||
| 622 | /* error without aborting current compilation */ | 701 | /* error without aborting current compilation */ |
| 623 | PUB_FUNC void _tcc_error_noabort(const char *fmt, ...) | 702 | PUB_FUNC void _tcc_error_noabort(TCCState* S, const char *fmt, ...) |
| 624 | { | 703 | { |
| 625 | va_list ap; | 704 | va_list ap; |
| 626 | va_start(ap, fmt); | 705 | va_start(ap, fmt); |
| 627 | error1(ERROR_NOABORT, fmt, ap); | 706 | error1(S, ERROR_NOABORT, fmt, ap); |
| 628 | va_end(ap); | 707 | va_end(ap); |
| 629 | } | 708 | } |
| 630 | 709 | ||
| 631 | PUB_FUNC void _tcc_error(const char *fmt, ...) | 710 | PUB_FUNC void _tcc_error(TCCState* S, const char *fmt, ...) |
| 632 | { | 711 | { |
| 633 | va_list ap; | 712 | va_list ap; |
| 634 | va_start(ap, fmt); | 713 | va_start(ap, fmt); |
| 635 | for (;;) error1(ERROR_ERROR, fmt, ap); | 714 | for (;;) error1(S, ERROR_ERROR, fmt, ap); |
| 636 | } | 715 | } |
| 637 | 716 | ||
| 638 | PUB_FUNC void _tcc_warning(const char *fmt, ...) | 717 | PUB_FUNC void _tcc_warning(TCCState* S, const char *fmt, ...) |
| 639 | { | 718 | { |
| 640 | va_list ap; | 719 | va_list ap; |
| 641 | va_start(ap, fmt); | 720 | va_start(ap, fmt); |
| 642 | error1(ERROR_WARN, fmt, ap); | 721 | error1(S, ERROR_WARN, fmt, ap); |
| 643 | va_end(ap); | 722 | va_end(ap); |
| 644 | } | 723 | } |
| 645 | 724 | ||
| 646 | /********************************************************/ | 725 | /********************************************************/ |
| 647 | /* I/O layer */ | 726 | /* I/O layer */ |
| 648 | 727 | ||
| 649 | ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen) | 728 | ST_FUNC void tcc_open_bf(TCCState *S, const char *filename, int initlen) |
| 650 | { | 729 | { |
| 651 | BufferedFile *bf; | 730 | BufferedFile *bf; |
| 652 | int buflen = initlen ? initlen : IO_BUF_SIZE; | 731 | int buflen = initlen ? initlen : IO_BUF_SIZE; |
| 653 | 732 | ||
| 654 | bf = tcc_mallocz(sizeof(BufferedFile) + buflen); | 733 | bf = tcc_mallocz(S, sizeof(BufferedFile) + buflen); |
| 655 | bf->buf_ptr = bf->buffer; | 734 | bf->buf_ptr = bf->buffer; |
| 656 | bf->buf_end = bf->buffer + initlen; | 735 | bf->buf_end = bf->buffer + initlen; |
| 657 | bf->buf_end[0] = CH_EOB; /* put eob symbol */ | 736 | bf->buf_end[0] = CH_EOB; /* put eob symbol */ |
| @@ -661,52 +740,51 @@ ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen) · 3 unmodified lines | |||
| 661 | #endif | 740 | #endif |
| 662 | bf->true_filename = bf->filename; | 741 | bf->true_filename = bf->filename; |
| 663 | bf->line_num = 1; | 742 | bf->line_num = 1; |
| 664 | bf->ifdef_stack_ptr = s1->ifdef_stack_ptr; | 743 | bf->ifdef_stack_ptr = S->ifdef_stack_ptr; |
| 665 | bf->fd = -1; | 744 | bf->fd = -1; |
| 666 | bf->prev = file; | 745 | bf->prev = S->tccpp_file; |
| 667 | file = bf; | 746 | S->tccpp_file = bf; |
| 668 | tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; | 747 | S->tccpp_tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; |
| 669 | } | 748 | } |
| 670 | 749 | ||
| 671 | ST_FUNC void tcc_close(void) | 750 | ST_FUNC void tcc_close(TCCState* S) |
| 672 | { | 751 | { |
| 673 | TCCState *s1 = tcc_state; | 752 | BufferedFile *bf = S->tccpp_file; |
| 674 | BufferedFile *bf = file; | ||
| 675 | if (bf->fd > 0) { | 753 | if (bf->fd > 0) { |
| 676 | close(bf->fd); | 754 | close(bf->fd); |
| 677 | total_lines += bf->line_num; | 755 | total_lines += bf->line_num; |
| 678 | } | 756 | } |
| 679 | if (bf->true_filename != bf->filename) | 757 | if (bf->true_filename != bf->filename) |
| 680 | tcc_free(bf->true_filename); | 758 | tcc_free(S, bf->true_filename); |
| 681 | file = bf->prev; | 759 | S->tccpp_file = bf->prev; |
| 682 | tcc_free(bf); | 760 | tcc_free(S, bf); |
| 683 | } | 761 | } |
| 684 | 762 | ||
| 685 | static int _tcc_open(TCCState *s1, const char *filename) | 763 | static int _tcc_open(TCCState *S, const char *filename) |
| 686 | { | 764 | { |
| 687 | int fd; | 765 | int fd; |
| 688 | if (strcmp(filename, "-") == 0) | 766 | if (strcmp(filename, "-") == 0) |
| 689 | fd = 0, filename = "<stdin>"; | 767 | fd = 0, filename = "<stdin>"; |
| 690 | else | 768 | else |
| 691 | fd = open(filename, O_RDONLY | O_BINARY); | 769 | fd = open(filename, O_RDONLY | O_BINARY); |
| 692 | if ((s1->verbose == 2 && fd >= 0) || s1->verbose == 3) | 770 | if ((S->verbose == 2 && fd >= 0) || S->verbose == 3) |
| 693 | printf("%s %*s%s\n", fd < 0 ? "nf":"->", | 771 | printf("%s %*s%s\n", fd < 0 ? "nf":"->", |
| 694 | (int)(s1->include_stack_ptr - s1->include_stack), "", filename); | 772 | (int)(S->include_stack_ptr - S->include_stack), "", filename); |
| 695 | return fd; | 773 | return fd; |
| 696 | } | 774 | } |
| 697 | 775 | ||
| 698 | ST_FUNC int tcc_open(TCCState *s1, const char *filename) | 776 | ST_FUNC int tcc_open(TCCState *S, const char *filename) |
| 699 | { | 777 | { |
| 700 | int fd = _tcc_open(s1, filename); | 778 | int fd = _tcc_open(S, filename); |
| 701 | if (fd < 0) | 779 | if (fd < 0) |
| 702 | return -1; | 780 | return -1; |
| 703 | tcc_open_bf(s1, filename, 0); | 781 | tcc_open_bf(S, filename, 0); |
| 704 | file->fd = fd; | 782 | S->tccpp_file->fd = fd; |
| 705 | return 0; | 783 | return 0; |
| 706 | } | 784 | } |
| 707 | 785 | ||
| 708 | /* compile the file opened in 'file'. Return non zero if errors. */ | 786 | /* compile the file opened in 'file'. Return non zero if errors. */ |
| 709 | static int tcc_compile(TCCState *s1, int filetype, const char *str, int fd) | 787 | static int tcc_compile(TCCState *S, int filetype, const char *str, int fd) |
| 710 | { | 788 | { |
| 711 | /* Here we enter the code section where we use the global variables for | 789 | /* Here we enter the code section where we use the global variables for |
| 712 | parsing and code generation (tccpp.c, tccgen.c, <target>-gen.c). | 790 | parsing and code generation (tccpp.c, tccgen.c, <target>-gen.c). |
| @@ -715,62 +793,62 @@ static int tcc_compile(TCCState *s1, int filetype, const char *str, int fd) · 2 unmodified lines | |||
| 715 | Alternatively we could use thread local storage for those global | 793 | Alternatively we could use thread local storage for those global |
| 716 | variables, which may or may not have advantages */ | 794 | variables, which may or may not have advantages */ |
| 717 | 795 | ||
| 718 | tcc_enter_state(s1); | 796 | tcc_enter_state(S); |
| 719 | s1->error_set_jmp_enabled = 1; | 797 | S->error_set_jmp_enabled = 1; |
| 720 | 798 | ||
| 721 | if (setjmp(s1->error_jmp_buf) == 0) { | 799 | if (setjmp(S->error_jmp_buf) == 0) { |
| 722 | s1->nb_errors = 0; | 800 | S->nb_errors = 0; |
| 723 | 801 | ||
| 724 | if (fd == -1) { | 802 | if (fd == -1) { |
| 725 | int len = strlen(str); | 803 | int len = strlen(str); |
| 726 | tcc_open_bf(s1, "<string>", len); | 804 | tcc_open_bf(S, "<string>", len); |
| 727 | memcpy(file->buffer, str, len); | 805 | memcpy(S->tccpp_file->buffer, str, len); |
| 728 | } else { | 806 | } else { |
| 729 | tcc_open_bf(s1, str, 0); | 807 | tcc_open_bf(S, str, 0); |
| 730 | file->fd = fd; | 808 | S->tccpp_file->fd = fd; |
| 731 | } | 809 | } |
| 732 | 810 | ||
| 733 | tccelf_begin_file(s1); | 811 | tccelf_begin_file(S); |
| 734 | preprocess_start(s1, filetype); | 812 | preprocess_start(S, filetype); |
| 735 | tccgen_init(s1); | 813 | tccgen_init(S); |
| 736 | if (s1->output_type == TCC_OUTPUT_PREPROCESS) { | 814 | if (S->output_type == TCC_OUTPUT_PREPROCESS) { |
| 737 | tcc_preprocess(s1); | 815 | tcc_preprocess(S); |
| 738 | } else if (filetype & (AFF_TYPE_ASM | AFF_TYPE_ASMPP)) { | 816 | } else if (filetype & (AFF_TYPE_ASM | AFF_TYPE_ASMPP)) { |
| 739 | tcc_assemble(s1, !!(filetype & AFF_TYPE_ASMPP)); | 817 | tcc_assemble(S, !!(filetype & AFF_TYPE_ASMPP)); |
| 740 | } else { | 818 | } else { |
| 741 | tccgen_compile(s1); | 819 | tccgen_compile(S); |
| 742 | } | 820 | } |
| 743 | } | 821 | } |
| 744 | tccgen_finish(s1); | 822 | tccgen_finish(S); |
| 745 | preprocess_end(s1); | 823 | preprocess_end(S); |
| 746 | 824 | ||
| 747 | s1->error_set_jmp_enabled = 0; | 825 | S->error_set_jmp_enabled = 0; |
| 748 | tcc_exit_state(s1); | 826 | tcc_exit_state(S); |
| 749 | 827 | ||
| 750 | tccelf_end_file(s1); | 828 | tccelf_end_file(S); |
| 751 | return s1->nb_errors != 0 ? -1 : 0; | 829 | return S->nb_errors != 0 ? -1 : 0; |
| 752 | } | 830 | } |
| 753 | 831 | ||
| 754 | LIBTCCAPI int tcc_compile_string(TCCState *s, const char *str) | 832 | LIBTCCAPI int tcc_compile_string(TCCState *S, const char *str) |
| 755 | { | 833 | { |
| 756 | return tcc_compile(s, s->filetype, str, -1); | 834 | return tcc_compile(S, S->filetype, str, -1); |
| 757 | } | 835 | } |
| 758 | 836 | ||
| 759 | /* define a preprocessor symbol. value can be NULL, sym can be "sym=val" */ | 837 | /* define a preprocessor symbol. value can be NULL, sym can be "sym=val" */ |
| 760 | LIBTCCAPI void tcc_define_symbol(TCCState *s1, const char *sym, const char *value) | 838 | LIBTCCAPI void tcc_define_symbol(TCCState *S, const char *sym, const char *value) |
| 761 | { | 839 | { |
| 762 | const char *eq; | 840 | const char *eq; |
| 763 | if (NULL == (eq = strchr(sym, '='))) | 841 | if (NULL == (eq = strchr(sym, '='))) |
| 764 | eq = strchr(sym, 0); | 842 | eq = strchr(sym, 0); |
| 765 | if (NULL == value) | 843 | if (NULL == value) |
| 766 | value = *eq ? eq + 1 : "1"; | 844 | value = *eq ? eq + 1 : "1"; |
| 767 | cstr_printf(&s1->cmdline_defs, "#define %.*s %s\n", (int)(eq-sym), sym, value); | 845 | cstr_printf(S, &S->cmdline_defs, "#define %.*s %s\n", (int)(eq-sym), sym, value); |
| 768 | } | 846 | } |
| 769 | 847 | ||
| 770 | /* undefine a preprocessor symbol */ | 848 | /* undefine a preprocessor symbol */ |
| 771 | LIBTCCAPI void tcc_undefine_symbol(TCCState *s1, const char *sym) | 849 | LIBTCCAPI void tcc_undefine_symbol(TCCState *S, const char *sym) |
| 772 | { | 850 | { |
| 773 | cstr_printf(&s1->cmdline_defs, "#undef %s\n", sym); | 851 | cstr_printf(S, &S->cmdline_defs, "#undef %s\n", sym); |
| 774 | } | 852 | } |
| 775 | 853 | ||
| 776 | 854 | ||
| @@ -778,7 +856,7 @@ LIBTCCAPI TCCState *tcc_new(void) · 1 unmodified line | |||
| 778 | { | 856 | { |
| 779 | TCCState *s; | 857 | TCCState *s; |
| 780 | 858 | ||
| 781 | s = tcc_mallocz(sizeof(TCCState)); | 859 | s = tcc_mallocz_base(sizeof(TCCState)); |
| 782 | if (!s) | 860 | if (!s) |
| 783 | return NULL; | 861 | return NULL; |
| 784 | #ifdef MEM_DEBUG | 862 | #ifdef MEM_DEBUG |
| @@ -820,153 +898,153 @@ LIBTCCAPI TCCState *tcc_new(void) · 35 unmodified lines | |||
| 820 | return s; | 898 | return s; |
| 821 | } | 899 | } |
| 822 | 900 | ||
| 823 | LIBTCCAPI void tcc_delete(TCCState *s1) | 901 | LIBTCCAPI void tcc_delete(TCCState *S) |
| 824 | { | 902 | { |
| 825 | /* free sections */ | 903 | /* free sections */ |
| 826 | tccelf_delete(s1); | 904 | tccelf_delete(S); |
| 827 | 905 | ||
| 828 | /* free library paths */ | 906 | /* free library paths */ |
| 829 | dynarray_reset(&s1->library_paths, &s1->nb_library_paths); | 907 | dynarray_reset(S, &S->library_paths, &S->nb_library_paths); |
| 830 | dynarray_reset(&s1->crt_paths, &s1->nb_crt_paths); | 908 | dynarray_reset(S, &S->crt_paths, &S->nb_crt_paths); |
| 831 | 909 | ||
| 832 | /* free include paths */ | 910 | /* free include paths */ |
| 833 | dynarray_reset(&s1->include_paths, &s1->nb_include_paths); | 911 | dynarray_reset(S, &S->include_paths, &S->nb_include_paths); |
| 834 | dynarray_reset(&s1->sysinclude_paths, &s1->nb_sysinclude_paths); | 912 | dynarray_reset(S, &S->sysinclude_paths, &S->nb_sysinclude_paths); |
| 835 | 913 | ||
| 836 | tcc_free(s1->tcc_lib_path); | 914 | tcc_free(S, S->tcc_lib_path); |
| 837 | tcc_free(s1->soname); | 915 | tcc_free(S, S->soname); |
| 838 | tcc_free(s1->rpath); | 916 | tcc_free(S, S->rpath); |
| 839 | tcc_free(s1->init_symbol); | 917 | tcc_free(S, S->init_symbol); |
| 840 | tcc_free(s1->fini_symbol); | 918 | tcc_free(S, S->fini_symbol); |
| 841 | tcc_free(s1->outfile); | 919 | tcc_free(S, S->outfile); |
| 842 | tcc_free(s1->deps_outfile); | 920 | tcc_free(S, S->deps_outfile); |
| 843 | dynarray_reset(&s1->files, &s1->nb_files); | 921 | dynarray_reset(S, &S->files, &S->nb_files); |
| 844 | dynarray_reset(&s1->target_deps, &s1->nb_target_deps); | 922 | dynarray_reset(S, &S->target_deps, &S->nb_target_deps); |
| 845 | dynarray_reset(&s1->pragma_libs, &s1->nb_pragma_libs); | 923 | dynarray_reset(S, &S->pragma_libs, &S->nb_pragma_libs); |
| 846 | dynarray_reset(&s1->argv, &s1->argc); | 924 | dynarray_reset(S, &S->argv, &S->argc); |
| 847 | cstr_free(&s1->cmdline_defs); | 925 | cstr_free(S, &S->cmdline_defs); |
| 848 | cstr_free(&s1->cmdline_incl); | 926 | cstr_free(S, &S->cmdline_incl); |
| 849 | #ifdef TCC_IS_NATIVE | 927 | #ifdef TCC_IS_NATIVE |
| 850 | /* free runtime memory */ | 928 | /* free runtime memory */ |
| 851 | tcc_run_free(s1); | 929 | tcc_run_free(S); |
| 852 | #endif | 930 | #endif |
| 853 | 931 | ||
| 854 | tcc_free(s1); | 932 | tcc_free_base(S); |
| 855 | #ifdef MEM_DEBUG | 933 | #ifdef MEM_DEBUG |
| 856 | if (0 == --nb_states) | 934 | if (0 == --nb_states) |
| 857 | tcc_memcheck(); | 935 | tcc_memcheck(); |
| 858 | #endif | 936 | #endif |
| 859 | } | 937 | } |
| 860 | 938 | ||
| 861 | LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) | 939 | LIBTCCAPI int tcc_set_output_type(TCCState *S, int output_type) |
| 862 | { | 940 | { |
| 863 | s->output_type = output_type; | 941 | S->output_type = output_type; |
| 864 | 942 | ||
| 865 | if (!s->nostdinc) { | 943 | if (!S->nostdinc) { |
| 866 | /* default include paths */ | 944 | /* default include paths */ |
| 867 | /* -isystem paths have already been handled */ | 945 | /* -isystem paths have already been handled */ |
| 868 | tcc_add_sysinclude_path(s, CONFIG_TCC_SYSINCLUDEPATHS); | 946 | tcc_add_sysinclude_path(S, CONFIG_TCC_SYSINCLUDEPATHS); |
| 869 | } | 947 | } |
| 870 | #ifdef CONFIG_TCC_BCHECK | 948 | #ifdef CONFIG_TCC_BCHECK |
| 871 | if (s->do_bounds_check) { | 949 | if (S->do_bounds_check) { |
| 872 | /* if bound checking, then add corresponding sections */ | 950 | /* if bound checking, then add corresponding sections */ |
| 873 | tccelf_bounds_new(s); | 951 | tccelf_bounds_new(S); |
| 874 | } | 952 | } |
| 875 | #endif | 953 | #endif |
| 876 | if (s->do_debug) { | 954 | if (S->do_debug) { |
| 877 | /* add debug sections */ | 955 | /* add debug sections */ |
| 878 | tccelf_stab_new(s); | 956 | tccelf_stab_new(S); |
| 879 | } | 957 | } |
| 880 | if (output_type == TCC_OUTPUT_OBJ) { | 958 | if (output_type == TCC_OUTPUT_OBJ) { |
| 881 | /* always elf for objects */ | 959 | /* always elf for objects */ |
| 882 | s->output_format = TCC_OUTPUT_FORMAT_ELF; | 960 | S->output_format = TCC_OUTPUT_FORMAT_ELF; |
| 883 | return 0; | 961 | return 0; |
| 884 | } | 962 | } |
| 885 | 963 | ||
| 886 | tcc_add_library_path(s, CONFIG_TCC_LIBPATHS); | 964 | tcc_add_library_path(S, CONFIG_TCC_LIBPATHS); |
| 887 | 965 | ||
| 888 | #ifdef TCC_TARGET_PE | 966 | #ifdef TCC_TARGET_PE |
| 889 | # ifdef _WIN32 | 967 | # ifdef _WIN32 |
| 890 | /* allow linking with system dll's directly */ | 968 | /* allow linking with system dll's directly */ |
| 891 | tcc_add_systemdir(s); | 969 | tcc_add_systemdir(S); |
| 892 | # endif | 970 | # endif |
| 893 | /* target PE has its own startup code in libtcc1.a */ | 971 | /* target PE has its own startup code in libtcc1.a */ |
| 894 | return 0; | 972 | return 0; |
| 895 | 973 | ||
| 896 | #elif defined TCC_TARGET_MACHO | 974 | #elif defined TCC_TARGET_MACHO |
| 897 | # ifdef TCC_IS_NATIVE | 975 | # ifdef TCC_IS_NATIVE |
| 898 | tcc_add_macos_sdkpath(s); | 976 | tcc_add_macos_sdkpath(S); |
| 899 | # endif | 977 | # endif |
| 900 | /* Mach-O with LC_MAIN doesn't need any crt startup code. */ | 978 | /* Mach-O with LC_MAIN doesn't need any crt startup code. */ |
| 901 | return 0; | 979 | return 0; |
| 902 | 980 | ||
| 903 | #else | 981 | #else |
| 904 | /* paths for crt objects */ | 982 | /* paths for crt objects */ |
| 905 | tcc_split_path(s, &s->crt_paths, &s->nb_crt_paths, CONFIG_TCC_CRTPREFIX); | 983 | tcc_split_path(S, &S->crt_paths, &S->nb_crt_paths, CONFIG_TCC_CRTPREFIX); |
| 906 | /* add libc crt1/crti objects */ | 984 | /* add libc crt1/crti objects */ |
| 907 | if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) && | 985 | if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) && |
| 908 | !s->nostdlib) { | 986 | !S->nostdlib) { |
| 909 | #if TARGETOS_OpenBSD | 987 | #if TARGETOS_OpenBSD |
| 910 | if (output_type != TCC_OUTPUT_DLL) | 988 | if (output_type != TCC_OUTPUT_DLL) |
| 911 | tcc_add_crt(s, "crt0.o"); | 989 | tcc_add_crt(S, "crt0.o"); |
| 912 | if (output_type == TCC_OUTPUT_DLL) | 990 | if (output_type == TCC_OUTPUT_DLL) |
| 913 | tcc_add_crt(s, "crtbeginS.o"); | 991 | tcc_add_crt(S, "crtbeginS.o"); |
| 914 | else | 992 | else |
| 915 | tcc_add_crt(s, "crtbegin.o"); | 993 | tcc_add_crt(S, "crtbegin.o"); |
| 916 | #elif TARGETOS_FreeBSD | 994 | #elif TARGETOS_FreeBSD |
| 917 | if (output_type != TCC_OUTPUT_DLL) | 995 | if (output_type != TCC_OUTPUT_DLL) |
| 918 | tcc_add_crt(s, "crt1.o"); | 996 | tcc_add_crt(S, "crt1.o"); |
| 919 | tcc_add_crt(s, "crti.o"); | 997 | tcc_add_crt(S, "crti.o"); |
| 920 | if (s->static_link) | 998 | if (S->static_link) |
| 921 | tcc_add_crt(s, "crtbeginT.o"); | 999 | tcc_add_crt(S, "crtbeginT.o"); |
| 922 | else if (output_type == TCC_OUTPUT_DLL) | 1000 | else if (output_type == TCC_OUTPUT_DLL) |
| 923 | tcc_add_crt(s, "crtbeginS.o"); | 1001 | tcc_add_crt(S, "crtbeginS.o"); |
| 924 | else | 1002 | else |
| 925 | tcc_add_crt(s, "crtbegin.o"); | 1003 | tcc_add_crt(S, "crtbegin.o"); |
| 926 | #elif TARGETOS_NetBSD | 1004 | #elif TARGETOS_NetBSD |
| 927 | if (output_type != TCC_OUTPUT_DLL) | 1005 | if (output_type != TCC_OUTPUT_DLL) |
| 928 | tcc_add_crt(s, "crt0.o"); | 1006 | tcc_add_crt(S, "crt0.o"); |
| 929 | tcc_add_crt(s, "crti.o"); | 1007 | tcc_add_crt(S, "crti.o"); |
| 930 | if (s->static_link) | 1008 | if (S->static_link) |
| 931 | tcc_add_crt(s, "crtbeginT.o"); | 1009 | tcc_add_crt(S, "crtbeginT.o"); |
| 932 | else if (output_type == TCC_OUTPUT_DLL) | 1010 | else if (output_type == TCC_OUTPUT_DLL) |
| 933 | tcc_add_crt(s, "crtbeginS.o"); | 1011 | tcc_add_crt(S, "crtbeginS.o"); |
| 934 | else | 1012 | else |
| 935 | tcc_add_crt(s, "crtbegin.o"); | 1013 | tcc_add_crt(S, "crtbegin.o"); |
| 936 | #else | 1014 | #else |
| 937 | if (output_type != TCC_OUTPUT_DLL) | 1015 | if (output_type != TCC_OUTPUT_DLL) |
| 938 | tcc_add_crt(s, "crt1.o"); | 1016 | tcc_add_crt(S, "crt1.o"); |
| 939 | tcc_add_crt(s, "crti.o"); | 1017 | tcc_add_crt(S, "crti.o"); |
| 940 | #endif | 1018 | #endif |
| 941 | } | 1019 | } |
| 942 | return 0; | 1020 | return 0; |
| 943 | #endif | 1021 | #endif |
| 944 | } | 1022 | } |
| 945 | 1023 | ||
| 946 | LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname) | 1024 | LIBTCCAPI int tcc_add_include_path(TCCState *S, const char *pathname) |
| 947 | { | 1025 | { |
| 948 | tcc_split_path(s, &s->include_paths, &s->nb_include_paths, pathname); | 1026 | tcc_split_path(S, &S->include_paths, &S->nb_include_paths, pathname); |
| 949 | return 0; | 1027 | return 0; |
| 950 | } | 1028 | } |
| 951 | 1029 | ||
| 952 | LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname) | 1030 | LIBTCCAPI int tcc_add_sysinclude_path(TCCState *S, const char *pathname) |
| 953 | { | 1031 | { |
| 954 | tcc_split_path(s, &s->sysinclude_paths, &s->nb_sysinclude_paths, pathname); | 1032 | tcc_split_path(S, &S->sysinclude_paths, &S->nb_sysinclude_paths, pathname); |
| 955 | return 0; | 1033 | return 0; |
| 956 | } | 1034 | } |
| 957 | 1035 | ||
| 958 | ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllname) | 1036 | ST_FUNC DLLReference *tcc_add_dllref(TCCState *S, const char *dllname) |
| 959 | { | 1037 | { |
| 960 | DLLReference *ref = tcc_mallocz(sizeof(DLLReference) + strlen(dllname)); | 1038 | DLLReference *ref = tcc_mallocz(S, sizeof(DLLReference) + strlen(dllname)); |
| 961 | strcpy(ref->name, dllname); | 1039 | strcpy(ref->name, dllname); |
| 962 | dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, ref); | 1040 | dynarray_add(S, &S->loaded_dlls, &S->nb_loaded_dlls, ref); |
| 963 | return ref; | 1041 | return ref; |
| 964 | } | 1042 | } |
| 965 | 1043 | ||
| 966 | /* OpenBSD: choose latest from libxxx.so.x.y versions */ | 1044 | /* OpenBSD: choose latest from libxxx.so.x.y versions */ |
| 967 | #if defined TARGETOS_OpenBSD && !defined _WIN32 | 1045 | #if defined TARGETOS_OpenBSD && !defined _WIN32 |
| 968 | #include <glob.h> | 1046 | #include <glob.h> |
| 969 | static int tcc_glob_so(TCCState *s1, const char *pattern, char *buf, int size) | 1047 | static int tcc_glob_so(TCCState *S, const char *pattern, char *buf, int size) |
| 970 | { | 1048 | { |
| 971 | const char *star; | 1049 | const char *star; |
| 972 | glob_t g; | 1050 | glob_t g; |
| @@ -988,25 +1066,25 @@ static int tcc_glob_so(TCCState *s1, const char *pattern, char *buf, int size) · 15 unmodified lines | |||
| 988 | } | 1066 | } |
| 989 | #endif | 1067 | #endif |
| 990 | 1068 | ||
| 991 | ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) | 1069 | ST_FUNC int tcc_add_file_internal(TCCState *S, const char *filename, int flags) |
| 992 | { | 1070 | { |
| 993 | int fd, ret = -1; | 1071 | int fd, ret = -1; |
| 994 | 1072 | ||
| 995 | #if defined TARGETOS_OpenBSD && !defined _WIN32 | 1073 | #if defined TARGETOS_OpenBSD && !defined _WIN32 |
| 996 | char buf[1024]; | 1074 | char buf[1024]; |
| 997 | if (tcc_glob_so(s1, filename, buf, sizeof buf) >= 0) | 1075 | if (tcc_glob_so(S, filename, buf, sizeof buf) >= 0) |
| 998 | filename = buf; | 1076 | filename = buf; |
| 999 | #endif | 1077 | #endif |
| 1000 | 1078 | ||
| 1001 | /* open the file */ | 1079 | /* open the file */ |
| 1002 | fd = _tcc_open(s1, filename); | 1080 | fd = _tcc_open(S, filename); |
| 1003 | if (fd < 0) { | 1081 | if (fd < 0) { |
| 1004 | if (flags & AFF_PRINT_ERROR) | 1082 | if (flags & AFF_PRINT_ERROR) |
| 1005 | tcc_error_noabort("file '%s' not found", filename); | 1083 | tcc_error_noabort(S, "file '%s' not found", filename); |
| 1006 | return ret; | 1084 | return ret; |
| 1007 | } | 1085 | } |
| 1008 | 1086 | ||
| 1009 | s1->current_filename = filename; | 1087 | S->current_filename = filename; |
| 1010 | if (flags & AFF_TYPE_BIN) { | 1088 | if (flags & AFF_TYPE_BIN) { |
| 1011 | ElfW(Ehdr) ehdr; | 1089 | ElfW(Ehdr) ehdr; |
| 1012 | int obj_type; | 1090 | int obj_type; |
| @@ -1017,22 +1095,22 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 4 unmodified lines | |||
| 1017 | switch (obj_type) { | 1095 | switch (obj_type) { |
| 1018 | 1096 | ||
| 1019 | case AFF_BINTYPE_REL: | 1097 | case AFF_BINTYPE_REL: |
| 1020 | ret = tcc_load_object_file(s1, fd, 0); | 1098 | ret = tcc_load_object_file(S, fd, 0); |
| 1021 | break; | 1099 | break; |
| 1022 | 1100 | ||
| 1023 | case AFF_BINTYPE_AR: | 1101 | case AFF_BINTYPE_AR: |
| 1024 | ret = tcc_load_archive(s1, fd, !(flags & AFF_WHOLE_ARCHIVE)); | 1102 | ret = tcc_load_archive(S, fd, !(flags & AFF_WHOLE_ARCHIVE)); |
| 1025 | break; | 1103 | break; |
| 1026 | 1104 | ||
| 1027 | #ifdef TCC_TARGET_PE | 1105 | #ifdef TCC_TARGET_PE |
| 1028 | default: | 1106 | default: |
| 1029 | ret = pe_load_file(s1, fd, filename); | 1107 | ret = pe_load_file(S, fd, filename); |
| 1030 | goto check_success; | 1108 | goto check_success; |
| 1031 | 1109 | ||
| 1032 | #elif defined TCC_TARGET_MACHO | 1110 | #elif defined TCC_TARGET_MACHO |
| 1033 | case AFF_BINTYPE_DYN: | 1111 | case AFF_BINTYPE_DYN: |
| 1034 | case_dyn_or_tbd: | 1112 | case_dyn_or_tbd: |
| 1035 | if (s1->output_type == TCC_OUTPUT_MEMORY) { | 1113 | if (S->output_type == TCC_OUTPUT_MEMORY) { |
| 1036 | #ifdef TCC_IS_NATIVE | 1114 | #ifdef TCC_IS_NATIVE |
| 1037 | void* dl; | 1115 | void* dl; |
| 1038 | const char* soname = filename; | 1116 | const char* soname = filename; |
| @@ -1040,14 +1118,14 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 1 unmodified line | |||
| 1040 | soname = macho_tbd_soname(filename); | 1118 | soname = macho_tbd_soname(filename); |
| 1041 | dl = dlopen(soname, RTLD_GLOBAL | RTLD_LAZY); | 1119 | dl = dlopen(soname, RTLD_GLOBAL | RTLD_LAZY); |
| 1042 | if (dl) | 1120 | if (dl) |
| 1043 | tcc_add_dllref(s1, soname)->handle = dl, ret = 0; | 1121 | tcc_add_dllref(S, soname)->handle = dl, ret = 0; |
| 1044 | if (filename != soname) | 1122 | if (filename != soname) |
| 1045 | tcc_free((void *)soname); | 1123 | tcc_free(S, (void *)soname); |
| 1046 | #endif | 1124 | #endif |
| 1047 | } else if (obj_type == AFF_BINTYPE_DYN) { | 1125 | } else if (obj_type == AFF_BINTYPE_DYN) { |
| 1048 | ret = macho_load_dll(s1, fd, filename, (flags & AFF_REFERENCED_DLL) != 0); | 1126 | ret = macho_load_dll(S, fd, filename, (flags & AFF_REFERENCED_DLL) != 0); |
| 1049 | } else { | 1127 | } else { |
| 1050 | ret = macho_load_tbd(s1, fd, filename, (flags & AFF_REFERENCED_DLL) != 0); | 1128 | ret = macho_load_tbd(S, fd, filename, (flags & AFF_REFERENCED_DLL) != 0); |
| 1051 | } | 1129 | } |
| 1052 | break; | 1130 | break; |
| 1053 | default: | 1131 | default: |
| @@ -1064,47 +1142,47 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 10 unmodified lines | |||
| 1064 | 1142 | ||
| 1065 | #else /* unix */ | 1143 | #else /* unix */ |
| 1066 | case AFF_BINTYPE_DYN: | 1144 | case AFF_BINTYPE_DYN: |
| 1067 | if (s1->output_type == TCC_OUTPUT_MEMORY) { | 1145 | if (S->output_type == TCC_OUTPUT_MEMORY) { |
| 1068 | #ifdef TCC_IS_NATIVE | 1146 | #ifdef TCC_IS_NATIVE |
| 1069 | void* dl = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY); | 1147 | void* dl = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY); |
| 1070 | if (dl) | 1148 | if (dl) |
| 1071 | tcc_add_dllref(s1, filename)->handle = dl, ret = 0; | 1149 | tcc_add_dllref(S, filename)->handle = dl, ret = 0; |
| 1072 | #endif | 1150 | #endif |
| 1073 | } else | 1151 | } else |
| 1074 | ret = tcc_load_dll(s1, fd, filename, (flags & AFF_REFERENCED_DLL) != 0); | 1152 | ret = tcc_load_dll(S, fd, filename, (flags & AFF_REFERENCED_DLL) != 0); |
| 1075 | break; | 1153 | break; |
| 1076 | 1154 | ||
| 1077 | default: | 1155 | default: |
| 1078 | /* as GNU ld, consider it is an ld script if not recognized */ | 1156 | /* as GNU ld, consider it is an ld script if not recognized */ |
| 1079 | ret = tcc_load_ldscript(s1, fd); | 1157 | ret = tcc_load_ldscript(S, fd); |
| 1080 | goto check_success; | 1158 | goto check_success; |
| 1081 | 1159 | ||
| 1082 | #endif /* pe / macos / unix */ | 1160 | #endif /* pe / macos / unix */ |
| 1083 | 1161 | ||
| 1084 | check_success: | 1162 | check_success: |
| 1085 | if (ret < 0) | 1163 | if (ret < 0) |
| 1086 | tcc_error_noabort("%s: unrecognized file type", filename); | 1164 | tcc_error_noabort(S, "%s: unrecognized file type", filename); |
| 1087 | break; | 1165 | break; |
| 1088 | 1166 | ||
| 1089 | #ifdef TCC_TARGET_COFF | 1167 | #ifdef TCC_TARGET_COFF |
| 1090 | case AFF_BINTYPE_C67: | 1168 | case AFF_BINTYPE_C67: |
| 1091 | ret = tcc_load_coff(s1, fd); | 1169 | ret = tcc_load_coff(S, fd); |
| 1092 | break; | 1170 | break; |
| 1093 | #endif | 1171 | #endif |
| 1094 | } | 1172 | } |
| 1095 | close(fd); | 1173 | close(fd); |
| 1096 | } else { | 1174 | } else { |
| 1097 | /* update target deps */ | 1175 | /* update target deps */ |
| 1098 | dynarray_add(&s1->target_deps, &s1->nb_target_deps, tcc_strdup(filename)); | 1176 | dynarray_add(S, &S->target_deps, &S->nb_target_deps, tcc_strdup(S, filename)); |
| 1099 | ret = tcc_compile(s1, flags, filename, fd); | 1177 | ret = tcc_compile(S, flags, filename, fd); |
| 1100 | } | 1178 | } |
| 1101 | s1->current_filename = NULL; | 1179 | S->current_filename = NULL; |
| 1102 | return ret; | 1180 | return ret; |
| 1103 | } | 1181 | } |
| 1104 | 1182 | ||
| 1105 | LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename) | 1183 | LIBTCCAPI int tcc_add_file(TCCState *S, const char *filename) |
| 1106 | { | 1184 | { |
| 1107 | int filetype = s->filetype; | 1185 | int filetype = S->filetype; |
| 1108 | if (0 == (filetype & AFF_TYPE_MASK)) { | 1186 | if (0 == (filetype & AFF_TYPE_MASK)) { |
| 1109 | /* use a file extension to detect a filetype */ | 1187 | /* use a file extension to detect a filetype */ |
| 1110 | const char *ext = tcc_fileextension(filename); | 1188 | const char *ext = tcc_fileextension(filename); |
| @@ -1124,16 +1202,16 @@ LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename) · 13 unmodified lines | |||
| 1124 | filetype = AFF_TYPE_C; | 1202 | filetype = AFF_TYPE_C; |
| 1125 | } | 1203 | } |
| 1126 | } | 1204 | } |
| 1127 | return tcc_add_file_internal(s, filename, filetype | AFF_PRINT_ERROR); | 1205 | return tcc_add_file_internal(S, filename, filetype | AFF_PRINT_ERROR); |
| 1128 | } | 1206 | } |
| 1129 | 1207 | ||
| 1130 | LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname) | 1208 | LIBTCCAPI int tcc_add_library_path(TCCState *S, const char *pathname) |
| 1131 | { | 1209 | { |
| 1132 | tcc_split_path(s, &s->library_paths, &s->nb_library_paths, pathname); | 1210 | tcc_split_path(S, &S->library_paths, &S->nb_library_paths, pathname); |
| 1133 | return 0; | 1211 | return 0; |
| 1134 | } | 1212 | } |
| 1135 | 1213 | ||
| 1136 | static int tcc_add_library_internal(TCCState *s, const char *fmt, | 1214 | static int tcc_add_library_internal(TCCState *S, const char *fmt, |
| 1137 | const char *filename, int flags, char **paths, int nb_paths) | 1215 | const char *filename, int flags, char **paths, int nb_paths) |
| 1138 | { | 1216 | { |
| 1139 | char buf[1024]; | 1217 | char buf[1024]; |
| @@ -1141,7 +1219,7 @@ static int tcc_add_library_internal(TCCState *s, const char *fmt, · 1 unmodified line | |||
| 1141 | 1219 | ||
| 1142 | for(i = 0; i < nb_paths; i++) { | 1220 | for(i = 0; i < nb_paths; i++) { |
| 1143 | snprintf(buf, sizeof(buf), fmt, paths[i], filename); | 1221 | snprintf(buf, sizeof(buf), fmt, paths[i], filename); |
| 1144 | if (tcc_add_file_internal(s, buf, flags | AFF_TYPE_BIN) == 0) | 1222 | if (tcc_add_file_internal(S, buf, flags | AFF_TYPE_BIN) == 0) |
| 1145 | return 0; | 1223 | return 0; |
| 1146 | } | 1224 | } |
| 1147 | return -1; | 1225 | return -1; |
| @@ -1150,87 +1228,87 @@ static int tcc_add_library_internal(TCCState *s, const char *fmt, · 2 unmodified lines | |||
| 1150 | #ifndef TCC_TARGET_MACHO | 1228 | #ifndef TCC_TARGET_MACHO |
| 1151 | /* find and load a dll. Return non zero if not found */ | 1229 | /* find and load a dll. Return non zero if not found */ |
| 1152 | /* XXX: add '-rpath' option support ? */ | 1230 | /* XXX: add '-rpath' option support ? */ |
| 1153 | ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags) | 1231 | ST_FUNC int tcc_add_dll(TCCState *S, const char *filename, int flags) |
| 1154 | { | 1232 | { |
| 1155 | return tcc_add_library_internal(s, "%s/%s", filename, flags, | 1233 | return tcc_add_library_internal(S, "%s/%s", filename, flags, |
| 1156 | s->library_paths, s->nb_library_paths); | 1234 | S->library_paths, S->nb_library_paths); |
| 1157 | } | 1235 | } |
| 1158 | #endif | 1236 | #endif |
| 1159 | 1237 | ||
| 1160 | #if !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO | 1238 | #if !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO |
| 1161 | ST_FUNC int tcc_add_crt(TCCState *s1, const char *filename) | 1239 | ST_FUNC int tcc_add_crt(TCCState *S, const char *filename) |
| 1162 | { | 1240 | { |
| 1163 | if (-1 == tcc_add_library_internal(s1, "%s/%s", | 1241 | if (-1 == tcc_add_library_internal(S, "%s/%s", |
| 1164 | filename, 0, s1->crt_paths, s1->nb_crt_paths)) | 1242 | filename, 0, S->crt_paths, S->nb_crt_paths)) |
| 1165 | tcc_error_noabort("file '%s' not found", filename); | 1243 | tcc_error_noabort(S, "file '%s' not found", filename); |
| 1166 | return 0; | 1244 | return 0; |
| 1167 | } | 1245 | } |
| 1168 | #endif | 1246 | #endif |
| 1169 | 1247 | ||
| 1170 | /* the library name is the same as the argument of the '-l' option */ | 1248 | /* the library name is the same as the argument of the '-l' option */ |
| 1171 | LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname) | 1249 | LIBTCCAPI int tcc_add_library(TCCState *S, const char *libraryname) |
| 1172 | { | 1250 | { |
| 1173 | #if defined TCC_TARGET_PE | 1251 | #if defined TCC_TARGET_PE |
| 1174 | static const char * const libs[] = { "%s/%s.def", "%s/lib%s.def", "%s/%s.dll", "%s/lib%s.dll", "%s/lib%s.a", NULL }; | 1252 | static const char * const libs[] = { "%s/%s.def", "%s/lib%s.def", "%s/%s.dll", "%s/lib%s.dll", "%s/lib%s.a", NULL }; |
| 1175 | const char * const *pp = s->static_link ? libs + 4 : libs; | 1253 | const char * const *pp = S->static_link ? libs + 4 : libs; |
| 1176 | #elif defined TCC_TARGET_MACHO | 1254 | #elif defined TCC_TARGET_MACHO |
| 1177 | static const char * const libs[] = { "%s/lib%s.dylib", "%s/lib%s.tbd", "%s/lib%s.a", NULL }; | 1255 | static const char * const libs[] = { "%s/lib%s.dylib", "%s/lib%s.tbd", "%s/lib%s.a", NULL }; |
| 1178 | const char * const *pp = s->static_link ? libs + 2 : libs; | 1256 | const char * const *pp = S->static_link ? libs + 2 : libs; |
| 1179 | #elif defined TARGETOS_OpenBSD | 1257 | #elif defined TARGETOS_OpenBSD |
| 1180 | static const char * const libs[] = { "%s/lib%s.so.*", "%s/lib%s.a", NULL }; | 1258 | static const char * const libs[] = { "%s/lib%s.so.*", "%s/lib%s.a", NULL }; |
| 1181 | const char * const *pp = s->static_link ? libs + 1 : libs; | 1259 | const char * const *pp = S->static_link ? libs + 1 : libs; |
| 1182 | #else | 1260 | #else |
| 1183 | static const char * const libs[] = { "%s/lib%s.so", "%s/lib%s.a", NULL }; | 1261 | static const char * const libs[] = { "%s/lib%s.so", "%s/lib%s.a", NULL }; |
| 1184 | const char * const *pp = s->static_link ? libs + 1 : libs; | 1262 | const char * const *pp = S->static_link ? libs + 1 : libs; |
| 1185 | #endif | 1263 | #endif |
| 1186 | int flags = s->filetype & AFF_WHOLE_ARCHIVE; | 1264 | int flags = S->filetype & AFF_WHOLE_ARCHIVE; |
| 1187 | while (*pp) { | 1265 | while (*pp) { |
| 1188 | if (0 == tcc_add_library_internal(s, *pp, | 1266 | if (0 == tcc_add_library_internal(S, *pp, |
| 1189 | libraryname, flags, s->library_paths, s->nb_library_paths)) | 1267 | libraryname, flags, S->library_paths, S->nb_library_paths)) |
| 1190 | return 0; | 1268 | return 0; |
| 1191 | ++pp; | 1269 | ++pp; |
| 1192 | } | 1270 | } |
| 1193 | return -1; | 1271 | return -1; |
| 1194 | } | 1272 | } |
| 1195 | 1273 | ||
| 1196 | PUB_FUNC int tcc_add_library_err(TCCState *s1, const char *libname) | 1274 | PUB_FUNC int tcc_add_library_err(TCCState *S, const char *libname) |
| 1197 | { | 1275 | { |
| 1198 | int ret = tcc_add_library(s1, libname); | 1276 | int ret = tcc_add_library(S, libname); |
| 1199 | if (ret < 0) | 1277 | if (ret < 0) |
| 1200 | tcc_error_noabort("library '%s' not found", libname); | 1278 | tcc_error_noabort(S, "library '%s' not found", libname); |
| 1201 | return ret; | 1279 | return ret; |
| 1202 | } | 1280 | } |
| 1203 | 1281 | ||
| 1204 | /* handle #pragma comment(lib,) */ | 1282 | /* handle #pragma comment(lib,) */ |
| 1205 | ST_FUNC void tcc_add_pragma_libs(TCCState *s1) | 1283 | ST_FUNC void tcc_add_pragma_libs(TCCState *S) |
| 1206 | { | 1284 | { |
| 1207 | int i; | 1285 | int i; |
| 1208 | for (i = 0; i < s1->nb_pragma_libs; i++) | 1286 | for (i = 0; i < S->nb_pragma_libs; i++) |
| 1209 | tcc_add_library_err(s1, s1->pragma_libs[i]); | 1287 | tcc_add_library_err(S, S->pragma_libs[i]); |
| 1210 | } | 1288 | } |
| 1211 | 1289 | ||
| 1212 | LIBTCCAPI int tcc_add_symbol(TCCState *s1, const char *name, const void *val) | 1290 | LIBTCCAPI int tcc_add_symbol(TCCState *S, const char *name, const void *val) |
| 1213 | { | 1291 | { |
| 1214 | #ifdef TCC_TARGET_PE | 1292 | #ifdef TCC_TARGET_PE |
| 1215 | /* On x86_64 'val' might not be reachable with a 32bit offset. | 1293 | /* On x86_64 'val' might not be reachable with a 32bit offset. |
| 1216 | So it is handled here as if it were in a DLL. */ | 1294 | So it is handled here as if it were in a DLL. */ |
| 1217 | pe_putimport(s1, 0, name, (uintptr_t)val); | 1295 | pe_putimport(S, 0, name, (uintptr_t)val); |
| 1218 | #else | 1296 | #else |
| 1219 | char buf[256]; | 1297 | char buf[256]; |
| 1220 | if (s1->leading_underscore) { | 1298 | if (S->leading_underscore) { |
| 1221 | buf[0] = '_'; | 1299 | buf[0] = '_'; |
| 1222 | pstrcpy(buf + 1, sizeof(buf) - 1, name); | 1300 | pstrcpy(buf + 1, sizeof(buf) - 1, name); |
| 1223 | name = buf; | 1301 | name = buf; |
| 1224 | } | 1302 | } |
| 1225 | set_global_sym(s1, name, NULL, (addr_t)(uintptr_t)val); /* NULL: SHN_ABS */ | 1303 | set_global_sym(S, name, NULL, (addr_t)(uintptr_t)val); /* NULL: SHN_ABS */ |
| 1226 | #endif | 1304 | #endif |
| 1227 | return 0; | 1305 | return 0; |
| 1228 | } | 1306 | } |
| 1229 | 1307 | ||
| 1230 | LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path) | 1308 | LIBTCCAPI void tcc_set_lib_path(TCCState *S, const char *path) |
| 1231 | { | 1309 | { |
| 1232 | tcc_free(s->tcc_lib_path); | 1310 | tcc_free(S, S->tcc_lib_path); |
| 1233 | s->tcc_lib_path = tcc_strdup(path); | 1311 | S->tcc_lib_path = tcc_strdup(S, path); |
| 1234 | } | 1312 | } |
| 1235 | 1313 | ||
| 1236 | /********************************************************/ | 1314 | /********************************************************/ |
| @@ -1310,7 +1388,7 @@ static const char *skip_linker_arg(const char **str) · 73 unmodified lines | |||
| 1310 | return s2; | 1388 | return s2; |
| 1311 | } | 1389 | } |
| 1312 | 1390 | ||
| 1313 | static void copy_linker_arg(char **pp, const char *s, int sep) | 1391 | static void copy_linker_arg(TCCState* S, char **pp, const char *s, int sep) |
| 1314 | { | 1392 | { |
| 1315 | const char *q = s; | 1393 | const char *q = s; |
| 1316 | char *p = *pp; | 1394 | char *p = *pp; |
| @@ -1318,13 +1396,12 @@ static void copy_linker_arg(char **pp, const char *s, int sep) · 1 unmodified line | |||
| 1318 | if (p && sep) | 1396 | if (p && sep) |
| 1319 | p[l = strlen(p)] = sep, ++l; | 1397 | p[l = strlen(p)] = sep, ++l; |
| 1320 | skip_linker_arg(&q); | 1398 | skip_linker_arg(&q); |
| 1321 | pstrncpy(l + (*pp = tcc_realloc(p, q - s + l + 1)), s, q - s); | 1399 | pstrncpy(l + (*pp = tcc_realloc(S, p, q - s + l + 1)), s, q - s); |
| 1322 | } | 1400 | } |
| 1323 | 1401 | ||
| 1324 | /* set linker options */ | 1402 | /* set linker options */ |
| 1325 | static int tcc_set_linker(TCCState *s, const char *option) | 1403 | static int tcc_set_linker(TCCState *S, const char *option) |
| 1326 | { | 1404 | { |
| 1327 | TCCState *s1 = s; | ||
| 1328 | while (*option) { | 1405 | while (*option) { |
| 1329 | 1406 | ||
| 1330 | const char *p = NULL; | 1407 | const char *p = NULL; |
| @@ -1333,18 +1410,18 @@ static int tcc_set_linker(TCCState *s, const char *option) · 2 unmodified lines | |||
| 1333 | int ret; | 1410 | int ret; |
| 1334 | 1411 | ||
| 1335 | if (link_option(option, "Bsymbolic", &p)) { | 1412 | if (link_option(option, "Bsymbolic", &p)) { |
| 1336 | s->symbolic = 1; | 1413 | S->symbolic = 1; |
| 1337 | } else if (link_option(option, "nostdlib", &p)) { | 1414 | } else if (link_option(option, "nostdlib", &p)) { |
| 1338 | s->nostdlib = 1; | 1415 | S->nostdlib = 1; |
| 1339 | } else if (link_option(option, "fini=", &p)) { | 1416 | } else if (link_option(option, "fini=", &p)) { |
| 1340 | copy_linker_arg(&s->fini_symbol, p, 0); | 1417 | copy_linker_arg(S, &S->fini_symbol, p, 0); |
| 1341 | ignoring = 1; | 1418 | ignoring = 1; |
| 1342 | } else if (link_option(option, "image-base=", &p) | 1419 | } else if (link_option(option, "image-base=", &p) |
| 1343 | || link_option(option, "Ttext=", &p)) { | 1420 | || link_option(option, "Ttext=", &p)) { |
| 1344 | s->text_addr = strtoull(p, &end, 16); | 1421 | S->text_addr = strtoull(p, &end, 16); |
| 1345 | s->has_text_addr = 1; | 1422 | S->has_text_addr = 1; |
| 1346 | } else if (link_option(option, "init=", &p)) { | 1423 | } else if (link_option(option, "init=", &p)) { |
| 1347 | copy_linker_arg(&s->init_symbol, p, 0); | 1424 | copy_linker_arg(S, &S->init_symbol, p, 0); |
| 1348 | ignoring = 1; | 1425 | ignoring = 1; |
| 1349 | } else if (link_option(option, "oformat=", &p)) { | 1426 | } else if (link_option(option, "oformat=", &p)) { |
| 1350 | #if defined(TCC_TARGET_PE) | 1427 | #if defined(TCC_TARGET_PE) |
| @@ -1354,12 +1431,12 @@ static int tcc_set_linker(TCCState *s, const char *option) · 3 unmodified lines | |||
| 1354 | #else | 1431 | #else |
| 1355 | if (strstart("elf32-", &p)) { | 1432 | if (strstart("elf32-", &p)) { |
| 1356 | #endif | 1433 | #endif |
| 1357 | s->output_format = TCC_OUTPUT_FORMAT_ELF; | 1434 | S->output_format = TCC_OUTPUT_FORMAT_ELF; |
| 1358 | } else if (!strcmp(p, "binary")) { | 1435 | } else if (!strcmp(p, "binary")) { |
| 1359 | s->output_format = TCC_OUTPUT_FORMAT_BINARY; | 1436 | S->output_format = TCC_OUTPUT_FORMAT_BINARY; |
| 1360 | #ifdef TCC_TARGET_COFF | 1437 | #ifdef TCC_TARGET_COFF |
| 1361 | } else if (!strcmp(p, "coff")) { | 1438 | } else if (!strcmp(p, "coff")) { |
| 1362 | s->output_format = TCC_OUTPUT_FORMAT_COFF; | 1439 | S->output_format = TCC_OUTPUT_FORMAT_COFF; |
| 1363 | #endif | 1440 | #endif |
| 1364 | } else | 1441 | } else |
| 1365 | goto err; | 1442 | goto err; |
| @@ -1369,64 +1446,64 @@ static int tcc_set_linker(TCCState *s, const char *option) · 3 unmodified lines | |||
| 1369 | } else if (link_option(option, "O", &p)) { | 1446 | } else if (link_option(option, "O", &p)) { |
| 1370 | ignoring = 1; | 1447 | ignoring = 1; |
| 1371 | } else if (link_option(option, "export-all-symbols", &p)) { | 1448 | } else if (link_option(option, "export-all-symbols", &p)) { |
| 1372 | s->rdynamic = 1; | 1449 | S->rdynamic = 1; |
| 1373 | } else if (link_option(option, "export-dynamic", &p)) { | 1450 | } else if (link_option(option, "export-dynamic", &p)) { |
| 1374 | s->rdynamic = 1; | 1451 | S->rdynamic = 1; |
| 1375 | } else if (link_option(option, "rpath=", &p)) { | 1452 | } else if (link_option(option, "rpath=", &p)) { |
| 1376 | copy_linker_arg(&s->rpath, p, ':'); | 1453 | copy_linker_arg(S, &S->rpath, p, ':'); |
| 1377 | } else if (link_option(option, "enable-new-dtags", &p)) { | 1454 | } else if (link_option(option, "enable-new-dtags", &p)) { |
| 1378 | s->enable_new_dtags = 1; | 1455 | S->enable_new_dtags = 1; |
| 1379 | } else if (link_option(option, "section-alignment=", &p)) { | 1456 | } else if (link_option(option, "section-alignment=", &p)) { |
| 1380 | s->section_align = strtoul(p, &end, 16); | 1457 | S->section_align = strtoul(p, &end, 16); |
| 1381 | } else if (link_option(option, "soname=", &p)) { | 1458 | } else if (link_option(option, "soname=", &p)) { |
| 1382 | copy_linker_arg(&s->soname, p, 0); | 1459 | copy_linker_arg(S, &S->soname, p, 0); |
| 1383 | #ifdef TCC_TARGET_PE | 1460 | #ifdef TCC_TARGET_PE |
| 1384 | } else if (link_option(option, "large-address-aware", &p)) { | 1461 | } else if (link_option(option, "large-address-aware", &p)) { |
| 1385 | s->pe_characteristics |= 0x20; | 1462 | S->pe_characteristics |= 0x20; |
| 1386 | } else if (link_option(option, "file-alignment=", &p)) { | 1463 | } else if (link_option(option, "file-alignment=", &p)) { |
| 1387 | s->pe_file_align = strtoul(p, &end, 16); | 1464 | S->pe_file_align = strtoul(p, &end, 16); |
| 1388 | } else if (link_option(option, "stack=", &p)) { | 1465 | } else if (link_option(option, "stack=", &p)) { |
| 1389 | s->pe_stack_size = strtoul(p, &end, 10); | 1466 | S->pe_stack_size = strtoul(p, &end, 10); |
| 1390 | } else if (link_option(option, "subsystem=", &p)) { | 1467 | } else if (link_option(option, "subsystem=", &p)) { |
| 1391 | #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) | 1468 | #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) |
| 1392 | if (!strcmp(p, "native")) { | 1469 | if (!strcmp(p, "native")) { |
| 1393 | s->pe_subsystem = 1; | 1470 | S->pe_subsystem = 1; |
| 1394 | } else if (!strcmp(p, "console")) { | 1471 | } else if (!strcmp(p, "console")) { |
| 1395 | s->pe_subsystem = 3; | 1472 | S->pe_subsystem = 3; |
| 1396 | } else if (!strcmp(p, "gui") || !strcmp(p, "windows")) { | 1473 | } else if (!strcmp(p, "gui") || !strcmp(p, "windows")) { |
| 1397 | s->pe_subsystem = 2; | 1474 | S->pe_subsystem = 2; |
| 1398 | } else if (!strcmp(p, "posix")) { | 1475 | } else if (!strcmp(p, "posix")) { |
| 1399 | s->pe_subsystem = 7; | 1476 | S->pe_subsystem = 7; |
| 1400 | } else if (!strcmp(p, "efiapp")) { | 1477 | } else if (!strcmp(p, "efiapp")) { |
| 1401 | s->pe_subsystem = 10; | 1478 | S->pe_subsystem = 10; |
| 1402 | } else if (!strcmp(p, "efiboot")) { | 1479 | } else if (!strcmp(p, "efiboot")) { |
| 1403 | s->pe_subsystem = 11; | 1480 | S->pe_subsystem = 11; |
| 1404 | } else if (!strcmp(p, "efiruntime")) { | 1481 | } else if (!strcmp(p, "efiruntime")) { |
| 1405 | s->pe_subsystem = 12; | 1482 | S->pe_subsystem = 12; |
| 1406 | } else if (!strcmp(p, "efirom")) { | 1483 | } else if (!strcmp(p, "efirom")) { |
| 1407 | s->pe_subsystem = 13; | 1484 | S->pe_subsystem = 13; |
| 1408 | #elif defined(TCC_TARGET_ARM) | 1485 | #elif defined(TCC_TARGET_ARM) |
| 1409 | if (!strcmp(p, "wince")) { | 1486 | if (!strcmp(p, "wince")) { |
| 1410 | s->pe_subsystem = 9; | 1487 | S->pe_subsystem = 9; |
| 1411 | #endif | 1488 | #endif |
| 1412 | } else | 1489 | } else |
| 1413 | goto err; | 1490 | goto err; |
| 1414 | #endif | 1491 | #endif |
| 1415 | } else if (ret = link_option(option, "?whole-archive", &p), ret) { | 1492 | } else if (ret = link_option(option, "?whole-archive", &p), ret) { |
| 1416 | if (ret > 0) | 1493 | if (ret > 0) |
| 1417 | s->filetype |= AFF_WHOLE_ARCHIVE; | 1494 | S->filetype |= AFF_WHOLE_ARCHIVE; |
| 1418 | else | 1495 | else |
| 1419 | s->filetype &= ~AFF_WHOLE_ARCHIVE; | 1496 | S->filetype &= ~AFF_WHOLE_ARCHIVE; |
| 1420 | } else if (link_option(option, "z=", &p)) { | 1497 | } else if (link_option(option, "z=", &p)) { |
| 1421 | ignoring = 1; | 1498 | ignoring = 1; |
| 1422 | } else if (p) { | 1499 | } else if (p) { |
| 1423 | return 0; | 1500 | return 0; |
| 1424 | } else { | 1501 | } else { |
| 1425 | err: | 1502 | err: |
| 1426 | tcc_error("unsupported linker option '%s'", option); | 1503 | tcc_error(S, "unsupported linker option '%s'", option); |
| 1427 | } | 1504 | } |
| 1428 | if (ignoring) | 1505 | if (ignoring) |
| 1429 | tcc_warning_c(warn_unsupported)("unsupported linker option '%s'", option); | 1506 | tcc_warning_c(warn_unsupported)(S, "unsupported linker option '%s'", option); |
| 1430 | option = skip_linker_arg(&p); | 1507 | option = skip_linker_arg(&p); |
| 1431 | } | 1508 | } |
| 1432 | return 1; | 1509 | return 1; |
| @@ -1604,7 +1681,7 @@ static const FlagDef options_m[] = { · 171 unmodified lines | |||
| 1604 | { 0, 0, NULL } | 1681 | { 0, 0, NULL } |
| 1605 | }; | 1682 | }; |
| 1606 | 1683 | ||
| 1607 | static int set_flag(TCCState *s, const FlagDef *flags, const char *name) | 1684 | static int set_flag(TCCState *S, const FlagDef *flags, const char *name) |
| 1608 | { | 1685 | { |
| 1609 | int value, mask, ret; | 1686 | int value, mask, ret; |
| 1610 | const FlagDef *p; | 1687 | const FlagDef *p; |
| @@ -1626,7 +1703,7 @@ static int set_flag(TCCState *s, const FlagDef *flags, const char *name) · 15 unmodified lines | |||
| 1626 | continue; | 1703 | continue; |
| 1627 | } | 1704 | } |
| 1628 | 1705 | ||
| 1629 | f = (unsigned char *)s + p->offset; | 1706 | f = (unsigned char *)S + p->offset; |
| 1630 | *f = (*f & mask) | (value ^ !!(p->flags & FD_INVERT)); | 1707 | *f = (*f & mask) | (value ^ !!(p->flags & FD_INVERT)); |
| 1631 | 1708 | ||
| 1632 | if (ret) { | 1709 | if (ret) { |
| @@ -1638,15 +1715,15 @@ static int set_flag(TCCState *s, const FlagDef *flags, const char *name) · 5 unmodified lines | |||
| 1638 | return ret; | 1715 | return ret; |
| 1639 | } | 1716 | } |
| 1640 | 1717 | ||
| 1641 | static void args_parser_add_file(TCCState *s, const char* filename, int filetype) | 1718 | static void args_parser_add_file(TCCState *S, const char* filename, int filetype) |
| 1642 | { | 1719 | { |
| 1643 | struct filespec *f = tcc_malloc(sizeof *f + strlen(filename)); | 1720 | struct filespec *f = tcc_malloc(S, sizeof *f + strlen(filename)); |
| 1644 | f->type = filetype; | 1721 | f->type = filetype; |
| 1645 | strcpy(f->name, filename); | 1722 | strcpy(f->name, filename); |
| 1646 | dynarray_add(&s->files, &s->nb_files, f); | 1723 | dynarray_add(S, &S->files, &S->nb_files, f); |
| 1647 | } | 1724 | } |
| 1648 | 1725 | ||
| 1649 | static int args_parser_make_argv(const char *r, int *argc, char ***argv) | 1726 | static int args_parser_make_argv(TCCState* S, const char *r, int *argc, char ***argv) |
| 1650 | { | 1727 | { |
| 1651 | int ret = 0, q, c; | 1728 | int ret = 0, q, c; |
| 1652 | CString str; | 1729 | CString str; |
| @@ -1656,7 +1733,7 @@ static int args_parser_make_argv(const char *r, int *argc, char ***argv) · 3 unmodified lines | |||
| 1656 | if (c == 0) | 1733 | if (c == 0) |
| 1657 | break; | 1734 | break; |
| 1658 | q = 0; | 1735 | q = 0; |
| 1659 | cstr_new(&str); | 1736 | cstr_new(S, &str); |
| 1660 | while (c = (unsigned char)*r, c) { | 1737 | while (c = (unsigned char)*r, c) { |
| 1661 | ++r; | 1738 | ++r; |
| 1662 | if (c == '\\' && (*r == '"' || *r == '\\')) { | 1739 | if (c == '\\' && (*r == '"' || *r == '\\')) { |
| @@ -1667,22 +1744,21 @@ static int args_parser_make_argv(const char *r, int *argc, char ***argv) · 4 unmodified lines | |||
| 1667 | } else if (q == 0 && c <= ' ') { | 1744 | } else if (q == 0 && c <= ' ') { |
| 1668 | break; | 1745 | break; |
| 1669 | } | 1746 | } |
| 1670 | cstr_ccat(&str, c); | 1747 | cstr_ccat(S, &str, c); |
| 1671 | } | 1748 | } |
| 1672 | cstr_ccat(&str, 0); | 1749 | cstr_ccat(S, &str, 0); |
| 1673 | //printf("<%s>\n", str.data), fflush(stdout); | 1750 | //printf("<%s>\n", str.data), fflush(stdout); |
| 1674 | dynarray_add(argv, argc, tcc_strdup(str.data)); | 1751 | dynarray_add(S, argv, argc, tcc_strdup(S, str.data)); |
| 1675 | cstr_free(&str); | 1752 | cstr_free(S, &str); |
| 1676 | ++ret; | 1753 | ++ret; |
| 1677 | } | 1754 | } |
| 1678 | return ret; | 1755 | return ret; |
| 1679 | } | 1756 | } |
| 1680 | 1757 | ||
| 1681 | /* read list file */ | 1758 | /* read list file */ |
| 1682 | static void args_parser_listfile(TCCState *s, | 1759 | static void args_parser_listfile(TCCState *S, |
| 1683 | const char *filename, int optind, int *pargc, char ***pargv) | 1760 | const char *filename, int optind, int *pargc, char ***pargv) |
| 1684 | { | 1761 | { |
| 1685 | TCCState *s1 = s; | ||
| 1686 | int fd, i; | 1762 | int fd, i; |
| 1687 | char *p; | 1763 | char *p; |
| 1688 | int argc = 0; | 1764 | int argc = 0; |
| @@ -1690,23 +1766,22 @@ static void args_parser_listfile(TCCState *s, · 1 unmodified line | |||
| 1690 | 1766 | ||
| 1691 | fd = open(filename, O_RDONLY | O_BINARY); | 1767 | fd = open(filename, O_RDONLY | O_BINARY); |
| 1692 | if (fd < 0) | 1768 | if (fd < 0) |
| 1693 | tcc_error("listfile '%s' not found", filename); | 1769 | tcc_error(S, "listfile '%s' not found", filename); |
| 1694 | 1770 | ||
| 1695 | p = tcc_load_text(fd); | 1771 | p = tcc_load_text(S, fd); |
| 1696 | for (i = 0; i < *pargc; ++i) | 1772 | for (i = 0; i < *pargc; ++i) |
| 1697 | if (i == optind) | 1773 | if (i == optind) |
| 1698 | args_parser_make_argv(p, &argc, &argv); | 1774 | args_parser_make_argv(S, p, &argc, &argv); |
| 1699 | else | 1775 | else |
| 1700 | dynarray_add(&argv, &argc, tcc_strdup((*pargv)[i])); | 1776 | dynarray_add(S, &argv, &argc, tcc_strdup(S, (*pargv)[i])); |
| 1701 | 1777 | ||
| 1702 | tcc_free(p); | 1778 | tcc_free(S, p); |
| 1703 | dynarray_reset(&s->argv, &s->argc); | 1779 | dynarray_reset(S, &S->argv, &S->argc); |
| 1704 | *pargc = s->argc = argc, *pargv = s->argv = argv; | 1780 | *pargc = S->argc = argc, *pargv = S->argv = argv; |
| 1705 | } | 1781 | } |
| 1706 | 1782 | ||
| 1707 | PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind) | 1783 | PUB_FUNC int tcc_parse_args(TCCState *S, int *pargc, char ***pargv, int optind) |
| 1708 | { | 1784 | { |
| 1709 | TCCState *s1 = s; | ||
| 1710 | const TCCOption *popt; | 1785 | const TCCOption *popt; |
| 1711 | const char *optarg, *r; | 1786 | const char *optarg, *r; |
| 1712 | const char *run = NULL; | 1787 | const char *run = NULL; |
| @@ -1716,26 +1791,26 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind) · 3 unmodified lines | |||
| 1716 | char **argv = *pargv; | 1791 | char **argv = *pargv; |
| 1717 | int argc = *pargc; | 1792 | int argc = *pargc; |
| 1718 | 1793 | ||
| 1719 | cstr_new(&linker_arg); | 1794 | cstr_new(S, &linker_arg); |
| 1720 | 1795 | ||
| 1721 | while (optind < argc) { | 1796 | while (optind < argc) { |
| 1722 | r = argv[optind]; | 1797 | r = argv[optind]; |
| 1723 | if (r[0] == '@' && r[1] != '\0') { | 1798 | if (r[0] == '@' && r[1] != '\0') { |
| 1724 | args_parser_listfile(s, r + 1, optind, &argc, &argv); | 1799 | args_parser_listfile(S, r + 1, optind, &argc, &argv); |
| 1725 | continue; | 1800 | continue; |
| 1726 | } | 1801 | } |
| 1727 | optind++; | 1802 | optind++; |
| 1728 | if (tool) { | 1803 | if (tool) { |
| 1729 | if (r[0] == '-' && r[1] == 'v' && r[2] == 0) | 1804 | if (r[0] == '-' && r[1] == 'v' && r[2] == 0) |
| 1730 | ++s->verbose; | 1805 | ++S->verbose; |
| 1731 | continue; | 1806 | continue; |
| 1732 | } | 1807 | } |
| 1733 | reparse: | 1808 | reparse: |
| 1734 | if (r[0] != '-' || r[1] == '\0') { | 1809 | if (r[0] != '-' || r[1] == '\0') { |
| 1735 | if (r[0] != '@') /* allow "tcc file(s) -run @ args ..." */ | 1810 | if (r[0] != '@') /* allow "tcc file(s) -run @ args ..." */ |
| 1736 | args_parser_add_file(s, r, s->filetype); | 1811 | args_parser_add_file(S, r, S->filetype); |
| 1737 | if (run) { | 1812 | if (run) { |
| 1738 | tcc_set_options(s, run); | 1813 | tcc_set_options(S, run); |
| 1739 | arg_start = optind - 1; | 1814 | arg_start = optind - 1; |
| 1740 | break; | 1815 | break; |
| 1741 | } | 1816 | } |
| @@ -1747,7 +1822,7 @@ reparse: · 5 unmodified lines | |||
| 1747 | const char *p1 = popt->name; | 1822 | const char *p1 = popt->name; |
| 1748 | const char *r1 = r + 1; | 1823 | const char *r1 = r + 1; |
| 1749 | if (p1 == NULL) | 1824 | if (p1 == NULL) |
| 1750 | tcc_error("invalid option -- '%s'", r); | 1825 | tcc_error(S, "invalid option -- '%s'", r); |
| 1751 | if (!strstart(p1, &r1)) | 1826 | if (!strstart(p1, &r1)) |
| 1752 | continue; | 1827 | continue; |
| 1753 | optarg = r1; | 1828 | optarg = r1; |
| @@ -1755,7 +1830,7 @@ reparse: · 1 unmodified line | |||
| 1755 | if (*r1 == '\0' && !(popt->flags & TCC_OPTION_NOSEP)) { | 1830 | if (*r1 == '\0' && !(popt->flags & TCC_OPTION_NOSEP)) { |
| 1756 | if (optind >= argc) | 1831 | if (optind >= argc) |
| 1757 | arg_err: | 1832 | arg_err: |
| 1758 | tcc_error("argument to '%s' is missing", r); | 1833 | tcc_error(S, "argument to '%s' is missing", r); |
| 1759 | optarg = argv[optind++]; | 1834 | optarg = argv[optind++]; |
| 1760 | } | 1835 | } |
| 1761 | } else if (*r1 != '\0') | 1836 | } else if (*r1 != '\0') |
| @@ -1771,132 +1846,132 @@ reparse: · 9 unmodified lines | |||
| 1771 | x = OPT_HELP2; | 1846 | x = OPT_HELP2; |
| 1772 | goto extra_action; | 1847 | goto extra_action; |
| 1773 | case TCC_OPTION_I: | 1848 | case TCC_OPTION_I: |
| 1774 | tcc_add_include_path(s, optarg); | 1849 | tcc_add_include_path(S, optarg); |
| 1775 | break; | 1850 | break; |
| 1776 | case TCC_OPTION_D: | 1851 | case TCC_OPTION_D: |
| 1777 | tcc_define_symbol(s, optarg, NULL); | 1852 | tcc_define_symbol(S, optarg, NULL); |
| 1778 | break; | 1853 | break; |
| 1779 | case TCC_OPTION_U: | 1854 | case TCC_OPTION_U: |
| 1780 | tcc_undefine_symbol(s, optarg); | 1855 | tcc_undefine_symbol(S, optarg); |
| 1781 | break; | 1856 | break; |
| 1782 | case TCC_OPTION_L: | 1857 | case TCC_OPTION_L: |
| 1783 | tcc_add_library_path(s, optarg); | 1858 | tcc_add_library_path(S, optarg); |
| 1784 | break; | 1859 | break; |
| 1785 | case TCC_OPTION_B: | 1860 | case TCC_OPTION_B: |
| 1786 | /* set tcc utilities path (mainly for tcc development) */ | 1861 | /* set tcc utilities path (mainly for tcc development) */ |
| 1787 | tcc_set_lib_path(s, optarg); | 1862 | tcc_set_lib_path(S, optarg); |
| 1788 | break; | 1863 | break; |
| 1789 | case TCC_OPTION_l: | 1864 | case TCC_OPTION_l: |
| 1790 | args_parser_add_file(s, optarg, AFF_TYPE_LIB | (s->filetype & ~AFF_TYPE_MASK)); | 1865 | args_parser_add_file(S, optarg, AFF_TYPE_LIB | (S->filetype & ~AFF_TYPE_MASK)); |
| 1791 | s->nb_libraries++; | 1866 | S->nb_libraries++; |
| 1792 | break; | 1867 | break; |
| 1793 | case TCC_OPTION_pthread: | 1868 | case TCC_OPTION_pthread: |
| 1794 | s->option_pthread = 1; | 1869 | S->option_pthread = 1; |
| 1795 | break; | 1870 | break; |
| 1796 | case TCC_OPTION_bench: | 1871 | case TCC_OPTION_bench: |
| 1797 | s->do_bench = 1; | 1872 | S->do_bench = 1; |
| 1798 | break; | 1873 | break; |
| 1799 | #ifdef CONFIG_TCC_BACKTRACE | 1874 | #ifdef CONFIG_TCC_BACKTRACE |
| 1800 | case TCC_OPTION_bt: | 1875 | case TCC_OPTION_bt: |
| 1801 | s->rt_num_callers = atoi(optarg); | 1876 | S->rt_num_callers = atoi(optarg); |
| 1802 | s->do_backtrace = 1; | 1877 | S->do_backtrace = 1; |
| 1803 | s->do_debug = 1; | 1878 | S->do_debug = 1; |
| 1804 | break; | 1879 | break; |
| 1805 | #endif | 1880 | #endif |
| 1806 | #ifdef CONFIG_TCC_BCHECK | 1881 | #ifdef CONFIG_TCC_BCHECK |
| 1807 | case TCC_OPTION_b: | 1882 | case TCC_OPTION_b: |
| 1808 | s->do_bounds_check = 1; | 1883 | S->do_bounds_check = 1; |
| 1809 | s->do_backtrace = 1; | 1884 | S->do_backtrace = 1; |
| 1810 | s->do_debug = 1; | 1885 | S->do_debug = 1; |
| 1811 | break; | 1886 | break; |
| 1812 | #endif | 1887 | #endif |
| 1813 | case TCC_OPTION_g: | 1888 | case TCC_OPTION_g: |
| 1814 | s->do_debug = 1; | 1889 | S->do_debug = 1; |
| 1815 | break; | 1890 | break; |
| 1816 | case TCC_OPTION_c: | 1891 | case TCC_OPTION_c: |
| 1817 | x = TCC_OUTPUT_OBJ; | 1892 | x = TCC_OUTPUT_OBJ; |
| 1818 | set_output_type: | 1893 | set_output_type: |
| 1819 | if (s->output_type) | 1894 | if (S->output_type) |
| 1820 | tcc_warning("-%s: overriding compiler action already specified", popt->name); | 1895 | tcc_warning(S, "-%s: overriding compiler action already specified", popt->name); |
| 1821 | s->output_type = x; | 1896 | S->output_type = x; |
| 1822 | break; | 1897 | break; |
| 1823 | case TCC_OPTION_d: | 1898 | case TCC_OPTION_d: |
| 1824 | if (*optarg == 'D') | 1899 | if (*optarg == 'D') |
| 1825 | s->dflag = 3; | 1900 | S->dflag = TCC_OPTION_d_D; |
| 1826 | else if (*optarg == 'M') | 1901 | else if (*optarg == 'M') |
| 1827 | s->dflag = 7; | 1902 | S->dflag = TCC_OPTION_d_M; |
| 1828 | else if (*optarg == 't') | 1903 | else if (*optarg == 't') |
| 1829 | s->dflag = 16; | 1904 | S->dflag = TCC_OPTION_d_t; |
| 1830 | else if (isnum(*optarg)) | 1905 | else if (isnum(*optarg)) |
| 1831 | s->g_debug |= atoi(optarg); | 1906 | S->g_debug |= atoi(optarg); |
| 1832 | else | 1907 | else |
| 1833 | goto unsupported_option; | 1908 | goto unsupported_option; |
| 1834 | break; | 1909 | break; |
| 1835 | case TCC_OPTION_static: | 1910 | case TCC_OPTION_static: |
| 1836 | s->static_link = 1; | 1911 | S->static_link = 1; |
| 1837 | break; | 1912 | break; |
| 1838 | case TCC_OPTION_std: | 1913 | case TCC_OPTION_std: |
| 1839 | if (strcmp(optarg, "=c11") == 0) | 1914 | if (strcmp(optarg, "=c11") == 0) |
| 1840 | s->cversion = 201112; | 1915 | S->cversion = 201112; |
| 1841 | break; | 1916 | break; |
| 1842 | case TCC_OPTION_shared: | 1917 | case TCC_OPTION_shared: |
| 1843 | x = TCC_OUTPUT_DLL; | 1918 | x = TCC_OUTPUT_DLL; |
| 1844 | goto set_output_type; | 1919 | goto set_output_type; |
| 1845 | case TCC_OPTION_soname: | 1920 | case TCC_OPTION_soname: |
| 1846 | s->soname = tcc_strdup(optarg); | 1921 | S->soname = tcc_strdup(S, optarg); |
| 1847 | break; | 1922 | break; |
| 1848 | case TCC_OPTION_o: | 1923 | case TCC_OPTION_o: |
| 1849 | if (s->outfile) { | 1924 | if (S->outfile) { |
| 1850 | tcc_warning("multiple -o option"); | 1925 | tcc_warning(S, "multiple -o option"); |
| 1851 | tcc_free(s->outfile); | 1926 | tcc_free(S, S->outfile); |
| 1852 | } | 1927 | } |
| 1853 | s->outfile = tcc_strdup(optarg); | 1928 | S->outfile = tcc_strdup(S, optarg); |
| 1854 | break; | 1929 | break; |
| 1855 | case TCC_OPTION_r: | 1930 | case TCC_OPTION_r: |
| 1856 | /* generate a .o merging several output files */ | 1931 | /* generate a .o merging several output files */ |
| 1857 | s->option_r = 1; | 1932 | S->option_r = 1; |
| 1858 | x = TCC_OUTPUT_OBJ; | 1933 | x = TCC_OUTPUT_OBJ; |
| 1859 | goto set_output_type; | 1934 | goto set_output_type; |
| 1860 | case TCC_OPTION_isystem: | 1935 | case TCC_OPTION_isystem: |
| 1861 | tcc_add_sysinclude_path(s, optarg); | 1936 | tcc_add_sysinclude_path(S, optarg); |
| 1862 | break; | 1937 | break; |
| 1863 | case TCC_OPTION_include: | 1938 | case TCC_OPTION_include: |
| 1864 | cstr_printf(&s->cmdline_incl, "#include \"%s\"\n", optarg); | 1939 | cstr_printf(S, &S->cmdline_incl, "#include \"%s\"\n", optarg); |
| 1865 | break; | 1940 | break; |
| 1866 | case TCC_OPTION_nostdinc: | 1941 | case TCC_OPTION_nostdinc: |
| 1867 | s->nostdinc = 1; | 1942 | S->nostdinc = 1; |
| 1868 | break; | 1943 | break; |
| 1869 | case TCC_OPTION_nostdlib: | 1944 | case TCC_OPTION_nostdlib: |
| 1870 | s->nostdlib = 1; | 1945 | S->nostdlib = 1; |
| 1871 | break; | 1946 | break; |
| 1872 | case TCC_OPTION_run: | 1947 | case TCC_OPTION_run: |
| 1873 | #ifndef TCC_IS_NATIVE | 1948 | #ifndef TCC_IS_NATIVE |
| 1874 | tcc_error("-run is not available in a cross compiler"); | 1949 | tcc_error(S, "-run is not available in a cross compiler"); |
| 1875 | #endif | 1950 | #endif |
| 1876 | run = optarg; | 1951 | run = optarg; |
| 1877 | x = TCC_OUTPUT_MEMORY; | 1952 | x = TCC_OUTPUT_MEMORY; |
| 1878 | goto set_output_type; | 1953 | goto set_output_type; |
| 1879 | case TCC_OPTION_v: | 1954 | case TCC_OPTION_v: |
| 1880 | do ++s->verbose; while (*optarg++ == 'v'); | 1955 | do ++S->verbose; while (*optarg++ == 'v'); |
| 1881 | ++noaction; | 1956 | ++noaction; |
| 1882 | break; | 1957 | break; |
| 1883 | case TCC_OPTION_f: | 1958 | case TCC_OPTION_f: |
| 1884 | if (set_flag(s, options_f, optarg) < 0) | 1959 | if (set_flag(S, options_f, optarg) < 0) |
| 1885 | goto unsupported_option; | 1960 | goto unsupported_option; |
| 1886 | break; | 1961 | break; |
| 1887 | #ifdef TCC_TARGET_ARM | 1962 | #ifdef TCC_TARGET_ARM |
| 1888 | case TCC_OPTION_mfloat_abi: | 1963 | case TCC_OPTION_mfloat_abi: |
| 1889 | /* tcc doesn't support soft float yet */ | 1964 | /* tcc doesn't support soft float yet */ |
| 1890 | if (!strcmp(optarg, "softfp")) { | 1965 | if (!strcmp(optarg, "softfp")) { |
| 1891 | s->float_abi = ARM_SOFTFP_FLOAT; | 1966 | S->float_abi = ARM_SOFTFP_FLOAT; |
| 1892 | } else if (!strcmp(optarg, "hard")) | 1967 | } else if (!strcmp(optarg, "hard")) |
| 1893 | s->float_abi = ARM_HARD_FLOAT; | 1968 | S->float_abi = ARM_HARD_FLOAT; |
| 1894 | else | 1969 | else |
| 1895 | tcc_error("unsupported float abi '%s'", optarg); | 1970 | tcc_error(S, "unsupported float abi '%s'", optarg); |
| 1896 | break; | 1971 | break; |
| 1897 | #endif | 1972 | #endif |
| 1898 | case TCC_OPTION_m: | 1973 | case TCC_OPTION_m: |
| 1899 | if (set_flag(s, options_m, optarg) < 0) { | 1974 | if (set_flag(S, options_m, optarg) < 0) { |
| 1900 | if (x = atoi(optarg), x != 32 && x != 64) | 1975 | if (x = atoi(optarg), x != 32 && x != 64) |
| 1901 | goto unsupported_option; | 1976 | goto unsupported_option; |
| 1902 | if (PTR_SIZE != x/8) | 1977 | if (PTR_SIZE != x/8) |
| @@ -1905,22 +1980,22 @@ reparse: · 2 unmodified lines | |||
| 1905 | } | 1980 | } |
| 1906 | break; | 1981 | break; |
| 1907 | case TCC_OPTION_W: | 1982 | case TCC_OPTION_W: |
| 1908 | s->warn_none = 0; | 1983 | S->warn_none = 0; |
| 1909 | if (optarg[0] && set_flag(s, options_W, optarg) < 0) | 1984 | if (optarg[0] && set_flag(S, options_W, optarg) < 0) |
| 1910 | goto unsupported_option; | 1985 | goto unsupported_option; |
| 1911 | break; | 1986 | break; |
| 1912 | case TCC_OPTION_w: | 1987 | case TCC_OPTION_w: |
| 1913 | s->warn_none = 1; | 1988 | S->warn_none = 1; |
| 1914 | break; | 1989 | break; |
| 1915 | case TCC_OPTION_rdynamic: | 1990 | case TCC_OPTION_rdynamic: |
| 1916 | s->rdynamic = 1; | 1991 | S->rdynamic = 1; |
| 1917 | break; | 1992 | break; |
| 1918 | case TCC_OPTION_Wl: | 1993 | case TCC_OPTION_Wl: |
| 1919 | if (linker_arg.size) | 1994 | if (linker_arg.size) |
| 1920 | --linker_arg.size, cstr_ccat(&linker_arg, ','); | 1995 | --linker_arg.size, cstr_ccat(S, &linker_arg, ','); |
| 1921 | cstr_cat(&linker_arg, optarg, 0); | 1996 | cstr_cat(S, &linker_arg, optarg, 0); |
| 1922 | if (tcc_set_linker(s, linker_arg.data)) | 1997 | if (tcc_set_linker(S, linker_arg.data)) |
| 1923 | cstr_free(&linker_arg); | 1998 | cstr_free(S, &linker_arg); |
| 1924 | break; | 1999 | break; |
| 1925 | case TCC_OPTION_Wp: | 2000 | case TCC_OPTION_Wp: |
| 1926 | r = optarg; | 2001 | r = optarg; |
| @@ -1929,25 +2004,25 @@ reparse: · 2 unmodified lines | |||
| 1929 | x = TCC_OUTPUT_PREPROCESS; | 2004 | x = TCC_OUTPUT_PREPROCESS; |
| 1930 | goto set_output_type; | 2005 | goto set_output_type; |
| 1931 | case TCC_OPTION_P: | 2006 | case TCC_OPTION_P: |
| 1932 | s->Pflag = atoi(optarg) + 1; | 2007 | S->Pflag = atoi(optarg) + 1; |
| 1933 | break; | 2008 | break; |
| 1934 | case TCC_OPTION_M: | 2009 | case TCC_OPTION_M: |
| 1935 | s->include_sys_deps = 1; | 2010 | S->include_sys_deps = 1; |
| 1936 | // fall through | 2011 | // fall through |
| 1937 | case TCC_OPTION_MM: | 2012 | case TCC_OPTION_MM: |
| 1938 | s->just_deps = 1; | 2013 | S->just_deps = 1; |
| 1939 | if(!s->deps_outfile) | 2014 | if(!S->deps_outfile) |
| 1940 | s->deps_outfile = tcc_strdup("-"); | 2015 | S->deps_outfile = tcc_strdup(S, "-"); |
| 1941 | // fall through | 2016 | // fall through |
| 1942 | case TCC_OPTION_MMD: | 2017 | case TCC_OPTION_MMD: |
| 1943 | s->gen_deps = 1; | 2018 | S->gen_deps = 1; |
| 1944 | break; | 2019 | break; |
| 1945 | case TCC_OPTION_MD: | 2020 | case TCC_OPTION_MD: |
| 1946 | s->gen_deps = 1; | 2021 | S->gen_deps = 1; |
| 1947 | s->include_sys_deps = 1; | 2022 | S->include_sys_deps = 1; |
| 1948 | break; | 2023 | break; |
| 1949 | case TCC_OPTION_MF: | 2024 | case TCC_OPTION_MF: |
| 1950 | s->deps_outfile = tcc_strdup(optarg); | 2025 | S->deps_outfile = tcc_strdup(S, optarg); |
| 1951 | break; | 2026 | break; |
| 1952 | case TCC_OPTION_dumpversion: | 2027 | case TCC_OPTION_dumpversion: |
| 1953 | printf ("%s\n", TCC_VERSION); | 2028 | printf ("%s\n", TCC_VERSION); |
| @@ -1964,11 +2039,11 @@ reparse: · 10 unmodified lines | |||
| 1964 | else if (*optarg == 'n') | 2039 | else if (*optarg == 'n') |
| 1965 | x = AFF_TYPE_NONE; | 2040 | x = AFF_TYPE_NONE; |
| 1966 | else | 2041 | else |
| 1967 | tcc_warning("unsupported language '%s'", optarg); | 2042 | tcc_warning(S, "unsupported language '%s'", optarg); |
| 1968 | s->filetype = x | (s->filetype & ~AFF_TYPE_MASK); | 2043 | S->filetype = x | (S->filetype & ~AFF_TYPE_MASK); |
| 1969 | break; | 2044 | break; |
| 1970 | case TCC_OPTION_O: | 2045 | case TCC_OPTION_O: |
| 1971 | s->optimize = atoi(optarg); | 2046 | S->optimize = atoi(optarg); |
| 1972 | break; | 2047 | break; |
| 1973 | case TCC_OPTION_print_search_dirs: | 2048 | case TCC_OPTION_print_search_dirs: |
| 1974 | x = OPT_PRINT_DIRS; | 2049 | x = OPT_PRINT_DIRS; |
| @@ -1981,12 +2056,12 @@ reparse: · 6 unmodified lines | |||
| 1981 | extra_action: | 2056 | extra_action: |
| 1982 | arg_start = optind - 1; | 2057 | arg_start = optind - 1; |
| 1983 | if (arg_start != noaction) | 2058 | if (arg_start != noaction) |
| 1984 | tcc_error("cannot parse %s here", r); | 2059 | tcc_error(S, "cannot parse %s here", r); |
| 1985 | tool = x; | 2060 | tool = x; |
| 1986 | break; | 2061 | break; |
| 1987 | default: | 2062 | default: |
| 1988 | unsupported_option: | 2063 | unsupported_option: |
| 1989 | tcc_warning_c(warn_unsupported)("unsupported option '%s'", r); | 2064 | tcc_warning_c(warn_unsupported)(S, "unsupported option '%s'", r); |
| 1990 | break; | 2065 | break; |
| 1991 | } | 2066 | } |
| 1992 | } | 2067 | } |
| @@ -2000,23 +2075,23 @@ unsupported_option: · 7 unmodified lines | |||
| 2000 | return tool; | 2075 | return tool; |
| 2001 | if (optind != noaction) | 2076 | if (optind != noaction) |
| 2002 | return 0; | 2077 | return 0; |
| 2003 | if (s->verbose == 2) | 2078 | if (S->verbose == 2) |
| 2004 | return OPT_PRINT_DIRS; | 2079 | return OPT_PRINT_DIRS; |
| 2005 | if (s->verbose) | 2080 | if (S->verbose) |
| 2006 | return OPT_V; | 2081 | return OPT_V; |
| 2007 | return OPT_HELP; | 2082 | return OPT_HELP; |
| 2008 | } | 2083 | } |
| 2009 | 2084 | ||
| 2010 | LIBTCCAPI void tcc_set_options(TCCState *s, const char *r) | 2085 | LIBTCCAPI void tcc_set_options(TCCState *S, const char *r) |
| 2011 | { | 2086 | { |
| 2012 | char **argv = NULL; | 2087 | char **argv = NULL; |
| 2013 | int argc = 0; | 2088 | int argc = 0; |
| 2014 | args_parser_make_argv(r, &argc, &argv); | 2089 | args_parser_make_argv(S, r, &argc, &argv); |
| 2015 | tcc_parse_args(s, &argc, &argv, 0); | 2090 | tcc_parse_args(S, &argc, &argv, 0); |
| 2016 | dynarray_reset(&argv, &argc); | 2091 | dynarray_reset(S, &argv, &argc); |
| 2017 | } | 2092 | } |
| 2018 | 2093 | ||
| 2019 | PUB_FUNC void tcc_print_stats(TCCState *s1, unsigned total_time) | 2094 | PUB_FUNC void tcc_print_stats(TCCState *S, unsigned total_time) |
| 2020 | { | 2095 | { |
| 2021 | if (total_time < 1) | 2096 | if (total_time < 1) |
| 2022 | total_time = 1; | 2097 | total_time = 1; |
| @@ -2029,12 +2104,14 @@ PUB_FUNC void tcc_print_stats(TCCState *s1, unsigned total_time) · 6 unmodified lines | |||
| 2029 | (unsigned)total_lines*1000/total_time, | 2104 | (unsigned)total_lines*1000/total_time, |
| 2030 | (double)total_bytes/1000/total_time); | 2105 | (double)total_bytes/1000/total_time); |
| 2031 | fprintf(stderr, "* text %d, data.rw %d, data.ro %d, bss %d bytes\n", | 2106 | fprintf(stderr, "* text %d, data.rw %d, data.ro %d, bss %d bytes\n", |
| 2032 | s1->total_output[0], | 2107 | S->total_output[0], |
| 2033 | s1->total_output[1], | 2108 | S->total_output[1], |
| 2034 | s1->total_output[2], | 2109 | S->total_output[2], |
| 2035 | s1->total_output[3] | 2110 | S->total_output[3] |
| 2036 | ); | 2111 | ); |
| 2037 | #ifdef MEM_DEBUG | 2112 | #ifdef MEM_DEBUG |
| 2038 | fprintf(stderr, "* %d bytes memory used\n", mem_max_size); | 2113 | fprintf(stderr, "* %d bytes memory used\n", mem_max_size); |
| 2039 | #endif | 2114 | #endif |
| 2040 | } | 2115 | } |
| 2116 | |||
| 2117 | #include "tccqsort.c" | ||
| @@ -15,56 +15,95 @@ typedef struct TCCState TCCState; · 14 unmodified lines | |||
| 15 | 15 | ||
| 16 | typedef void (*TCCErrorFunc)(void *opaque, const char *msg); | 16 | typedef void (*TCCErrorFunc)(void *opaque, const char *msg); |
| 17 | 17 | ||
| 18 | #ifndef _OFF_T_DEFINED | ||
| 19 | #define _OFF_T_DEFINED | ||
| 20 | #ifndef _OFF_T_ | ||
| 21 | #define _OFF_T_ | ||
| 22 | typedef long _off_t; | ||
| 23 | #ifndef _SIZE_T_ | ||
| 24 | #define _SIZE_T_ | ||
| 25 | typedef unsigned long size_t; | ||
| 26 | #endif | ||
| 27 | #if !defined(NO_OLDNAMES) || defined(_POSIX) | ||
| 28 | typedef long off_t; | ||
| 29 | #endif | ||
| 30 | #endif | ||
| 31 | #endif | ||
| 32 | |||
| 33 | struct vio_module_t; | ||
| 34 | |||
| 35 | typedef struct vio_fd { | ||
| 36 | int fd; | ||
| 37 | void *vio_udata; | ||
| 38 | struct vio_module_t *vio_module; | ||
| 39 | } vio_fd; | ||
| 40 | |||
| 41 | #define CALL_VIO_OPEN_FIRST 0x01 | ||
| 42 | #define CALL_VIO_OPEN_LAST 0x02 | ||
| 43 | |||
| 44 | typedef struct vio_module_t { | ||
| 45 | void *user_data; | ||
| 46 | struct TCCState *S; | ||
| 47 | int call_vio_open_flags; /*CALL_VIO_OPEN_FIRST, CALL_VIO_OPEN_LAST, one or both */ | ||
| 48 | int (*vio_open)(vio_fd *fd, const char *fn, int oflag) ; | ||
| 49 | off_t (*vio_lseek)(vio_fd fd, off_t offset, int whence); | ||
| 50 | size_t (*vio_read)(vio_fd fd, void *buf, size_t bytes); | ||
| 51 | int (*vio_close)(vio_fd *fd); | ||
| 52 | } vio_module_t; | ||
| 53 | |||
| 18 | /* create a new TCC compilation context */ | 54 | /* create a new TCC compilation context */ |
| 19 | LIBTCCAPI TCCState *tcc_new(void); | 55 | LIBTCCAPI TCCState *tcc_new(void); |
| 20 | 56 | ||
| 21 | /* free a TCC compilation context */ | 57 | /* free a TCC compilation context */ |
| 22 | LIBTCCAPI void tcc_delete(TCCState *s); | 58 | LIBTCCAPI void tcc_delete(TCCState *S); |
| 23 | 59 | ||
| 24 | /* set CONFIG_TCCDIR at runtime */ | 60 | /* set CONFIG_TCCDIR at runtime */ |
| 25 | LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path); | 61 | LIBTCCAPI void tcc_set_lib_path(TCCState *S, const char *path); |
| 26 | 62 | ||
| 27 | /* set error/warning display callback */ | 63 | /* set error/warning display callback */ |
| 28 | LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque, TCCErrorFunc error_func); | 64 | LIBTCCAPI void tcc_set_error_func(TCCState *S, void *error_opaque, TCCErrorFunc error_func); |
| 29 | 65 | ||
| 30 | /* return error/warning callback */ | 66 | /* return error/warning callback */ |
| 31 | LIBTCCAPI TCCErrorFunc tcc_get_error_func(TCCState *s); | 67 | LIBTCCAPI TCCErrorFunc tcc_get_error_func(TCCState *S); |
| 32 | 68 | ||
| 33 | /* return error/warning callback opaque pointer */ | 69 | /* return error/warning callback opaque pointer */ |
| 34 | LIBTCCAPI void *tcc_get_error_opaque(TCCState *s); | 70 | LIBTCCAPI void *tcc_get_error_opaque(TCCState *S); |
| 35 | 71 | ||
| 36 | /* set options as from command line (multiple supported) */ | 72 | /* set options as from command line (multiple supported) */ |
| 37 | LIBTCCAPI void tcc_set_options(TCCState *s, const char *str); | 73 | LIBTCCAPI void tcc_set_options(TCCState *S, const char *str); |
| 74 | |||
| 75 | /* set virtual io module */ | ||
| 76 | LIBTCCAPI void tcc_set_vio_module(TCCState *S, vio_module_t *vio_module); | ||
| 38 | 77 | ||
| 39 | /*****************************/ | 78 | /*****************************/ |
| 40 | /* preprocessor */ | 79 | /* preprocessor */ |
| 41 | 80 | ||
| 42 | /* add include path */ | 81 | /* add include path */ |
| 43 | LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname); | 82 | LIBTCCAPI int tcc_add_include_path(TCCState *S, const char *pathname); |
| 44 | 83 | ||
| 45 | /* add in system include path */ | 84 | /* add in system include path */ |
| 46 | LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname); | 85 | LIBTCCAPI int tcc_add_sysinclude_path(TCCState *S, const char *pathname); |
| 47 | 86 | ||
| 48 | /* define preprocessor symbol 'sym'. value can be NULL, sym can be "sym=val" */ | 87 | /* define preprocessor symbol 'sym'. value can be NULL, sym can be "sym=val" */ |
| 49 | LIBTCCAPI void tcc_define_symbol(TCCState *s, const char *sym, const char *value); | 88 | LIBTCCAPI void tcc_define_symbol(TCCState *S, const char *sym, const char *value); |
| 50 | 89 | ||
| 51 | /* undefine preprocess symbol 'sym' */ | 90 | /* undefine preprocess symbol 'sym' */ |
| 52 | LIBTCCAPI void tcc_undefine_symbol(TCCState *s, const char *sym); | 91 | LIBTCCAPI void tcc_undefine_symbol(TCCState *S, const char *sym); |
| 53 | 92 | ||
| 54 | /*****************************/ | 93 | /*****************************/ |
| 55 | /* compiling */ | 94 | /* compiling */ |
| 56 | 95 | ||
| 57 | /* add a file (C file, dll, object, library, ld script). Return -1 if error. */ | 96 | /* add a file (C file, dll, object, library, ld script). Return -1 if error. */ |
| 58 | LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename); | 97 | LIBTCCAPI int tcc_add_file(TCCState *S, const char *filename); |
| 59 | 98 | ||
| 60 | /* compile a string containing a C source. Return -1 if error. */ | 99 | /* compile a string containing a C source. Return -1 if error. */ |
| 61 | LIBTCCAPI int tcc_compile_string(TCCState *s, const char *buf); | 100 | LIBTCCAPI int tcc_compile_string(TCCState *S, const char *buf); |
| 62 | 101 | ||
| 63 | /*****************************/ | 102 | /*****************************/ |
| 64 | /* linking commands */ | 103 | /* linking commands */ |
| 65 | 104 | ||
| 66 | /* set output type. MUST BE CALLED before any compilation */ | 105 | /* set output type. MUST BE CALLED before any compilation */ |
| 67 | LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type); | 106 | LIBTCCAPI int tcc_set_output_type(TCCState *S, int output_type); |
| 68 | #define TCC_OUTPUT_MEMORY 1 /* output will be run in memory (default) */ | 107 | #define TCC_OUTPUT_MEMORY 1 /* output will be run in memory (default) */ |
| 69 | #define TCC_OUTPUT_EXE 2 /* executable file */ | 108 | #define TCC_OUTPUT_EXE 2 /* executable file */ |
| 70 | #define TCC_OUTPUT_DLL 3 /* dynamic library */ | 109 | #define TCC_OUTPUT_DLL 3 /* dynamic library */ |
| @@ -72,24 +111,24 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type); · 1 unmodified line | |||
| 72 | #define TCC_OUTPUT_PREPROCESS 5 /* only preprocess (used internally) */ | 111 | #define TCC_OUTPUT_PREPROCESS 5 /* only preprocess (used internally) */ |
| 73 | 112 | ||
| 74 | /* equivalent to -Lpath option */ | 113 | /* equivalent to -Lpath option */ |
| 75 | LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname); | 114 | LIBTCCAPI int tcc_add_library_path(TCCState *S, const char *pathname); |
| 76 | 115 | ||
| 77 | /* the library name is the same as the argument of the '-l' option */ | 116 | /* the library name is the same as the argument of the '-l' option */ |
| 78 | LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname); | 117 | LIBTCCAPI int tcc_add_library(TCCState *S, const char *libraryname); |
| 79 | 118 | ||
| 80 | /* add a symbol to the compiled program */ | 119 | /* add a symbol to the compiled program */ |
| 81 | LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val); | 120 | LIBTCCAPI int tcc_add_symbol(TCCState *S, const char *name, const void *val); |
| 82 | 121 | ||
| 83 | /* output an executable, library or object file. DO NOT call | 122 | /* output an executable, library or object file. DO NOT call |
| 84 | tcc_relocate() before. */ | 123 | tcc_relocate() before. */ |
| 85 | LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename); | 124 | LIBTCCAPI int tcc_output_file(TCCState *S, const char *filename); |
| 86 | 125 | ||
| 87 | /* link and run main() function and return its value. DO NOT call | 126 | /* link and run main() function and return its value. DO NOT call |
| 88 | tcc_relocate() before. */ | 127 | tcc_relocate() before. */ |
| 89 | LIBTCCAPI int tcc_run(TCCState *s, int argc, char **argv); | 128 | LIBTCCAPI int tcc_run(TCCState *S, int argc, char **argv); |
| 90 | 129 | ||
| 91 | /* do all relocations (needed before using tcc_get_symbol()) */ | 130 | /* do all relocations (needed before using tcc_get_symbol()) */ |
| 92 | LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr); | 131 | LIBTCCAPI int tcc_relocate(TCCState *S, void *ptr); |
| 93 | /* possible values for 'ptr': | 132 | /* possible values for 'ptr': |
| 94 | - TCC_RELOCATE_AUTO : Allocate and manage memory internally | 133 | - TCC_RELOCATE_AUTO : Allocate and manage memory internally |
| 95 | - NULL : return required memory size for the step below | 134 | - NULL : return required memory size for the step below |
| @@ -98,12 +137,24 @@ LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr); · 2 unmodified lines | |||
| 98 | #define TCC_RELOCATE_AUTO (void*)1 | 137 | #define TCC_RELOCATE_AUTO (void*)1 |
| 99 | 138 | ||
| 100 | /* return symbol value or NULL if not found */ | 139 | /* return symbol value or NULL if not found */ |
| 101 | LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name); | 140 | LIBTCCAPI void *tcc_get_symbol(TCCState *S, const char *name); |
| 102 | 141 | ||
| 103 | /* return symbol value or NULL if not found */ | 142 | /* return symbol value or NULL if not found */ |
| 104 | LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx, | 143 | LIBTCCAPI void tcc_list_symbols(TCCState *S, void *ctx, |
| 105 | void (*symbol_cb)(void *ctx, const char *name, const void *val)); | 144 | void (*symbol_cb)(void *ctx, const char *name, const void *val)); |
| 106 | 145 | ||
| 146 | typedef int (*tcc_cmpfun)(const void *, const void *, void *); | ||
| 147 | LIBTCCAPI void tcc_qsort_s(void *base, size_t nel, size_t width, tcc_cmpfun cmp, void *ctx); | ||
| 148 | |||
| 149 | enum { /*need better names for some of then*/ | ||
| 150 | TCC_OPTION_d_BI = 1, | ||
| 151 | TCC_OPTION_d_D = 3, | ||
| 152 | TCC_OPTION_d_4 = 4, | ||
| 153 | TCC_OPTION_d_M = 7, | ||
| 154 | TCC_OPTION_d_t = 16, | ||
| 155 | TCC_OPTION_d_32 = 32, | ||
| 156 | }; | ||
| 157 | |||
| 107 | #ifdef __cplusplus | 158 | #ifdef __cplusplus |
| 108 | } | 159 | } |
| 109 | #endif | 160 | #endif |
| @@ -9,9 +9,9 @@ · 8 unmodified lines | |||
| 9 | #define CONFIG_TCC_ASM | 9 | #define CONFIG_TCC_ASM |
| 10 | #define NB_ASM_REGS 32 | 10 | #define NB_ASM_REGS 32 |
| 11 | 11 | ||
| 12 | ST_FUNC void g(int c); | 12 | ST_FUNC void g(TCCState* S, int c); |
| 13 | ST_FUNC void gen_le16(int c); | 13 | ST_FUNC void gen_le16(TCCState* S, int c); |
| 14 | ST_FUNC void gen_le32(int c); | 14 | ST_FUNC void gen_le32(TCCState* S, int c); |
| 15 | 15 | ||
| 16 | /*************************************************************/ | 16 | /*************************************************************/ |
| 17 | #else | 17 | #else |
| @@ -20,85 +20,85 @@ ST_FUNC void gen_le32(int c); · 2 unmodified lines | |||
| 20 | #include "tcc.h" | 20 | #include "tcc.h" |
| 21 | 21 | ||
| 22 | /* XXX: make it faster ? */ | 22 | /* XXX: make it faster ? */ |
| 23 | ST_FUNC void g(int c) | 23 | ST_FUNC void g(TCCState* S, int c) |
| 24 | { | 24 | { |
| 25 | int ind1; | 25 | int ind1; |
| 26 | if (nocode_wanted) | 26 | if (S->tccgen_nocode_wanted) |
| 27 | return; | 27 | return; |
| 28 | ind1 = ind + 1; | 28 | ind1 = S->tccgen_ind + 1; |
| 29 | if (ind1 > cur_text_section->data_allocated) | 29 | if (ind1 > cur_text_section->data_allocated) |
| 30 | section_realloc(cur_text_section, ind1); | 30 | section_realloc(S, cur_text_section, ind1); |
| 31 | cur_text_section->data[ind] = c; | 31 | cur_text_section->data[S->tccgen_ind] = c; |
| 32 | ind = ind1; | 32 | S->tccgen_ind = ind1; |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | ST_FUNC void gen_le16 (int i) | 35 | ST_FUNC void gen_le16 (TCCState* S, int i) |
| 36 | { | 36 | { |
| 37 | g(i); | 37 | g(S, i); |
| 38 | g(i>>8); | 38 | g(S, i>>8); |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | ST_FUNC void gen_le32 (int i) | 41 | ST_FUNC void gen_le32 (TCCState* S, int i) |
| 42 | { | 42 | { |
| 43 | int ind1; | 43 | int ind1; |
| 44 | if (nocode_wanted) | 44 | if (S->tccgen_nocode_wanted) |
| 45 | return; | 45 | return; |
| 46 | ind1 = ind + 4; | 46 | ind1 = S->tccgen_ind + 4; |
| 47 | if (ind1 > cur_text_section->data_allocated) | 47 | if (ind1 > cur_text_section->data_allocated) |
| 48 | section_realloc(cur_text_section, ind1); | 48 | section_realloc(S, cur_text_section, ind1); |
| 49 | cur_text_section->data[ind++] = i & 0xFF; | 49 | cur_text_section->data[S->tccgen_ind++] = i & 0xFF; |
| 50 | cur_text_section->data[ind++] = (i >> 8) & 0xFF; | 50 | cur_text_section->data[S->tccgen_ind++] = (i >> 8) & 0xFF; |
| 51 | cur_text_section->data[ind++] = (i >> 16) & 0xFF; | 51 | cur_text_section->data[S->tccgen_ind++] = (i >> 16) & 0xFF; |
| 52 | cur_text_section->data[ind++] = (i >> 24) & 0xFF; | 52 | cur_text_section->data[S->tccgen_ind++] = (i >> 24) & 0xFF; |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | ST_FUNC void gen_expr32(ExprValue *pe) | 55 | ST_FUNC void gen_expr32(TCCState* S, ExprValue *pe) |
| 56 | { | 56 | { |
| 57 | gen_le32(pe->v); | 57 | gen_le32(S, pe->v); |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | static void asm_emit_opcode(uint32_t opcode) { | 60 | static void asm_emit_opcode(TCCState* S, uint32_t opcode) { |
| 61 | gen_le32(opcode); | 61 | gen_le32(S, opcode); |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | static void asm_nullary_opcode(TCCState *s1, int token) | 64 | static void asm_nullary_opcode(TCCState *S, int token) |
| 65 | { | 65 | { |
| 66 | switch (token) { | 66 | switch (token) { |
| 67 | // Sync instructions | 67 | // Sync instructions |
| 68 | 68 | ||
| 69 | case TOK_ASM_fence: // I | 69 | case TOK_ASM_fence: // I |
| 70 | asm_emit_opcode((0x3 << 2) | 3 | (0 << 12)); | 70 | asm_emit_opcode(S, (0x3 << 2) | 3 | (0 << 12)); |
| 71 | return; | 71 | return; |
| 72 | case TOK_ASM_fence_i: // I | 72 | case TOK_ASM_fence_i: // I |
| 73 | asm_emit_opcode((0x3 << 2) | 3| (1 << 12)); | 73 | asm_emit_opcode(S, (0x3 << 2) | 3| (1 << 12)); |
| 74 | return; | 74 | return; |
| 75 | 75 | ||
| 76 | // System calls | 76 | // System calls |
| 77 | 77 | ||
| 78 | case TOK_ASM_scall: // I (pseudo) | 78 | case TOK_ASM_scall: // I (pseudo) |
| 79 | asm_emit_opcode((0x1C << 2) | 3 | (0 << 12)); | 79 | asm_emit_opcode(S, (0x1C << 2) | 3 | (0 << 12)); |
| 80 | return; | 80 | return; |
| 81 | case TOK_ASM_sbreak: // I (pseudo) | 81 | case TOK_ASM_sbreak: // I (pseudo) |
| 82 | asm_emit_opcode((0x1C << 2) | 3 | (0 << 12) | (1 << 20)); | 82 | asm_emit_opcode(S, (0x1C << 2) | 3 | (0 << 12) | (1 << 20)); |
| 83 | return; | 83 | return; |
| 84 | 84 | ||
| 85 | // Privileged Instructions | 85 | // Privileged Instructions |
| 86 | 86 | ||
| 87 | case TOK_ASM_ecall: | 87 | case TOK_ASM_ecall: |
| 88 | asm_emit_opcode((0x1C << 2) | 3 | (0 << 20)); | 88 | asm_emit_opcode(S, (0x1C << 2) | 3 | (0 << 20)); |
| 89 | return; | 89 | return; |
| 90 | case TOK_ASM_ebreak: | 90 | case TOK_ASM_ebreak: |
| 91 | asm_emit_opcode((0x1C << 2) | 3 | (1 << 20)); | 91 | asm_emit_opcode(S, (0x1C << 2) | 3 | (1 << 20)); |
| 92 | return; | 92 | return; |
| 93 | 93 | ||
| 94 | // Other | 94 | // Other |
| 95 | 95 | ||
| 96 | case TOK_ASM_wfi: | 96 | case TOK_ASM_wfi: |
| 97 | asm_emit_opcode((0x1C << 2) | 3 | (0x105 << 20)); | 97 | asm_emit_opcode(S, (0x1C << 2) | 3 | (0x105 << 20)); |
| 98 | return; | 98 | return; |
| 99 | 99 | ||
| 100 | default: | 100 | default: |
| 101 | expect("nullary instruction"); | 101 | expect(S, "nullary instruction"); |
| 102 | } | 102 | } |
| 103 | } | 103 | } |
| 104 | 104 | ||
| @@ -121,30 +121,30 @@ typedef struct Operand { · 16 unmodified lines | |||
| 121 | } Operand; | 121 | } Operand; |
| 122 | 122 | ||
| 123 | /* Parse a text containing operand and store the result in OP */ | 123 | /* Parse a text containing operand and store the result in OP */ |
| 124 | static void parse_operand(TCCState *s1, Operand *op) | 124 | static void parse_operand(TCCState *S, Operand *op) |
| 125 | { | 125 | { |
| 126 | ExprValue e; | 126 | ExprValue e; |
| 127 | int8_t reg; | 127 | int8_t reg; |
| 128 | 128 | ||
| 129 | op->type = 0; | 129 | op->type = 0; |
| 130 | 130 | ||
| 131 | if ((reg = asm_parse_regvar(tok)) != -1) { | 131 | if ((reg = asm_parse_regvar(S, S->tccpp_tok)) != -1) { |
| 132 | next(); // skip register name | 132 | next(S); // skip register name |
| 133 | op->type = OP_REG; | 133 | op->type = OP_REG; |
| 134 | op->reg = (uint8_t) reg; | 134 | op->reg = (uint8_t) reg; |
| 135 | return; | 135 | return; |
| 136 | } else if (tok == '$') { | 136 | } else if (S->tccpp_tok == '$') { |
| 137 | /* constant value */ | 137 | /* constant value */ |
| 138 | next(); // skip '#' or '$' | 138 | next(S); // skip '#' or '$' |
| 139 | } | 139 | } |
| 140 | asm_expr(s1, &e); | 140 | asm_expr(S, &e); |
| 141 | op->type = OP_IM32; | 141 | op->type = OP_IM32; |
| 142 | op->e = e; | 142 | op->e = e; |
| 143 | if (!op->e.sym) { | 143 | if (!op->e.sym) { |
| 144 | if ((int) op->e.v >= -2048 && (int) op->e.v < 2048) | 144 | if ((int) op->e.v >= -2048 && (int) op->e.v < 2048) |
| 145 | op->type = OP_IM12S; | 145 | op->type = OP_IM12S; |
| 146 | } else | 146 | } else |
| 147 | expect("operand"); | 147 | expect(S, "operand"); |
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | #define ENCODE_RS1(register_index) ((register_index) << 15) | 150 | #define ENCODE_RS1(register_index) ((register_index) << 15) |
| @@ -152,96 +152,96 @@ static void parse_operand(TCCState *s1, Operand *op) · 1 unmodified line | |||
| 152 | #define ENCODE_RD(register_index) ((register_index) << 7) | 152 | #define ENCODE_RD(register_index) ((register_index) << 7) |
| 153 | 153 | ||
| 154 | // Note: Those all map to CSR--so they are pseudo-instructions. | 154 | // Note: Those all map to CSR--so they are pseudo-instructions. |
| 155 | static void asm_unary_opcode(TCCState *s1, int token) | 155 | static void asm_unary_opcode(TCCState *S, int token) |
| 156 | { | 156 | { |
| 157 | uint32_t opcode = (0x1C << 2) | 3 | (2 << 12); | 157 | uint32_t opcode = (0x1C << 2) | 3 | (2 << 12); |
| 158 | Operand op; | 158 | Operand op; |
| 159 | parse_operand(s1, &op); | 159 | parse_operand(S, &op); |
| 160 | if (op.type != OP_REG) { | 160 | if (op.type != OP_REG) { |
| 161 | expect("register"); | 161 | expect(S, "register"); |
| 162 | return; | 162 | return; |
| 163 | } | 163 | } |
| 164 | opcode |= ENCODE_RD(op.reg); | 164 | opcode |= ENCODE_RD(op.reg); |
| 165 | 165 | ||
| 166 | switch (token) { | 166 | switch (token) { |
| 167 | case TOK_ASM_rdcycle: | 167 | case TOK_ASM_rdcycle: |
| 168 | asm_emit_opcode(opcode | (0xC00 << 20)); | 168 | asm_emit_opcode(S, opcode | (0xC00 << 20)); |
| 169 | return; | 169 | return; |
| 170 | case TOK_ASM_rdcycleh: | 170 | case TOK_ASM_rdcycleh: |
| 171 | asm_emit_opcode(opcode | (0xC80 << 20)); | 171 | asm_emit_opcode(S, opcode | (0xC80 << 20)); |
| 172 | return; | 172 | return; |
| 173 | case TOK_ASM_rdtime: | 173 | case TOK_ASM_rdtime: |
| 174 | asm_emit_opcode(opcode | (0xC01 << 20) | ENCODE_RD(op.reg)); | 174 | asm_emit_opcode(S, opcode | (0xC01 << 20) | ENCODE_RD(op.reg)); |
| 175 | return; | 175 | return; |
| 176 | case TOK_ASM_rdtimeh: | 176 | case TOK_ASM_rdtimeh: |
| 177 | asm_emit_opcode(opcode | (0xC81 << 20) | ENCODE_RD(op.reg)); | 177 | asm_emit_opcode(S, opcode | (0xC81 << 20) | ENCODE_RD(op.reg)); |
| 178 | return; | 178 | return; |
| 179 | case TOK_ASM_rdinstret: | 179 | case TOK_ASM_rdinstret: |
| 180 | asm_emit_opcode(opcode | (0xC02 << 20) | ENCODE_RD(op.reg)); | 180 | asm_emit_opcode(S, opcode | (0xC02 << 20) | ENCODE_RD(op.reg)); |
| 181 | return; | 181 | return; |
| 182 | case TOK_ASM_rdinstreth: | 182 | case TOK_ASM_rdinstreth: |
| 183 | asm_emit_opcode(opcode | (0xC82 << 20) | ENCODE_RD(op.reg)); | 183 | asm_emit_opcode(S, opcode | (0xC82 << 20) | ENCODE_RD(op.reg)); |
| 184 | return; | 184 | return; |
| 185 | default: | 185 | default: |
| 186 | expect("unary instruction"); | 186 | expect(S, "unary instruction"); |
| 187 | } | 187 | } |
| 188 | } | 188 | } |
| 189 | 189 | ||
| 190 | static void asm_emit_u(int token, uint32_t opcode, const Operand* rd, const Operand* rs2) | 190 | static void asm_emit_u(TCCState *S, int token, uint32_t opcode, const Operand* rd, const Operand* rs2) |
| 191 | { | 191 | { |
| 192 | if (rd->type != OP_REG) { | 192 | if (rd->type != OP_REG) { |
| 193 | tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL)); | 193 | tcc_error(S, "'%s': Expected destination operand that is a register", get_tok_str(S, token, NULL)); |
| 194 | return; | 194 | return; |
| 195 | } | 195 | } |
| 196 | if (rs2->type != OP_IM12S && rs2->type != OP_IM32) { | 196 | if (rs2->type != OP_IM12S && rs2->type != OP_IM32) { |
| 197 | tcc_error("'%s': Expected second source operand that is an immediate value", get_tok_str(token, NULL)); | 197 | tcc_error(S, "'%s': Expected second source operand that is an immediate value", get_tok_str(S, token, NULL)); |
| 198 | return; | 198 | return; |
| 199 | } else if (rs2->e.v >= 0x100000) { | 199 | } else if (rs2->e.v >= 0x100000) { |
| 200 | tcc_error("'%s': Expected second source operand that is an immediate value between 0 and 0xfffff", get_tok_str(token, NULL)); | 200 | tcc_error(S, "'%s': Expected second source operand that is an immediate value between 0 and 0xfffff", get_tok_str(S, token, NULL)); |
| 201 | return; | 201 | return; |
| 202 | } | 202 | } |
| 203 | /* U-type instruction: | 203 | /* U-type instruction: |
| 204 | 31...12 imm[31:12] | 204 | 31...12 imm[31:12] |
| 205 | 11...7 rd | 205 | 11...7 rd |
| 206 | 6...0 opcode */ | 206 | 6...0 opcode */ |
| 207 | gen_le32(opcode | ENCODE_RD(rd->reg) | (rs2->e.v << 12)); | 207 | gen_le32(S, opcode | ENCODE_RD(rd->reg) | (rs2->e.v << 12)); |
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | static void asm_binary_opcode(TCCState* s1, int token) | 210 | static void asm_binary_opcode(TCCState* S, int token) |
| 211 | { | 211 | { |
| 212 | Operand ops[2]; | 212 | Operand ops[2]; |
| 213 | parse_operand(s1, &ops[0]); | 213 | parse_operand(S, &ops[0]); |
| 214 | if (tok == ',') | 214 | if (S->tccpp_tok == ',') |
| 215 | next(); | 215 | next(S); |
| 216 | else | 216 | else |
| 217 | expect("','"); | 217 | expect(S, "','"); |
| 218 | parse_operand(s1, &ops[1]); | 218 | parse_operand(S, &ops[1]); |
| 219 | 219 | ||
| 220 | switch (token) { | 220 | switch (token) { |
| 221 | case TOK_ASM_lui: | 221 | case TOK_ASM_lui: |
| 222 | asm_emit_u(token, (0xD << 2) | 3, &ops[0], &ops[1]); | 222 | asm_emit_u(S, token, (0xD << 2) | 3, &ops[0], &ops[1]); |
| 223 | return; | 223 | return; |
| 224 | case TOK_ASM_auipc: | 224 | case TOK_ASM_auipc: |
| 225 | asm_emit_u(token, (0x05 << 2) | 3, &ops[0], &ops[1]); | 225 | asm_emit_u(S, token, (0x05 << 2) | 3, &ops[0], &ops[1]); |
| 226 | return; | 226 | return; |
| 227 | default: | 227 | default: |
| 228 | expect("binary instruction"); | 228 | expect(S, "binary instruction"); |
| 229 | } | 229 | } |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | /* caller: Add funct3, funct7 into opcode */ | 232 | /* caller: Add funct3, funct7 into opcode */ |
| 233 | static void asm_emit_r(int token, uint32_t opcode, const Operand* rd, const Operand* rs1, const Operand* rs2) | 233 | static void asm_emit_r(TCCState* S, int token, uint32_t opcode, const Operand* rd, const Operand* rs1, const Operand* rs2) |
| 234 | { | 234 | { |
| 235 | if (rd->type != OP_REG) { | 235 | if (rd->type != OP_REG) { |
| 236 | tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL)); | 236 | tcc_error(S, "'%s': Expected destination operand that is a register", get_tok_str(S, token, NULL)); |
| 237 | return; | 237 | return; |
| 238 | } | 238 | } |
| 239 | if (rs1->type != OP_REG) { | 239 | if (rs1->type != OP_REG) { |
| 240 | tcc_error("'%s': Expected first source operand that is a register", get_tok_str(token, NULL)); | 240 | tcc_error(S, "'%s': Expected first source operand that is a register", get_tok_str(S, token, NULL)); |
| 241 | return; | 241 | return; |
| 242 | } | 242 | } |
| 243 | if (rs2->type != OP_REG) { | 243 | if (rs2->type != OP_REG) { |
| 244 | tcc_error("'%s': Expected second source operand that is a register or immediate", get_tok_str(token, NULL)); | 244 | tcc_error(S, "'%s': Expected second source operand that is a register or immediate", get_tok_str(S, token, NULL)); |
| 245 | return; | 245 | return; |
| 246 | } | 246 | } |
| 247 | /* R-type instruction: | 247 | /* R-type instruction: |
| @@ -251,22 +251,22 @@ static void asm_emit_r(int token, uint32_t opcode, const Operand* rd, const Oper · 3 unmodified lines | |||
| 251 | 14...12 funct3 | 251 | 14...12 funct3 |
| 252 | 11...7 rd | 252 | 11...7 rd |
| 253 | 6...0 opcode */ | 253 | 6...0 opcode */ |
| 254 | gen_le32(opcode | ENCODE_RD(rd->reg) | ENCODE_RS1(rs1->reg) | ENCODE_RS2(rs2->reg)); | 254 | gen_le32(S, opcode | ENCODE_RD(rd->reg) | ENCODE_RS1(rs1->reg) | ENCODE_RS2(rs2->reg)); |
| 255 | } | 255 | } |
| 256 | 256 | ||
| 257 | /* caller: Add funct3 into opcode */ | 257 | /* caller: Add funct3 into opcode */ |
| 258 | static void asm_emit_i(int token, uint32_t opcode, const Operand* rd, const Operand* rs1, const Operand* rs2) | 258 | static void asm_emit_i(TCCState* S, int token, uint32_t opcode, const Operand* rd, const Operand* rs1, const Operand* rs2) |
| 259 | { | 259 | { |
| 260 | if (rd->type != OP_REG) { | 260 | if (rd->type != OP_REG) { |
| 261 | tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL)); | 261 | tcc_error(S, "'%s': Expected destination operand that is a register", get_tok_str(S, token, NULL)); |
| 262 | return; | 262 | return; |
| 263 | } | 263 | } |
| 264 | if (rs1->type != OP_REG) { | 264 | if (rs1->type != OP_REG) { |
| 265 | tcc_error("'%s': Expected first source operand that is a register", get_tok_str(token, NULL)); | 265 | tcc_error(S, "'%s': Expected first source operand that is a register", get_tok_str(S, token, NULL)); |
| 266 | return; | 266 | return; |
| 267 | } | 267 | } |
| 268 | if (rs2->type != OP_IM12S) { | 268 | if (rs2->type != OP_IM12S) { |
| 269 | tcc_error("'%s': Expected second source operand that is an immediate value between 0 and 4095", get_tok_str(token, NULL)); | 269 | tcc_error(S, "'%s': Expected second source operand that is an immediate value between 0 and 4095", get_tok_str(S, token, NULL)); |
| 270 | return; | 270 | return; |
| 271 | } | 271 | } |
| 272 | /* I-type instruction: | 272 | /* I-type instruction: |
| @@ -276,156 +276,156 @@ static void asm_emit_i(int token, uint32_t opcode, const Operand* rd, const Oper · 3 unmodified lines | |||
| 276 | 11...7 rd | 276 | 11...7 rd |
| 277 | 6...0 opcode */ | 277 | 6...0 opcode */ |
| 278 | 278 | ||
| 279 | gen_le32(opcode | ENCODE_RD(rd->reg) | ENCODE_RS1(rs1->reg) | (rs2->e.v << 20)); | 279 | gen_le32(S, opcode | ENCODE_RD(rd->reg) | ENCODE_RS1(rs1->reg) | (rs2->e.v << 20)); |
| 280 | } | 280 | } |
| 281 | 281 | ||
| 282 | static void asm_shift_opcode(TCCState *s1, int token) | 282 | static void asm_shift_opcode(TCCState *S, int token) |
| 283 | { | 283 | { |
| 284 | Operand ops[3]; | 284 | Operand ops[3]; |
| 285 | parse_operand(s1, &ops[0]); | 285 | parse_operand(S, &ops[0]); |
| 286 | if (tok == ',') | 286 | if (S->tccpp_tok == ',') |
| 287 | next(); | 287 | next(S); |
| 288 | else | 288 | else |
| 289 | expect("','"); | 289 | expect(S, "','"); |
| 290 | parse_operand(s1, &ops[1]); | 290 | parse_operand(S, &ops[1]); |
| 291 | if (tok == ',') | 291 | if (S->tccpp_tok == ',') |
| 292 | next(); | 292 | next(S); |
| 293 | else | 293 | else |
| 294 | expect("','"); | 294 | expect(S, "','"); |
| 295 | parse_operand(s1, &ops[2]); | 295 | parse_operand(S, &ops[2]); |
| 296 | 296 | ||
| 297 | switch (token) { | 297 | switch (token) { |
| 298 | case TOK_ASM_sll: | 298 | case TOK_ASM_sll: |
| 299 | asm_emit_r(token, (0xC << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]); | 299 | asm_emit_r(S, token, (0xC << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]); |
| 300 | return; | 300 | return; |
| 301 | case TOK_ASM_slli: | 301 | case TOK_ASM_slli: |
| 302 | asm_emit_i(token, (4 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]); | 302 | asm_emit_i(S, token, (4 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]); |
| 303 | return; | 303 | return; |
| 304 | case TOK_ASM_srl: | 304 | case TOK_ASM_srl: |
| 305 | asm_emit_r(token, (0xC << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]); | 305 | asm_emit_r(S, token, (0xC << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]); |
| 306 | return; | 306 | return; |
| 307 | case TOK_ASM_srli: | 307 | case TOK_ASM_srli: |
| 308 | asm_emit_i(token, (0x4 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]); | 308 | asm_emit_i(S, token, (0x4 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]); |
| 309 | return; | 309 | return; |
| 310 | case TOK_ASM_sra: | 310 | case TOK_ASM_sra: |
| 311 | asm_emit_r(token, (0xC << 2) | 3 | (5 << 12) | (32 << 25), &ops[0], &ops[1], &ops[2]); | 311 | asm_emit_r(S, token, (0xC << 2) | 3 | (5 << 12) | (32 << 25), &ops[0], &ops[1], &ops[2]); |
| 312 | return; | 312 | return; |
| 313 | case TOK_ASM_srai: | 313 | case TOK_ASM_srai: |
| 314 | asm_emit_i(token, (0x4 << 2) | 3 | (5 << 12) | (16 << 26), &ops[0], &ops[1], &ops[2]); | 314 | asm_emit_i(S, token, (0x4 << 2) | 3 | (5 << 12) | (16 << 26), &ops[0], &ops[1], &ops[2]); |
| 315 | return; | 315 | return; |
| 316 | case TOK_ASM_sllw: | 316 | case TOK_ASM_sllw: |
| 317 | asm_emit_r(token, (0xE << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]); | 317 | asm_emit_r(S, token, (0xE << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]); |
| 318 | return; | 318 | return; |
| 319 | case TOK_ASM_slliw: | 319 | case TOK_ASM_slliw: |
| 320 | asm_emit_i(token, (6 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]); | 320 | asm_emit_i(S, token, (6 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]); |
| 321 | return; | 321 | return; |
| 322 | case TOK_ASM_srlw: | 322 | case TOK_ASM_srlw: |
| 323 | asm_emit_r(token, (0xE << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]); | 323 | asm_emit_r(S, token, (0xE << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]); |
| 324 | return; | 324 | return; |
| 325 | case TOK_ASM_srliw: | 325 | case TOK_ASM_srliw: |
| 326 | asm_emit_i(token, (0x6 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]); | 326 | asm_emit_i(S, token, (0x6 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]); |
| 327 | return; | 327 | return; |
| 328 | case TOK_ASM_sraw: | 328 | case TOK_ASM_sraw: |
| 329 | asm_emit_r(token, (0xE << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]); | 329 | asm_emit_r(S, token, (0xE << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]); |
| 330 | return; | 330 | return; |
| 331 | case TOK_ASM_sraiw: | 331 | case TOK_ASM_sraiw: |
| 332 | asm_emit_i(token, (0x6 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]); | 332 | asm_emit_i(S, token, (0x6 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]); |
| 333 | return; | 333 | return; |
| 334 | default: | 334 | default: |
| 335 | expect("shift instruction"); | 335 | expect(S, "shift instruction"); |
| 336 | } | 336 | } |
| 337 | } | 337 | } |
| 338 | 338 | ||
| 339 | static void asm_data_processing_opcode(TCCState* s1, int token) | 339 | static void asm_data_processing_opcode(TCCState* S, int token) |
| 340 | { | 340 | { |
| 341 | Operand ops[3]; | 341 | Operand ops[3]; |
| 342 | parse_operand(s1, &ops[0]); | 342 | parse_operand(S, &ops[0]); |
| 343 | if (tok == ',') | 343 | if (S->tccpp_tok == ',') |
| 344 | next(); | 344 | next(S); |
| 345 | else | 345 | else |
| 346 | expect("','"); | 346 | expect(S, "','"); |
| 347 | parse_operand(s1, &ops[1]); | 347 | parse_operand(S, &ops[1]); |
| 348 | if (tok == ',') | 348 | if (S->tccpp_tok == ',') |
| 349 | next(); | 349 | next(S); |
| 350 | else | 350 | else |
| 351 | expect("','"); | 351 | expect(S, "','"); |
| 352 | parse_operand(s1, &ops[2]); | 352 | parse_operand(S, &ops[2]); |
| 353 | 353 | ||
| 354 | switch (token) { | 354 | switch (token) { |
| 355 | // Arithmetic (RD,RS1,(RS2|IMM)); R-format, I-format or U-format | 355 | // Arithmetic (RD,RS1,(RS2|IMM)); R-format, I-format or U-format |
| 356 | 356 | ||
| 357 | case TOK_ASM_add: | 357 | case TOK_ASM_add: |
| 358 | asm_emit_r(token, (0xC << 2) | 3, &ops[0], &ops[1], &ops[2]); | 358 | asm_emit_r(S, token, (0xC << 2) | 3, &ops[0], &ops[1], &ops[2]); |
| 359 | return; | 359 | return; |
| 360 | case TOK_ASM_addi: | 360 | case TOK_ASM_addi: |
| 361 | asm_emit_i(token, (4 << 2) | 3, &ops[0], &ops[1], &ops[2]); | 361 | asm_emit_i(S, token, (4 << 2) | 3, &ops[0], &ops[1], &ops[2]); |
| 362 | return; | 362 | return; |
| 363 | case TOK_ASM_sub: | 363 | case TOK_ASM_sub: |
| 364 | asm_emit_r(token, (0xC << 2) | 3 | (32 << 25), &ops[0], &ops[1], &ops[2]); | 364 | asm_emit_r(S, token, (0xC << 2) | 3 | (32 << 25), &ops[0], &ops[1], &ops[2]); |
| 365 | return; | 365 | return; |
| 366 | case TOK_ASM_addw: | 366 | case TOK_ASM_addw: |
| 367 | asm_emit_r(token, (0xE << 2) | 3 | (0 << 12), &ops[0], &ops[1], &ops[2]); | 367 | asm_emit_r(S, token, (0xE << 2) | 3 | (0 << 12), &ops[0], &ops[1], &ops[2]); |
| 368 | return; | 368 | return; |
| 369 | case TOK_ASM_addiw: // 64 bit | 369 | case TOK_ASM_addiw: // 64 bit |
| 370 | asm_emit_i(token, (0x6 << 2) | 3 | (0 << 12), &ops[0], &ops[1], &ops[2]); | 370 | asm_emit_i(S, token, (0x6 << 2) | 3 | (0 << 12), &ops[0], &ops[1], &ops[2]); |
| 371 | return; | 371 | return; |
| 372 | case TOK_ASM_subw: | 372 | case TOK_ASM_subw: |
| 373 | asm_emit_r(token, (0xE << 2) | 3 | (0 << 12) | (32 << 25), &ops[0], &ops[1], &ops[2]); | 373 | asm_emit_r(S, token, (0xE << 2) | 3 | (0 << 12) | (32 << 25), &ops[0], &ops[1], &ops[2]); |
| 374 | return; | 374 | return; |
| 375 | 375 | ||
| 376 | // Logical (RD,RS1,(RS2|IMM)); R-format or I-format | 376 | // Logical (RD,RS1,(RS2|IMM)); R-format or I-format |
| 377 | 377 | ||
| 378 | case TOK_ASM_xor: | 378 | case TOK_ASM_xor: |
| 379 | asm_emit_r(token, (0xC << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]); | 379 | asm_emit_r(S, token, (0xC << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]); |
| 380 | return; | 380 | return; |
| 381 | case TOK_ASM_xori: | 381 | case TOK_ASM_xori: |
| 382 | asm_emit_i(token, (0x4 << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]); | 382 | asm_emit_i(S, token, (0x4 << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]); |
| 383 | return; | 383 | return; |
| 384 | case TOK_ASM_or: | 384 | case TOK_ASM_or: |
| 385 | asm_emit_r(token, (0xC << 2) | 3 | (6 << 12), &ops[0], &ops[1], &ops[2]); | 385 | asm_emit_r(S, token, (0xC << 2) | 3 | (6 << 12), &ops[0], &ops[1], &ops[2]); |
| 386 | return; | 386 | return; |
| 387 | case TOK_ASM_ori: | 387 | case TOK_ASM_ori: |
| 388 | asm_emit_i(token, (0x4 << 2) | 3 | (6 << 12), &ops[0], &ops[1], &ops[2]); | 388 | asm_emit_i(S, token, (0x4 << 2) | 3 | (6 << 12), &ops[0], &ops[1], &ops[2]); |
| 389 | return; | 389 | return; |
| 390 | case TOK_ASM_and: | 390 | case TOK_ASM_and: |
| 391 | asm_emit_r(token, (0xC << 2) | 3 | (7 << 12), &ops[0], &ops[1], &ops[2]); | 391 | asm_emit_r(S, token, (0xC << 2) | 3 | (7 << 12), &ops[0], &ops[1], &ops[2]); |
| 392 | return; | 392 | return; |
| 393 | case TOK_ASM_andi: | 393 | case TOK_ASM_andi: |
| 394 | asm_emit_i(token, (0x4 << 2) | 3 | (7 << 12), &ops[0], &ops[1], &ops[2]); | 394 | asm_emit_i(S, token, (0x4 << 2) | 3 | (7 << 12), &ops[0], &ops[1], &ops[2]); |
| 395 | return; | 395 | return; |
| 396 | 396 | ||
| 397 | // Compare (RD,RS1,(RS2|IMM)); R-format or I-format | 397 | // Compare (RD,RS1,(RS2|IMM)); R-format or I-format |
| 398 | 398 | ||
| 399 | case TOK_ASM_slt: | 399 | case TOK_ASM_slt: |
| 400 | asm_emit_r(token, (0xC << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]); | 400 | asm_emit_r(S, token, (0xC << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]); |
| 401 | return; | 401 | return; |
| 402 | case TOK_ASM_slti: | 402 | case TOK_ASM_slti: |
| 403 | asm_emit_i(token, (0x4 << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]); | 403 | asm_emit_i(S, token, (0x4 << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]); |
| 404 | return; | 404 | return; |
| 405 | case TOK_ASM_sltu: | 405 | case TOK_ASM_sltu: |
| 406 | asm_emit_r(token, (0xC << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]); | 406 | asm_emit_r(S, token, (0xC << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]); |
| 407 | return; | 407 | return; |
| 408 | case TOK_ASM_sltiu: | 408 | case TOK_ASM_sltiu: |
| 409 | asm_emit_i(token, (0x4 << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]); | 409 | asm_emit_i(S, token, (0x4 << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]); |
| 410 | return; | 410 | return; |
| 411 | default: | 411 | default: |
| 412 | expect("known data processing instruction"); | 412 | expect(S, "known data processing instruction"); |
| 413 | } | 413 | } |
| 414 | } | 414 | } |
| 415 | 415 | ||
| 416 | /* caller: Add funct3 to opcode */ | 416 | /* caller: Add funct3 to opcode */ |
| 417 | static void asm_emit_s(int token, uint32_t opcode, const Operand* rs1, const Operand* rs2, const Operand* imm) | 417 | static void asm_emit_s(TCCState* S, int token, uint32_t opcode, const Operand* rs1, const Operand* rs2, const Operand* imm) |
| 418 | { | 418 | { |
| 419 | if (rs1->type != OP_REG) { | 419 | if (rs1->type != OP_REG) { |
| 420 | tcc_error("'%s': Expected first source operand that is a register", get_tok_str(token, NULL)); | 420 | tcc_error(S, "'%s': Expected first source operand that is a register", get_tok_str(S, token, NULL)); |
| 421 | return; | 421 | return; |
| 422 | } | 422 | } |
| 423 | if (rs2->type != OP_REG) { | 423 | if (rs2->type != OP_REG) { |
| 424 | tcc_error("'%s': Expected second source operand that is a register", get_tok_str(token, NULL)); | 424 | tcc_error(S, "'%s': Expected second source operand that is a register", get_tok_str(S, token, NULL)); |
| 425 | return; | 425 | return; |
| 426 | } | 426 | } |
| 427 | if (imm->type != OP_IM12S) { | 427 | if (imm->type != OP_IM12S) { |
| 428 | tcc_error("'%s': Expected third operand that is an immediate value between 0 and 0xfff", get_tok_str(token, NULL)); | 428 | tcc_error(S, "'%s': Expected third operand that is an immediate value between 0 and 0xfff", get_tok_str(S, token, NULL)); |
| 429 | return; | 429 | return; |
| 430 | } | 430 | } |
| 431 | { | 431 | { |
| @@ -438,112 +438,112 @@ static void asm_emit_s(int token, uint32_t opcode, const Operand* rs1, const Ope · 6 unmodified lines | |||
| 438 | 11...7 imm[4:0] | 438 | 11...7 imm[4:0] |
| 439 | 6...0 opcode | 439 | 6...0 opcode |
| 440 | opcode always fixed pos. */ | 440 | opcode always fixed pos. */ |
| 441 | gen_le32(opcode | ENCODE_RS1(rs1->reg) | ENCODE_RS2(rs2->reg) | ((v & 0x1F) << 7) | ((v >> 5) << 25)); | 441 | gen_le32(S, opcode | ENCODE_RS1(rs1->reg) | ENCODE_RS2(rs2->reg) | ((v & 0x1F) << 7) | ((v >> 5) << 25)); |
| 442 | } | 442 | } |
| 443 | } | 443 | } |
| 444 | 444 | ||
| 445 | static void asm_data_transfer_opcode(TCCState* s1, int token) | 445 | static void asm_data_transfer_opcode(TCCState* S, int token) |
| 446 | { | 446 | { |
| 447 | Operand ops[3]; | 447 | Operand ops[3]; |
| 448 | parse_operand(s1, &ops[0]); | 448 | parse_operand(S, &ops[0]); |
| 449 | if (ops[0].type != OP_REG) { | 449 | if (ops[0].type != OP_REG) { |
| 450 | expect("register"); | 450 | expect(S, "register"); |
| 451 | return; | 451 | return; |
| 452 | } | 452 | } |
| 453 | if (tok == ',') | 453 | if (S->tccpp_tok == ',') |
| 454 | next(); | 454 | next(S); |
| 455 | else | 455 | else |
| 456 | expect("','"); | 456 | expect(S, "','"); |
| 457 | parse_operand(s1, &ops[1]); | 457 | parse_operand(S, &ops[1]); |
| 458 | if (ops[1].type != OP_REG) { | 458 | if (ops[1].type != OP_REG) { |
| 459 | expect("register"); | 459 | expect(S, "register"); |
| 460 | return; | 460 | return; |
| 461 | } | 461 | } |
| 462 | if (tok == ',') | 462 | if (S->tccpp_tok == ',') |
| 463 | next(); | 463 | next(S); |
| 464 | else | 464 | else |
| 465 | expect("','"); | 465 | expect(S, "','"); |
| 466 | parse_operand(s1, &ops[2]); | 466 | parse_operand(S, &ops[2]); |
| 467 | 467 | ||
| 468 | switch (token) { | 468 | switch (token) { |
| 469 | // Loads (RD,RS1,I); I-format | 469 | // Loads (RD,RS1,I); I-format |
| 470 | 470 | ||
| 471 | case TOK_ASM_lb: | 471 | case TOK_ASM_lb: |
| 472 | asm_emit_i(token, (0x0 << 2) | 3, &ops[0], &ops[1], &ops[2]); | 472 | asm_emit_i(S, token, (0x0 << 2) | 3, &ops[0], &ops[1], &ops[2]); |
| 473 | return; | 473 | return; |
| 474 | case TOK_ASM_lh: | 474 | case TOK_ASM_lh: |
| 475 | asm_emit_i(token, (0x0 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]); | 475 | asm_emit_i(S, token, (0x0 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]); |
| 476 | return; | 476 | return; |
| 477 | case TOK_ASM_lw: | 477 | case TOK_ASM_lw: |
| 478 | asm_emit_i(token, (0x0 << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]); | 478 | asm_emit_i(S, token, (0x0 << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]); |
| 479 | return; | 479 | return; |
| 480 | case TOK_ASM_lbu: | 480 | case TOK_ASM_lbu: |
| 481 | asm_emit_i(token, (0x0 << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]); | 481 | asm_emit_i(S, token, (0x0 << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]); |
| 482 | return; | 482 | return; |
| 483 | case TOK_ASM_lhu: | 483 | case TOK_ASM_lhu: |
| 484 | asm_emit_i(token, (0x0 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]); | 484 | asm_emit_i(S, token, (0x0 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]); |
| 485 | return; | 485 | return; |
| 486 | // 64 bit | 486 | // 64 bit |
| 487 | case TOK_ASM_ld: | 487 | case TOK_ASM_ld: |
| 488 | asm_emit_i(token, (0x0 << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]); | 488 | asm_emit_i(S, token, (0x0 << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]); |
| 489 | return; | 489 | return; |
| 490 | case TOK_ASM_lwu: | 490 | case TOK_ASM_lwu: |
| 491 | asm_emit_i(token, (0x0 << 2) | 3 | (6 << 12), &ops[0], &ops[1], &ops[2]); | 491 | asm_emit_i(S, token, (0x0 << 2) | 3 | (6 << 12), &ops[0], &ops[1], &ops[2]); |
| 492 | return; | 492 | return; |
| 493 | 493 | ||
| 494 | // Stores (RS1,RS2,I); S-format | 494 | // Stores (RS1,RS2,I); S-format |
| 495 | 495 | ||
| 496 | case TOK_ASM_sb: | 496 | case TOK_ASM_sb: |
| 497 | asm_emit_s(token, (0x8 << 2) | 3 | (0 << 12), &ops[0], &ops[1], &ops[2]); | 497 | asm_emit_s(S, token, (0x8 << 2) | 3 | (0 << 12), &ops[0], &ops[1], &ops[2]); |
| 498 | return; | 498 | return; |
| 499 | case TOK_ASM_sh: | 499 | case TOK_ASM_sh: |
| 500 | asm_emit_s(token, (0x8 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]); | 500 | asm_emit_s(S, token, (0x8 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]); |
| 501 | return; | 501 | return; |
| 502 | case TOK_ASM_sw: | 502 | case TOK_ASM_sw: |
| 503 | asm_emit_s(token, (0x8 << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]); | 503 | asm_emit_s(S, token, (0x8 << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]); |
| 504 | return; | 504 | return; |
| 505 | case TOK_ASM_sd: | 505 | case TOK_ASM_sd: |
| 506 | asm_emit_s(token, (0x8 << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]); | 506 | asm_emit_s(S, token, (0x8 << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]); |
| 507 | return; | 507 | return; |
| 508 | 508 | ||
| 509 | default: | 509 | default: |
| 510 | expect("known data transfer instruction"); | 510 | expect(S, "known data transfer instruction"); |
| 511 | } | 511 | } |
| 512 | } | 512 | } |
| 513 | 513 | ||
| 514 | static void asm_branch_opcode(TCCState* s1, int token) | 514 | static void asm_branch_opcode(TCCState* S, int token) |
| 515 | { | 515 | { |
| 516 | // Branch (RS1,RS2,IMM); SB-format | 516 | // Branch (RS1,RS2,IMM); SB-format |
| 517 | uint32_t opcode = (0x18 << 2) | 3; | 517 | uint32_t opcode = (0x18 << 2) | 3; |
| 518 | uint32_t offset = 0; | 518 | uint32_t offset = 0; |
| 519 | Operand ops[3]; | 519 | Operand ops[3]; |
| 520 | parse_operand(s1, &ops[0]); | 520 | parse_operand(S, &ops[0]); |
| 521 | if (ops[0].type != OP_REG) { | 521 | if (ops[0].type != OP_REG) { |
| 522 | expect("register"); | 522 | expect(S, "register"); |
| 523 | return; | 523 | return; |
| 524 | } | 524 | } |
| 525 | if (tok == ',') | 525 | if (S->tccpp_tok == ',') |
| 526 | next(); | 526 | next(S); |
| 527 | else | 527 | else |
| 528 | expect("','"); | 528 | expect(S, "','"); |
| 529 | parse_operand(s1, &ops[1]); | 529 | parse_operand(S, &ops[1]); |
| 530 | if (ops[1].type != OP_REG) { | 530 | if (ops[1].type != OP_REG) { |
| 531 | expect("register"); | 531 | expect(S, "register"); |
| 532 | return; | 532 | return; |
| 533 | } | 533 | } |
| 534 | if (tok == ',') | 534 | if (S->tccpp_tok == ',') |
| 535 | next(); | 535 | next(S); |
| 536 | else | 536 | else |
| 537 | expect("','"); | 537 | expect(S, "','"); |
| 538 | parse_operand(s1, &ops[2]); | 538 | parse_operand(S, &ops[2]); |
| 539 | 539 | ||
| 540 | if (ops[2].type != OP_IM12S) { | 540 | if (ops[2].type != OP_IM12S) { |
| 541 | tcc_error("'%s': Expected third operand that is an immediate value between 0 and 0xfff", get_tok_str(token, NULL)); | 541 | tcc_error(S, "'%s': Expected third operand that is an immediate value between 0 and 0xfff", get_tok_str(S, token, NULL)); |
| 542 | return; | 542 | return; |
| 543 | } | 543 | } |
| 544 | offset = ops[2].e.v; | 544 | offset = ops[2].e.v; |
| 545 | if (offset & 1) { | 545 | if (offset & 1) { |
| 546 | tcc_error("'%s': Expected third operand that is an even immediate value", get_tok_str(token, NULL)); | 546 | tcc_error(S, "'%s': Expected third operand that is an even immediate value", get_tok_str(S, token, NULL)); |
| 547 | return; | 547 | return; |
| 548 | } | 548 | } |
| 549 | 549 | ||
| @@ -567,12 +567,12 @@ static void asm_branch_opcode(TCCState* s1, int token) · 17 unmodified lines | |||
| 567 | opcode |= 7 << 12; | 567 | opcode |= 7 << 12; |
| 568 | break; | 568 | break; |
| 569 | default: | 569 | default: |
| 570 | expect("known branch instruction"); | 570 | expect(S, "known branch instruction"); |
| 571 | } | 571 | } |
| 572 | asm_emit_opcode(opcode | ENCODE_RS1(ops[0].reg) | ENCODE_RS2(ops[1].reg) | (((offset >> 1) & 0xF) << 8) | (((offset >> 5) & 0x1f) << 25) | (((offset >> 11) & 1) << 7) | (((offset >> 12) & 1) << 31)); | 572 | asm_emit_opcode(S, opcode | ENCODE_RS1(ops[0].reg) | ENCODE_RS2(ops[1].reg) | (((offset >> 1) & 0xF) << 8) | (((offset >> 5) & 0x1f) << 25) | (((offset >> 11) & 1) << 7) | (((offset >> 12) & 1) << 31)); |
| 573 | } | 573 | } |
| 574 | 574 | ||
| 575 | ST_FUNC void asm_opcode(TCCState *s1, int token) | 575 | ST_FUNC void asm_opcode(TCCState *S, int token) |
| 576 | { | 576 | { |
| 577 | switch (token) { | 577 | switch (token) { |
| 578 | case TOK_ASM_fence: | 578 | case TOK_ASM_fence: |
| @@ -585,7 +585,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 6 unmodified lines | |||
| 585 | case TOK_ASM_mrth: | 585 | case TOK_ASM_mrth: |
| 586 | case TOK_ASM_hrts: | 586 | case TOK_ASM_hrts: |
| 587 | case TOK_ASM_wfi: | 587 | case TOK_ASM_wfi: |
| 588 | asm_nullary_opcode(s1, token); | 588 | asm_nullary_opcode(S, token); |
| 589 | return; | 589 | return; |
| 590 | 590 | ||
| 591 | case TOK_ASM_rdcycle: | 591 | case TOK_ASM_rdcycle: |
| @@ -594,12 +594,12 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 2 unmodified lines | |||
| 594 | case TOK_ASM_rdtimeh: | 594 | case TOK_ASM_rdtimeh: |
| 595 | case TOK_ASM_rdinstret: | 595 | case TOK_ASM_rdinstret: |
| 596 | case TOK_ASM_rdinstreth: | 596 | case TOK_ASM_rdinstreth: |
| 597 | asm_unary_opcode(s1, token); | 597 | asm_unary_opcode(S, token); |
| 598 | return; | 598 | return; |
| 599 | 599 | ||
| 600 | case TOK_ASM_lui: | 600 | case TOK_ASM_lui: |
| 601 | case TOK_ASM_auipc: | 601 | case TOK_ASM_auipc: |
| 602 | asm_binary_opcode(s1, token); | 602 | asm_binary_opcode(S, token); |
| 603 | return; | 603 | return; |
| 604 | 604 | ||
| 605 | case TOK_ASM_sll: | 605 | case TOK_ASM_sll: |
| @@ -620,7 +620,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 14 unmodified lines | |||
| 620 | case TOK_ASM_srad: | 620 | case TOK_ASM_srad: |
| 621 | case TOK_ASM_sraiw: | 621 | case TOK_ASM_sraiw: |
| 622 | case TOK_ASM_sraid: | 622 | case TOK_ASM_sraid: |
| 623 | asm_shift_opcode(s1, token); | 623 | asm_shift_opcode(S, token); |
| 624 | return; | 624 | return; |
| 625 | 625 | ||
| 626 | case TOK_ASM_add: | 626 | case TOK_ASM_add: |
| @@ -642,7 +642,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 15 unmodified lines | |||
| 642 | case TOK_ASM_slti: | 642 | case TOK_ASM_slti: |
| 643 | case TOK_ASM_sltu: | 643 | case TOK_ASM_sltu: |
| 644 | case TOK_ASM_sltiu: | 644 | case TOK_ASM_sltiu: |
| 645 | asm_data_processing_opcode(s1, token); | 645 | asm_data_processing_opcode(S, token); |
| 646 | 646 | ||
| 647 | case TOK_ASM_lb: | 647 | case TOK_ASM_lb: |
| 648 | case TOK_ASM_lh: | 648 | case TOK_ASM_lh: |
| @@ -655,7 +655,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 6 unmodified lines | |||
| 655 | case TOK_ASM_sh: | 655 | case TOK_ASM_sh: |
| 656 | case TOK_ASM_sw: | 656 | case TOK_ASM_sw: |
| 657 | case TOK_ASM_sd: | 657 | case TOK_ASM_sd: |
| 658 | asm_data_transfer_opcode(s1, token); | 658 | asm_data_transfer_opcode(S, token); |
| 659 | return; | 659 | return; |
| 660 | 660 | ||
| 661 | case TOK_ASM_beq: | 661 | case TOK_ASM_beq: |
| @@ -664,35 +664,35 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 2 unmodified lines | |||
| 664 | case TOK_ASM_bge: | 664 | case TOK_ASM_bge: |
| 665 | case TOK_ASM_bltu: | 665 | case TOK_ASM_bltu: |
| 666 | case TOK_ASM_bgeu: | 666 | case TOK_ASM_bgeu: |
| 667 | asm_branch_opcode(s1, token); | 667 | asm_branch_opcode(S, token); |
| 668 | return; | 668 | return; |
| 669 | 669 | ||
| 670 | default: | 670 | default: |
| 671 | expect("known instruction"); | 671 | expect(S, "known instruction"); |
| 672 | } | 672 | } |
| 673 | } | 673 | } |
| 674 | 674 | ||
| 675 | ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier) | 675 | ST_FUNC void subst_asm_operand(TCCState *S, CString *add_str, SValue *sv, int modifier) |
| 676 | { | 676 | { |
| 677 | tcc_error("RISCV64 asm not implemented."); | 677 | tcc_error(S, "RISCV64 asm not implemented."); |
| 678 | } | 678 | } |
| 679 | 679 | ||
| 680 | /* generate prolog and epilog code for asm statement */ | 680 | /* generate prolog and epilog code for asm statement */ |
| 681 | ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, | 681 | ST_FUNC void asm_gen_code(TCCState *S, ASMOperand *operands, int nb_operands, |
| 682 | int nb_outputs, int is_output, | 682 | int nb_outputs, int is_output, |
| 683 | uint8_t *clobber_regs, | 683 | uint8_t *clobber_regs, |
| 684 | int out_reg) | 684 | int out_reg) |
| 685 | { | 685 | { |
| 686 | } | 686 | } |
| 687 | 687 | ||
| 688 | ST_FUNC void asm_compute_constraints(ASMOperand *operands, | 688 | ST_FUNC void asm_compute_constraints(TCCState *S, ASMOperand *operands, |
| 689 | int nb_operands, int nb_outputs, | 689 | int nb_operands, int nb_outputs, |
| 690 | const uint8_t *clobber_regs, | 690 | const uint8_t *clobber_regs, |
| 691 | int *pout_reg) | 691 | int *pout_reg) |
| 692 | { | 692 | { |
| 693 | } | 693 | } |
| 694 | 694 | ||
| 695 | ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str) | 695 | ST_FUNC void asm_clobber(TCCState *S, uint8_t *clobber_regs, const char *str) |
| 696 | { | 696 | { |
| 697 | int reg; | 697 | int reg; |
| 698 | TokenSym *ts; | 698 | TokenSym *ts; |
| @@ -701,15 +701,15 @@ ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str) · 2 unmodified lines | |||
| 701 | !strcmp(str, "cc") || | 701 | !strcmp(str, "cc") || |
| 702 | !strcmp(str, "flags")) | 702 | !strcmp(str, "flags")) |
| 703 | return; | 703 | return; |
| 704 | ts = tok_alloc(str, strlen(str)); | 704 | ts = tok_alloc(S, str, strlen(str)); |
| 705 | reg = asm_parse_regvar(ts->tok); | 705 | reg = asm_parse_regvar(S, ts->tok); |
| 706 | if (reg == -1) { | 706 | if (reg == -1) { |
| 707 | tcc_error("invalid clobber register '%s'", str); | 707 | tcc_error(S, "invalid clobber register '%s'", str); |
| 708 | } | 708 | } |
| 709 | clobber_regs[reg] = 1; | 709 | clobber_regs[reg] = 1; |
| 710 | } | 710 | } |
| 711 | 711 | ||
| 712 | ST_FUNC int asm_parse_regvar (int t) | 712 | ST_FUNC int asm_parse_regvar (TCCState* S, int t) |
| 713 | { | 713 | { |
| 714 | if (t >= TOK_ASM_x0 && t <= TOK_ASM_pc) { /* register name */ | 714 | if (t >= TOK_ASM_x0 && t <= TOK_ASM_pc) { /* register name */ |
| 715 | switch (t) { | 715 | switch (t) { |
| @@ -74,12 +74,6 @@ ST_DATA const int reg_classes[NB_REGS] = { · 73 unmodified lines | |||
| 74 | 1 << TREG_SP | 74 | 1 << TREG_SP |
| 75 | }; | 75 | }; |
| 76 | 76 | ||
| 77 | #if defined(CONFIG_TCC_BCHECK) | ||
| 78 | static addr_t func_bound_offset; | ||
| 79 | static unsigned long func_bound_ind; | ||
| 80 | ST_DATA int func_bound_add_epilog; | ||
| 81 | #endif | ||
| 82 | |||
| 83 | static int ireg(int r) | 77 | static int ireg(int r) |
| 84 | { | 78 | { |
| 85 | if (r == TREG_RA) | 79 | if (r == TREG_RA) |
| @@ -106,46 +100,46 @@ static int is_freg(int r) · 20 unmodified lines | |||
| 106 | return r >= 8 && r < 16; | 100 | return r >= 8 && r < 16; |
| 107 | } | 101 | } |
| 108 | 102 | ||
| 109 | ST_FUNC void o(unsigned int c) | 103 | ST_FUNC void o(TCCState* S, unsigned int c) |
| 110 | { | 104 | { |
| 111 | int ind1 = ind + 4; | 105 | int ind1 = S->tccgen_ind + 4; |
| 112 | if (nocode_wanted) | 106 | if (S->tccgen_nocode_wanted) |
| 113 | return; | 107 | return; |
| 114 | if (ind1 > cur_text_section->data_allocated) | 108 | if (ind1 > cur_text_section->data_allocated) |
| 115 | section_realloc(cur_text_section, ind1); | 109 | section_realloc(S, cur_text_section, ind1); |
| 116 | write32le(cur_text_section->data + ind, c); | 110 | write32le(cur_text_section->data + S->tccgen_ind, c); |
| 117 | ind = ind1; | 111 | S->tccgen_ind = ind1; |
| 118 | } | 112 | } |
| 119 | 113 | ||
| 120 | static void EIu(uint32_t opcode, uint32_t func3, | 114 | static void EIu(TCCState* S, uint32_t opcode, uint32_t func3, |
| 121 | uint32_t rd, uint32_t rs1, uint32_t imm) | 115 | uint32_t rd, uint32_t rs1, uint32_t imm) |
| 122 | { | 116 | { |
| 123 | o(opcode | (func3 << 12) | (rd << 7) | (rs1 << 15) | (imm << 20)); | 117 | o(S, opcode | (func3 << 12) | (rd << 7) | (rs1 << 15) | (imm << 20)); |
| 124 | } | 118 | } |
| 125 | 119 | ||
| 126 | static void ER(uint32_t opcode, uint32_t func3, | 120 | static void ER(TCCState* S, uint32_t opcode, uint32_t func3, |
| 127 | uint32_t rd, uint32_t rs1, uint32_t rs2, uint32_t func7) | 121 | uint32_t rd, uint32_t rs1, uint32_t rs2, uint32_t func7) |
| 128 | { | 122 | { |
| 129 | o(opcode | func3 << 12 | rd << 7 | rs1 << 15 | rs2 << 20 | func7 << 25); | 123 | o(S, opcode | func3 << 12 | rd << 7 | rs1 << 15 | rs2 << 20 | func7 << 25); |
| 130 | } | 124 | } |
| 131 | 125 | ||
| 132 | static void EI(uint32_t opcode, uint32_t func3, | 126 | static void EI(TCCState* S, uint32_t opcode, uint32_t func3, |
| 133 | uint32_t rd, uint32_t rs1, uint32_t imm) | 127 | uint32_t rd, uint32_t rs1, uint32_t imm) |
| 134 | { | 128 | { |
| 135 | assert(! ((imm + (1 << 11)) >> 12)); | 129 | assert(! ((imm + (1 << 11)) >> 12)); |
| 136 | EIu(opcode, func3, rd, rs1, imm); | 130 | EIu(S, opcode, func3, rd, rs1, imm); |
| 137 | } | 131 | } |
| 138 | 132 | ||
| 139 | static void ES(uint32_t opcode, uint32_t func3, | 133 | static void ES(TCCState* S, uint32_t opcode, uint32_t func3, |
| 140 | uint32_t rs1, uint32_t rs2, uint32_t imm) | 134 | uint32_t rs1, uint32_t rs2, uint32_t imm) |
| 141 | { | 135 | { |
| 142 | assert(! ((imm + (1 << 11)) >> 12)); | 136 | assert(! ((imm + (1 << 11)) >> 12)); |
| 143 | o(opcode | (func3 << 12) | ((imm & 0x1f) << 7) | (rs1 << 15) | 137 | o(S, opcode | (func3 << 12) | ((imm & 0x1f) << 7) | (rs1 << 15) |
| 144 | | (rs2 << 20) | ((imm >> 5) << 25)); | 138 | | (rs2 << 20) | ((imm >> 5) << 25)); |
| 145 | } | 139 | } |
| 146 | 140 | ||
| 147 | // Patch all branches in list pointed to by t to branch to a: | 141 | // Patch all branches in list pointed to by t to branch to a: |
| 148 | ST_FUNC void gsym_addr(int t_, int a_) | 142 | ST_FUNC void gsym_addr(TCCState* S, int t_, int a_) |
| 149 | { | 143 | { |
| 150 | uint32_t t = t_; | 144 | uint32_t t = t_; |
| 151 | uint32_t a = a_; | 145 | uint32_t a = a_; |
| @@ -154,7 +148,7 @@ ST_FUNC void gsym_addr(int t_, int a_) · 2 unmodified lines | |||
| 154 | uint32_t next = read32le(ptr); | 148 | uint32_t next = read32le(ptr); |
| 155 | uint32_t r = a - t, imm; | 149 | uint32_t r = a - t, imm; |
| 156 | if ((r + (1 << 21)) & ~((1U << 22) - 2)) | 150 | if ((r + (1 << 21)) & ~((1U << 22) - 2)) |
| 157 | tcc_error("out-of-range branch chain"); | 151 | tcc_error(S, "out-of-range branch chain"); |
| 158 | imm = (((r >> 12) & 0xff) << 12) | 152 | imm = (((r >> 12) & 0xff) << 12) |
| 159 | | (((r >> 11) & 1) << 20) | 153 | | (((r >> 11) & 1) << 20) |
| 160 | | (((r >> 1) & 0x3ff) << 21) | 154 | | (((r >> 1) & 0x3ff) << 21) |
| @@ -164,7 +158,7 @@ ST_FUNC void gsym_addr(int t_, int a_) · 3 unmodified lines | |||
| 164 | } | 158 | } |
| 165 | } | 159 | } |
| 166 | 160 | ||
| 167 | static int load_symofs(int r, SValue *sv, int forstore) | 161 | static int load_symofs(TCCState* S, int r, SValue *sv, int forstore) |
| 168 | { | 162 | { |
| 169 | int rr, doload = 0; | 163 | int rr, doload = 0; |
| 170 | int fc = sv->c.i, v = sv->r & VT_VALMASK; | 164 | int fc = sv->c.i, v = sv->r & VT_VALMASK; |
| @@ -172,56 +166,56 @@ static int load_symofs(int r, SValue *sv, int forstore) · 1 unmodified line | |||
| 172 | Sym label = {0}; | 166 | Sym label = {0}; |
| 173 | assert(v == VT_CONST); | 167 | assert(v == VT_CONST); |
| 174 | if (sv->sym->type.t & VT_STATIC) { // XXX do this per linker relax | 168 | if (sv->sym->type.t & VT_STATIC) { // XXX do this per linker relax |
| 175 | greloca(cur_text_section, sv->sym, ind, | 169 | greloca(S, cur_text_section, sv->sym, S->tccgen_ind, |
| 176 | R_RISCV_PCREL_HI20, sv->c.i); | 170 | R_RISCV_PCREL_HI20, sv->c.i); |
| 177 | sv->c.i = 0; | 171 | sv->c.i = 0; |
| 178 | } else { | 172 | } else { |
| 179 | if (((unsigned)fc + (1 << 11)) >> 12) | 173 | if (((unsigned)fc + (1 << 11)) >> 12) |
| 180 | tcc_error("unimp: large addend for global address (0x%lx)", (long)sv->c.i); | 174 | tcc_error(S, "unimp: large addend for global address (0x%lx)", (long)sv->c.i); |
| 181 | greloca(cur_text_section, sv->sym, ind, | 175 | greloca(S, cur_text_section, sv->sym, S->tccgen_ind, |
| 182 | R_RISCV_GOT_HI20, 0); | 176 | R_RISCV_GOT_HI20, 0); |
| 183 | doload = 1; | 177 | doload = 1; |
| 184 | } | 178 | } |
| 185 | label.type.t = VT_VOID | VT_STATIC; | 179 | label.type.t = VT_VOID | VT_STATIC; |
| 186 | put_extern_sym(&label, cur_text_section, ind, 0); | 180 | put_extern_sym(S, &label, cur_text_section, S->tccgen_ind, 0); |
| 187 | rr = is_ireg(r) ? ireg(r) : 5; | 181 | rr = is_ireg(r) ? ireg(r) : 5; |
| 188 | o(0x17 | (rr << 7)); // auipc RR, 0 %pcrel_hi(sym)+addend | 182 | o(S, 0x17 | (rr << 7)); // auipc RR, 0 %pcrel_hi(sym)+addend |
| 189 | greloca(cur_text_section, &label, ind, | 183 | greloca(S, cur_text_section, &label, S->tccgen_ind, |
| 190 | doload || !forstore | 184 | doload || !forstore |
| 191 | ? R_RISCV_PCREL_LO12_I : R_RISCV_PCREL_LO12_S, 0); | 185 | ? R_RISCV_PCREL_LO12_I : R_RISCV_PCREL_LO12_S, 0); |
| 192 | if (doload) { | 186 | if (doload) { |
| 193 | EI(0x03, 3, rr, rr, 0); // ld RR, 0(RR) | 187 | EI(S, 0x03, 3, rr, rr, 0); // ld RR, 0(RR) |
| 194 | } | 188 | } |
| 195 | } else if (v == VT_LOCAL || v == VT_LLOCAL) { | 189 | } else if (v == VT_LOCAL || v == VT_LLOCAL) { |
| 196 | rr = 8; // s0 | 190 | rr = 8; // s0 |
| 197 | if (fc != sv->c.i) | 191 | if (fc != sv->c.i) |
| 198 | tcc_error("unimp: store(giant local off) (0x%lx)", (long)sv->c.i); | 192 | tcc_error(S, "unimp: store(giant local off) (0x%lx)", (long)sv->c.i); |
| 199 | if (((unsigned)fc + (1 << 11)) >> 12) { | 193 | if (((unsigned)fc + (1 << 11)) >> 12) { |
| 200 | rr = is_ireg(r) ? ireg(r) : 5; // t0 | 194 | rr = is_ireg(r) ? ireg(r) : 5; // t0 |
| 201 | o(0x37 | (rr << 7) | ((0x800 + fc) & 0xfffff000)); //lui RR, upper(fc) | 195 | o(S, 0x37 | (rr << 7) | ((0x800 + fc) & 0xfffff000)); //lui RR, upper(fc) |
| 202 | ER(0x33, 0, rr, rr, 8, 0); // add RR, RR, s0 | 196 | ER(S, 0x33, 0, rr, rr, 8, 0); // add RR, RR, s0 |
| 203 | sv->c.i = fc << 20 >> 20; | 197 | sv->c.i = fc << 20 >> 20; |
| 204 | } | 198 | } |
| 205 | } else | 199 | } else |
| 206 | tcc_error("uhh"); | 200 | tcc_error(S, "uhh"); |
| 207 | return rr; | 201 | return rr; |
| 208 | } | 202 | } |
| 209 | 203 | ||
| 210 | static void load_large_constant(int rr, int fc, uint32_t pi) | 204 | static void load_large_constant(TCCState* S, int rr, int fc, uint32_t pi) |
| 211 | { | 205 | { |
| 212 | if (fc < 0) | 206 | if (fc < 0) |
| 213 | pi++; | 207 | pi++; |
| 214 | o(0x37 | (rr << 7) | (((pi + 0x800) & 0xfffff000))); // lui RR, up(up(fc)) | 208 | o(S, 0x37 | (rr << 7) | (((pi + 0x800) & 0xfffff000))); // lui RR, up(up(fc)) |
| 215 | EI(0x13, 0, rr, rr, (int)pi << 20 >> 20); // addi RR, RR, lo(up(fc)) | 209 | EI(S, 0x13, 0, rr, rr, (int)pi << 20 >> 20); // addi RR, RR, lo(up(fc)) |
| 216 | EI(0x13, 1, rr, rr, 12); // slli RR, RR, 12 | 210 | EI(S, 0x13, 1, rr, rr, 12); // slli RR, RR, 12 |
| 217 | EI(0x13, 0, rr, rr, (fc + (1 << 19)) >> 20); // addi RR, RR, up(lo(fc)) | 211 | EI(S, 0x13, 0, rr, rr, (fc + (1 << 19)) >> 20); // addi RR, RR, up(lo(fc)) |
| 218 | EI(0x13, 1, rr, rr, 12); // slli RR, RR, 12 | 212 | EI(S, 0x13, 1, rr, rr, 12); // slli RR, RR, 12 |
| 219 | fc = fc << 12 >> 12; | 213 | fc = fc << 12 >> 12; |
| 220 | EI(0x13, 0, rr, rr, fc >> 8); // addi RR, RR, lo1(lo(fc)) | 214 | EI(S, 0x13, 0, rr, rr, fc >> 8); // addi RR, RR, lo1(lo(fc)) |
| 221 | EI(0x13, 1, rr, rr, 8); // slli RR, RR, 8 | 215 | EI(S, 0x13, 1, rr, rr, 8); // slli RR, RR, 8 |
| 222 | } | 216 | } |
| 223 | 217 | ||
| 224 | ST_FUNC void load(int r, SValue *sv) | 218 | ST_FUNC void load(TCCState* S, int r, SValue *sv) |
| 225 | { | 219 | { |
| 226 | int fr = sv->r; | 220 | int fr = sv->r; |
| 227 | int v = fr & VT_VALMASK; | 221 | int v = fr & VT_VALMASK; |
| @@ -239,49 +233,49 @@ ST_FUNC void load(int r, SValue *sv) · 11 unmodified lines | |||
| 239 | if (size < 4 && !is_float(sv->type.t) && (sv->type.t & VT_UNSIGNED)) | 233 | if (size < 4 && !is_float(sv->type.t) && (sv->type.t & VT_UNSIGNED)) |
| 240 | func3 |= 4; | 234 | func3 |= 4; |
| 241 | if (v == VT_LOCAL || (fr & VT_SYM)) { | 235 | if (v == VT_LOCAL || (fr & VT_SYM)) { |
| 242 | br = load_symofs(r, sv, 0); | 236 | br = load_symofs(S, r, sv, 0); |
| 243 | fc = sv->c.i; | 237 | fc = sv->c.i; |
| 244 | } else if (v < VT_CONST) { | 238 | } else if (v < VT_CONST) { |
| 245 | br = ireg(v); | 239 | br = ireg(v); |
| 246 | /*if (((unsigned)fc + (1 << 11)) >> 12) | 240 | /*if (((unsigned)fc + (1 << 11)) >> 12) |
| 247 | tcc_error("unimp: load(large addend) (0x%x)", fc);*/ | 241 | tcc_error(S, "unimp: load(large addend) (0x%x)", fc);*/ |
| 248 | fc = 0; // XXX store ofs in LVAL(reg) | 242 | fc = 0; // XXX store ofs in LVAL(reg) |
| 249 | } else if (v == VT_LLOCAL) { | 243 | } else if (v == VT_LLOCAL) { |
| 250 | br = load_symofs(r, sv, 0); | 244 | br = load_symofs(S, r, sv, 0); |
| 251 | fc = sv->c.i; | 245 | fc = sv->c.i; |
| 252 | EI(0x03, 3, rr, br, fc); // ld RR, fc(BR) | 246 | EI(S, 0x03, 3, rr, br, fc); // ld RR, fc(BR) |
| 253 | br = rr; | 247 | br = rr; |
| 254 | fc = 0; | 248 | fc = 0; |
| 255 | } else if (v == VT_CONST) { | 249 | } else if (v == VT_CONST) { |
| 256 | int64_t si = sv->c.i; | 250 | int64_t si = sv->c.i; |
| 257 | si >>= 32; | 251 | si >>= 32; |
| 258 | if (si != 0) { | 252 | if (si != 0) { |
| 259 | load_large_constant(rr, fc, si); | 253 | load_large_constant(S, rr, fc, si); |
| 260 | fc &= 0xff; | 254 | fc &= 0xff; |
| 261 | } else { | 255 | } else { |
| 262 | o(0x37 | (rr << 7) | ((0x800 + fc) & 0xfffff000)); //lui RR, upper(fc) | 256 | o(S, 0x37 | (rr << 7) | ((0x800 + fc) & 0xfffff000)); //lui RR, upper(fc) |
| 263 | fc = fc << 20 >> 20; | 257 | fc = fc << 20 >> 20; |
| 264 | } | 258 | } |
| 265 | br = rr; | 259 | br = rr; |
| 266 | } else { | 260 | } else { |
| 267 | tcc_error("unimp: load(non-local lval)"); | 261 | tcc_error(S, "unimp: load(non-local lval)"); |
| 268 | } | 262 | } |
| 269 | EI(opcode, func3, rr, br, fc); // l[bhwd][u] / fl[wd] RR, fc(BR) | 263 | EI(S, opcode, func3, rr, br, fc); // l[bhwd][u] / fl[wd] RR, fc(BR) |
| 270 | } else if (v == VT_CONST) { | 264 | } else if (v == VT_CONST) { |
| 271 | int rb = 0, do32bit = 8, zext = 0; | 265 | int rb = 0, do32bit = 8, zext = 0; |
| 272 | assert((!is_float(sv->type.t) && is_ireg(r)) || bt == VT_LDOUBLE); | 266 | assert((!is_float(sv->type.t) && is_ireg(r)) || bt == VT_LDOUBLE); |
| 273 | if (fr & VT_SYM) { | 267 | if (fr & VT_SYM) { |
| 274 | rb = load_symofs(r, sv, 0); | 268 | rb = load_symofs(S, r, sv, 0); |
| 275 | fc = sv->c.i; | 269 | fc = sv->c.i; |
| 276 | do32bit = 0; | 270 | do32bit = 0; |
| 277 | } | 271 | } |
| 278 | if (is_float(sv->type.t) && bt != VT_LDOUBLE) | 272 | if (is_float(sv->type.t) && bt != VT_LDOUBLE) |
| 279 | tcc_error("unimp: load(float)"); | 273 | tcc_error(S, "unimp: load(float)"); |
| 280 | if (fc != sv->c.i) { | 274 | if (fc != sv->c.i) { |
| 281 | int64_t si = sv->c.i; | 275 | int64_t si = sv->c.i; |
| 282 | si >>= 32; | 276 | si >>= 32; |
| 283 | if (si != 0) { | 277 | if (si != 0) { |
| 284 | load_large_constant(rr, fc, si); | 278 | load_large_constant(S, rr, fc, si); |
| 285 | fc &= 0xff; | 279 | fc &= 0xff; |
| 286 | rb = rr; | 280 | rb = rr; |
| 287 | do32bit = 0; | 281 | do32bit = 0; |
| @@ -292,37 +286,37 @@ ST_FUNC void load(int r, SValue *sv) · 4 unmodified lines | |||
| 292 | } | 286 | } |
| 293 | } | 287 | } |
| 294 | if (((unsigned)fc + (1 << 11)) >> 12) | 288 | if (((unsigned)fc + (1 << 11)) >> 12) |
| 295 | o(0x37 | (rr << 7) | ((0x800 + fc) & 0xfffff000)), rb = rr; //lui RR, upper(fc) | 289 | o(S, 0x37 | (rr << 7) | ((0x800 + fc) & 0xfffff000)), rb = rr; //lui RR, upper(fc) |
| 296 | if (fc || (rr != rb) || do32bit || (fr & VT_SYM)) | 290 | if (fc || (rr != rb) || do32bit || (fr & VT_SYM)) |
| 297 | EI(0x13 | do32bit, 0, rr, rb, fc << 20 >> 20); // addi[w] R, x0|R, FC | 291 | EI(S, 0x13 | do32bit, 0, rr, rb, fc << 20 >> 20); // addi[w] R, x0|R, FC |
| 298 | if (zext) { | 292 | if (zext) { |
| 299 | EI(0x13, 1, rr, rr, 32); // slli RR, RR, 32 | 293 | EI(S, 0x13, 1, rr, rr, 32); // slli RR, RR, 32 |
| 300 | EI(0x13, 5, rr, rr, 32); // srli RR, RR, 32 | 294 | EI(S, 0x13, 5, rr, rr, 32); // srli RR, RR, 32 |
| 301 | } | 295 | } |
| 302 | } else if (v == VT_LOCAL) { | 296 | } else if (v == VT_LOCAL) { |
| 303 | int br = load_symofs(r, sv, 0); | 297 | int br = load_symofs(S, r, sv, 0); |
| 304 | assert(is_ireg(r)); | 298 | assert(is_ireg(r)); |
| 305 | fc = sv->c.i; | 299 | fc = sv->c.i; |
| 306 | EI(0x13, 0, rr, br, fc); // addi R, s0, FC | 300 | EI(S, 0x13, 0, rr, br, fc); // addi R, s0, FC |
| 307 | } else if (v < VT_CONST) { /* reg-reg */ | 301 | } else if (v < VT_CONST) { /* reg-reg */ |
| 308 | //assert(!fc); XXX support offseted regs | 302 | //assert(!fc); XXX support offseted regs |
| 309 | if (is_freg(r) && is_freg(v)) | 303 | if (is_freg(r) && is_freg(v)) |
| 310 | ER(0x53, 0, rr, freg(v), freg(v), bt == VT_DOUBLE ? 0x11 : 0x10); //fsgnj.[sd] RR, V, V == fmv.[sd] RR, V | 304 | ER(S, 0x53, 0, rr, freg(v), freg(v), bt == VT_DOUBLE ? 0x11 : 0x10); //fsgnj.[sd] RR, V, V == fmv.[sd] RR, V |
| 311 | else if (is_ireg(r) && is_ireg(v)) | 305 | else if (is_ireg(r) && is_ireg(v)) |
| 312 | EI(0x13, 0, rr, ireg(v), 0); // addi RR, V, 0 == mv RR, V | 306 | EI(S, 0x13, 0, rr, ireg(v), 0); // addi RR, V, 0 == mv RR, V |
| 313 | else { | 307 | else { |
| 314 | int func7 = is_ireg(r) ? 0x70 : 0x78; | 308 | int func7 = is_ireg(r) ? 0x70 : 0x78; |
| 315 | size = type_size(&sv->type, &align); | 309 | size = type_size(&sv->type, &align); |
| 316 | if (size == 8) | 310 | if (size == 8) |
| 317 | func7 |= 1; | 311 | func7 |= 1; |
| 318 | assert(size == 4 || size == 8); | 312 | assert(size == 4 || size == 8); |
| 319 | o(0x53 | (rr << 7) | ((is_freg(v) ? freg(v) : ireg(v)) << 15) | 313 | o(S, 0x53 | (rr << 7) | ((is_freg(v) ? freg(v) : ireg(v)) << 15) |
| 320 | | (func7 << 25)); // fmv.{w.x, x.w, d.x, x.d} RR, VR | 314 | | (func7 << 25)); // fmv.{w.x, x.w, d.x, x.d} RR, VR |
| 321 | } | 315 | } |
| 322 | } else if (v == VT_CMP) { | 316 | } else if (v == VT_CMP) { |
| 323 | int op = vtop->cmp_op; | 317 | int op = S->tccgen_vtop->cmp_op; |
| 324 | int a = vtop->cmp_r & 0xff; | 318 | int a = S->tccgen_vtop->cmp_r & 0xff; |
| 325 | int b = (vtop->cmp_r >> 8) & 0xff; | 319 | int b = (S->tccgen_vtop->cmp_r >> 8) & 0xff; |
| 326 | int inv = 0; | 320 | int inv = 0; |
| 327 | switch (op) { | 321 | switch (op) { |
| 328 | case TOK_ULT: | 322 | case TOK_ULT: |
| @@ -341,32 +335,32 @@ ST_FUNC void load(int r, SValue *sv) · 12 unmodified lines | |||
| 341 | int t = a; a = b; b = t; | 335 | int t = a; a = b; b = t; |
| 342 | inv ^= 1; | 336 | inv ^= 1; |
| 343 | } | 337 | } |
| 344 | ER(0x33, (op > TOK_UGT) ? 2 : 3, rr, a, b, 0); // slt[u] d, a, b | 338 | ER(S, 0x33, (op > TOK_UGT) ? 2 : 3, rr, a, b, 0); // slt[u] d, a, b |
| 345 | if (inv) | 339 | if (inv) |
| 346 | EI(0x13, 4, rr, rr, 1); // xori d, d, 1 | 340 | EI(S, 0x13, 4, rr, rr, 1); // xori d, d, 1 |
| 347 | break; | 341 | break; |
| 348 | case TOK_NE: | 342 | case TOK_NE: |
| 349 | case TOK_EQ: | 343 | case TOK_EQ: |
| 350 | if (rr != a || b) | 344 | if (rr != a || b) |
| 351 | ER(0x33, 0, rr, a, b, 0x20); // sub d, a, b | 345 | ER(S, 0x33, 0, rr, a, b, 0x20); // sub d, a, b |
| 352 | if (op == TOK_NE) | 346 | if (op == TOK_NE) |
| 353 | ER(0x33, 3, rr, 0, rr, 0); // sltu d, x0, d == snez d,d | 347 | ER(S, 0x33, 3, rr, 0, rr, 0); // sltu d, x0, d == snez d,d |
| 354 | else | 348 | else |
| 355 | EI(0x13, 3, rr, rr, 1); // sltiu d, d, 1 == seqz d,d | 349 | EI(S, 0x13, 3, rr, rr, 1); // sltiu d, d, 1 == seqz d,d |
| 356 | break; | 350 | break; |
| 357 | } | 351 | } |
| 358 | } else if ((v & ~1) == VT_JMP) { | 352 | } else if ((v & ~1) == VT_JMP) { |
| 359 | int t = v & 1; | 353 | int t = v & 1; |
| 360 | assert(is_ireg(r)); | 354 | assert(is_ireg(r)); |
| 361 | EI(0x13, 0, rr, 0, t); // addi RR, x0, t | 355 | EI(S, 0x13, 0, rr, 0, t); // addi RR, x0, t |
| 362 | gjmp_addr(ind + 8); | 356 | gjmp_addr(S, S->tccgen_ind + 8); |
| 363 | gsym(fc); | 357 | gsym(S, fc); |
| 364 | EI(0x13, 0, rr, 0, t ^ 1); // addi RR, x0, !t | 358 | EI(S, 0x13, 0, rr, 0, t ^ 1); // addi RR, x0, !t |
| 365 | } else | 359 | } else |
| 366 | tcc_error("unimp: load(non-const)"); | 360 | tcc_error(S, "unimp: load(non-const)"); |
| 367 | } | 361 | } |
| 368 | 362 | ||
| 369 | ST_FUNC void store(int r, SValue *sv) | 363 | ST_FUNC void store(TCCState* S, int r, SValue *sv) |
| 370 | { | 364 | { |
| 371 | int fr = sv->r & VT_VALMASK; | 365 | int fr = sv->r & VT_VALMASK; |
| 372 | int rr = is_ireg(r) ? ireg(r) : freg(r), ptrreg; | 366 | int rr = is_ireg(r) ? ireg(r) : freg(r), ptrreg; |
| @@ -379,125 +373,125 @@ ST_FUNC void store(int r, SValue *sv) · 6 unmodified lines | |||
| 379 | if (bt == VT_LDOUBLE) | 373 | if (bt == VT_LDOUBLE) |
| 380 | size = align = 8; | 374 | size = align = 8; |
| 381 | if (bt == VT_STRUCT) | 375 | if (bt == VT_STRUCT) |
| 382 | tcc_error("unimp: store(struct)"); | 376 | tcc_error(S, "unimp: store(struct)"); |
| 383 | if (size > 8) | 377 | if (size > 8) |
| 384 | tcc_error("unimp: large sized store"); | 378 | tcc_error(S, "unimp: large sized store"); |
| 385 | assert(sv->r & VT_LVAL); | 379 | assert(sv->r & VT_LVAL); |
| 386 | if (fr == VT_LOCAL || (sv->r & VT_SYM)) { | 380 | if (fr == VT_LOCAL || (sv->r & VT_SYM)) { |
| 387 | ptrreg = load_symofs(-1, sv, 1); | 381 | ptrreg = load_symofs(S, -1, sv, 1); |
| 388 | fc = sv->c.i; | 382 | fc = sv->c.i; |
| 389 | } else if (fr < VT_CONST) { | 383 | } else if (fr < VT_CONST) { |
| 390 | ptrreg = ireg(fr); | 384 | ptrreg = ireg(fr); |
| 391 | /*if (((unsigned)fc + (1 << 11)) >> 12) | 385 | /*if (((unsigned)fc + (1 << 11)) >> 12) |
| 392 | tcc_error("unimp: store(large addend) (0x%x)", fc);*/ | 386 | tcc_error(S, "unimp: store(large addend) (0x%x)", fc);*/ |
| 393 | fc = 0; // XXX support offsets regs | 387 | fc = 0; // XXX support offsets regs |
| 394 | } else if (fr == VT_CONST) { | 388 | } else if (fr == VT_CONST) { |
| 395 | int64_t si = sv->c.i; | 389 | int64_t si = sv->c.i; |
| 396 | ptrreg = 8; // s0 | 390 | ptrreg = 8; // s0 |
| 397 | si >>= 32; | 391 | si >>= 32; |
| 398 | if (si != 0) { | 392 | if (si != 0) { |
| 399 | load_large_constant(ptrreg, fc, si); | 393 | load_large_constant(S, ptrreg, fc, si); |
| 400 | fc &= 0xff; | 394 | fc &= 0xff; |
| 401 | } else { | 395 | } else { |
| 402 | o(0x37 | (ptrreg << 7) | ((0x800 + fc) & 0xfffff000)); //lui RR, upper(fc) | 396 | o(S, 0x37 | (ptrreg << 7) | ((0x800 + fc) & 0xfffff000)); //lui RR, upper(fc) |
| 403 | fc = fc << 20 >> 20; | 397 | fc = fc << 20 >> 20; |
| 404 | } | 398 | } |
| 405 | } else | 399 | } else |
| 406 | tcc_error("implement me: %s(!local)", __FUNCTION__); | 400 | tcc_error(S, "implement me: %s(!local)", __FUNCTION__); |
| 407 | ES(is_freg(r) ? 0x27 : 0x23, // fs... | s... | 401 | ES(S, is_freg(r) ? 0x27 : 0x23, // fs... | s... |
| 408 | size == 1 ? 0 : size == 2 ? 1 : size == 4 ? 2 : 3, // ... [wd] | [bhwd] | 402 | size == 1 ? 0 : size == 2 ? 1 : size == 4 ? 2 : 3, // ... [wd] | [bhwd] |
| 409 | ptrreg, rr, fc); // RR, fc(base) | 403 | ptrreg, rr, fc); // RR, fc(base) |
| 410 | } | 404 | } |
| 411 | 405 | ||
| 412 | static void gcall_or_jmp(int docall) | 406 | static void gcall_or_jmp(TCCState* S, int docall) |
| 413 | { | 407 | { |
| 414 | int tr = docall ? 1 : 5; // ra or t0 | 408 | int tr = docall ? 1 : 5; // ra or t0 |
| 415 | if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && | 409 | if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && |
| 416 | ((vtop->r & VT_SYM) && vtop->c.i == (int)vtop->c.i)) { | 410 | ((S->tccgen_vtop->r & VT_SYM) && S->tccgen_vtop->c.i == (int)S->tccgen_vtop->c.i)) { |
| 417 | /* constant symbolic case -> simple relocation */ | 411 | /* constant symbolic case -> simple relocation */ |
| 418 | greloca(cur_text_section, vtop->sym, ind, | 412 | greloca(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind, |
| 419 | R_RISCV_CALL_PLT, (int)vtop->c.i); | 413 | R_RISCV_CALL_PLT, (int)S->tccgen_vtop->c.i); |
| 420 | o(0x17 | (tr << 7)); // auipc TR, 0 %call(func) | 414 | o(S, 0x17 | (tr << 7)); // auipc TR, 0 %call(func) |
| 421 | EI(0x67, 0, tr, tr, 0);// jalr TR, r(TR) | 415 | EI(S, 0x67, 0, tr, tr, 0);// jalr TR, r(TR) |
| 422 | } else if (vtop->r < VT_CONST) { | 416 | } else if (S->tccgen_vtop->r < VT_CONST) { |
| 423 | int r = ireg(vtop->r); | 417 | int r = ireg(S->tccgen_vtop->r); |
| 424 | EI(0x67, 0, tr, r, 0); // jalr TR, 0(R) | 418 | EI(S, 0x67, 0, tr, r, 0); // jalr TR, 0(R) |
| 425 | } else { | 419 | } else { |
| 426 | int r = TREG_RA; | 420 | int r = TREG_RA; |
| 427 | load(r, vtop); | 421 | load(S, r, S->tccgen_vtop); |
| 428 | r = ireg(r); | 422 | r = ireg(r); |
| 429 | EI(0x67, 0, tr, r, 0); // jalr TR, 0(R) | 423 | EI(S, 0x67, 0, tr, r, 0); // jalr TR, 0(R) |
| 430 | } | 424 | } |
| 431 | } | 425 | } |
| 432 | 426 | ||
| 433 | #if defined(CONFIG_TCC_BCHECK) | 427 | #if defined(CONFIG_TCC_BCHECK) |
| 434 | 428 | ||
| 435 | static void gen_bounds_call(int v) | 429 | static void gen_bounds_call(TCCState* S, int v) |
| 436 | { | 430 | { |
| 437 | Sym *sym = external_helper_sym(v); | 431 | Sym *sym = external_helper_sym(S, v); |
| 438 | 432 | ||
| 439 | greloca(cur_text_section, sym, ind, R_RISCV_CALL_PLT, 0); | 433 | greloca(S, cur_text_section, sym, S->tccgen_ind, R_RISCV_CALL_PLT, 0); |
| 440 | o(0x17 | (1 << 7)); // auipc TR, 0 %call(func) | 434 | o(S, 0x17 | (1 << 7)); // auipc TR, 0 %call(func) |
| 441 | EI(0x67, 0, 1, 1, 0); // jalr TR, r(TR) | 435 | EI(S, 0x67, 0, 1, 1, 0); // jalr TR, r(TR) |
| 442 | } | 436 | } |
| 443 | 437 | ||
| 444 | static void gen_bounds_prolog(void) | 438 | static void gen_bounds_prolog(TCCState* S) |
| 445 | { | 439 | { |
| 446 | /* leave some room for bound checking code */ | 440 | /* leave some room for bound checking code */ |
| 447 | func_bound_offset = lbounds_section->data_offset; | 441 | S->func_bound_offset = lbounds_section->data_offset; |
| 448 | func_bound_ind = ind; | 442 | S->func_bound_ind = S->tccgen_ind; |
| 449 | func_bound_add_epilog = 0; | 443 | S->func_bound_add_epilog = 0; |
| 450 | o(0x00000013); /* ld a0,#lbound section pointer */ | 444 | o(S, 0x00000013); /* ld a0,#lbound section pointer */ |
| 451 | o(0x00000013); | 445 | o(S, 0x00000013); |
| 452 | o(0x00000013); /* nop -> call __bound_local_new */ | 446 | o(S, 0x00000013); /* nop -> call __bound_local_new */ |
| 453 | o(0x00000013); | 447 | o(S, 0x00000013); |
| 454 | } | 448 | } |
| 455 | 449 | ||
| 456 | static void gen_bounds_epilog(void) | 450 | static void gen_bounds_epilog(TCCState* S) |
| 457 | { | 451 | { |
| 458 | addr_t saved_ind; | 452 | addr_t saved_ind; |
| 459 | addr_t *bounds_ptr; | 453 | addr_t *bounds_ptr; |
| 460 | Sym *sym_data; | 454 | Sym *sym_data; |
| 461 | Sym label = {0}; | 455 | Sym label = {0}; |
| 462 | 456 | ||
| 463 | int offset_modified = func_bound_offset != lbounds_section->data_offset; | 457 | int offset_modified = S->func_bound_offset != lbounds_section->data_offset; |
| 464 | 458 | ||
| 465 | if (!offset_modified && !func_bound_add_epilog) | 459 | if (!offset_modified && !S->func_bound_add_epilog) |
| 466 | return; | 460 | return; |
| 467 | 461 | ||
| 468 | /* add end of table info */ | 462 | /* add end of table info */ |
| 469 | bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t)); | 463 | bounds_ptr = section_ptr_add(S, lbounds_section, sizeof(addr_t)); |
| 470 | *bounds_ptr = 0; | 464 | *bounds_ptr = 0; |
| 471 | 465 | ||
| 472 | sym_data = get_sym_ref(&char_pointer_type, lbounds_section, | 466 | sym_data = get_sym_ref(S, &S->tccgen_char_pointer_type, lbounds_section, |
| 473 | func_bound_offset, lbounds_section->data_offset); | 467 | S->func_bound_offset, lbounds_section->data_offset); |
| 474 | 468 | ||
| 475 | label.type.t = VT_VOID | VT_STATIC; | 469 | label.type.t = VT_VOID | VT_STATIC; |
| 476 | /* generate bound local allocation */ | 470 | /* generate bound local allocation */ |
| 477 | if (offset_modified) { | 471 | if (offset_modified) { |
| 478 | saved_ind = ind; | 472 | saved_ind = S->tccgen_ind; |
| 479 | ind = func_bound_ind; | 473 | S->tccgen_ind = S->func_bound_ind; |
| 480 | put_extern_sym(&label, cur_text_section, ind, 0); | 474 | put_extern_sym(S, &label, cur_text_section, S->tccgen_ind, 0); |
| 481 | greloca(cur_text_section, sym_data, ind, R_RISCV_GOT_HI20, 0); | 475 | greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_RISCV_GOT_HI20, 0); |
| 482 | o(0x17 | (10 << 7)); // auipc a0, 0 %pcrel_hi(sym)+addend | 476 | o(S, 0x17 | (10 << 7)); // auipc a0, 0 %pcrel_hi(sym)+addend |
| 483 | greloca(cur_text_section, &label, ind, R_RISCV_PCREL_LO12_I, 0); | 477 | greloca(S, cur_text_section, &label, S->tccgen_ind, R_RISCV_PCREL_LO12_I, 0); |
| 484 | EI(0x03, 3, 10, 10, 0); // ld a0, 0(a0) | 478 | EI(S, 0x03, 3, 10, 10, 0); // ld a0, 0(a0) |
| 485 | gen_bounds_call(TOK___bound_local_new); | 479 | gen_bounds_call(S, TOK___bound_local_new); |
| 486 | ind = saved_ind; | 480 | S->tccgen_ind = saved_ind; |
| 487 | label.c = 0; /* force new local ELF symbol */ | 481 | label.c = 0; /* force new local ELF symbol */ |
| 488 | } | 482 | } |
| 489 | 483 | ||
| 490 | /* generate bound check local freeing */ | 484 | /* generate bound check local freeing */ |
| 491 | o(0xe02a1101); /* addi sp,sp,-32 sd a0,0(sp) */ | 485 | o(S, 0xe02a1101); /* addi sp,sp,-32 sd a0,0(sp) */ |
| 492 | o(0xa82ae42e); /* sd a1,8(sp) fsd fa0,16(sp) */ | 486 | o(S, 0xa82ae42e); /* sd a1,8(sp) fsd fa0,16(sp) */ |
| 493 | put_extern_sym(&label, cur_text_section, ind, 0); | 487 | put_extern_sym(S, &label, cur_text_section, S->tccgen_ind, 0); |
| 494 | greloca(cur_text_section, sym_data, ind, R_RISCV_GOT_HI20, 0); | 488 | greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_RISCV_GOT_HI20, 0); |
| 495 | o(0x17 | (10 << 7)); // auipc a0, 0 %pcrel_hi(sym)+addend | 489 | o(S, 0x17 | (10 << 7)); // auipc a0, 0 %pcrel_hi(sym)+addend |
| 496 | greloca(cur_text_section, &label, ind, R_RISCV_PCREL_LO12_I, 0); | 490 | greloca(S, cur_text_section, &label, S->tccgen_ind, R_RISCV_PCREL_LO12_I, 0); |
| 497 | EI(0x03, 3, 10, 10, 0); // ld a0, 0(a0) | 491 | EI(S, 0x03, 3, 10, 10, 0); // ld a0, 0(a0) |
| 498 | gen_bounds_call(TOK___bound_local_delete); | 492 | gen_bounds_call(S, TOK___bound_local_delete); |
| 499 | o(0x65a26502); /* ld a0,0(sp) ld a1,8(sp) */ | 493 | o(S, 0x65a26502); /* ld a0,0(sp) ld a1,8(sp) */ |
| 500 | o(0x61052542); /* fld fa0,16(sp) addi sp,sp,32 */ | 494 | o(S, 0x61052542); /* fld fa0,16(sp) addi sp,sp,32 */ |
| 501 | } | 495 | } |
| 502 | #endif | 496 | #endif |
| 503 | 497 | ||
| @@ -546,27 +540,27 @@ static void reg_pass(CType *type, int *prc, int *fieldofs, int named) · 42 unmodified lines | |||
| 546 | } | 540 | } |
| 547 | } | 541 | } |
| 548 | 542 | ||
| 549 | ST_FUNC void gfunc_call(int nb_args) | 543 | ST_FUNC void gfunc_call(TCCState* S, int nb_args) |
| 550 | { | 544 | { |
| 551 | int i, align, size, areg[2]; | 545 | int i, align, size, areg[2]; |
| 552 | int *info = tcc_malloc((nb_args + 1) * sizeof (int)); | 546 | int *info = tcc_malloc(S, (nb_args + 1) * sizeof (int)); |
| 553 | int stack_adj = 0, tempspace = 0, stack_add, ofs, splitofs = 0; | 547 | int stack_adj = 0, tempspace = 0, stack_add, ofs, splitofs = 0; |
| 554 | SValue *sv; | 548 | SValue *sv; |
| 555 | Sym *sa; | 549 | Sym *sa; |
| 556 | 550 | ||
| 557 | #ifdef CONFIG_TCC_BCHECK | 551 | #ifdef CONFIG_TCC_BCHECK |
| 558 | int bc_save = tcc_state->do_bounds_check; | 552 | int bc_save = S->do_bounds_check; |
| 559 | if (tcc_state->do_bounds_check) | 553 | if (S->do_bounds_check) |
| 560 | gbound_args(nb_args); | 554 | gbound_args(S, nb_args); |
| 561 | #endif | 555 | #endif |
| 562 | 556 | ||
| 563 | areg[0] = 0; /* int arg regs */ | 557 | areg[0] = 0; /* int arg regs */ |
| 564 | areg[1] = 8; /* float arg regs */ | 558 | areg[1] = 8; /* float arg regs */ |
| 565 | sa = vtop[-nb_args].type.ref->next; | 559 | sa = S->tccgen_vtop[-nb_args].type.ref->next; |
| 566 | for (i = 0; i < nb_args; i++) { | 560 | for (i = 0; i < nb_args; i++) { |
| 567 | int nregs, byref = 0, tempofs; | 561 | int nregs, byref = 0, tempofs; |
| 568 | int prc[3], fieldofs[3]; | 562 | int prc[3], fieldofs[3]; |
| 569 | sv = &vtop[1 + i - nb_args]; | 563 | sv = &S->tccgen_vtop[1 + i - nb_args]; |
| 570 | sv->type.t &= ~VT_ARRAY; // XXX this should be done in tccgen.c | 564 | sv->type.t &= ~VT_ARRAY; // XXX this should be done in tccgen.c |
| 571 | size = type_size(&sv->type, &align); | 565 | size = type_size(&sv->type, &align); |
| 572 | if (size > 16) { | 566 | if (size > 16) { |
| @@ -623,53 +617,53 @@ ST_FUNC void gfunc_call(int nb_args) · 50 unmodified lines | |||
| 623 | stack_add = stack_adj + tempspace; | 617 | stack_add = stack_adj + tempspace; |
| 624 | 618 | ||
| 625 | /* fetch cpu flag before generating any code */ | 619 | /* fetch cpu flag before generating any code */ |
| 626 | if ((vtop->r & VT_VALMASK) == VT_CMP) | 620 | if ((S->tccgen_vtop->r & VT_VALMASK) == VT_CMP) |
| 627 | gv(RC_INT); | 621 | gv(S, RC_INT); |
| 628 | 622 | ||
| 629 | if (stack_add) { | 623 | if (stack_add) { |
| 630 | if (stack_add >= 0x1000) { | 624 | if (stack_add >= 0x1000) { |
| 631 | o(0x37 | (5 << 7) | (-stack_add & 0xfffff000)); //lui t0, upper(v) | 625 | o(S, 0x37 | (5 << 7) | (-stack_add & 0xfffff000)); //lui t0, upper(v) |
| 632 | EI(0x13, 0, 5, 5, -stack_add << 20 >> 20); // addi t0, t0, lo(v) | 626 | EI(S, 0x13, 0, 5, 5, -stack_add << 20 >> 20); // addi t0, t0, lo(v) |
| 633 | ER(0x33, 0, 2, 2, 5, 0); // add sp, sp, t0 | 627 | ER(S, 0x33, 0, 2, 2, 5, 0); // add sp, sp, t0 |
| 634 | } | 628 | } |
| 635 | else | 629 | else |
| 636 | EI(0x13, 0, 2, 2, -stack_add); // addi sp, sp, -adj | 630 | EI(S, 0x13, 0, 2, 2, -stack_add); // addi sp, sp, -adj |
| 637 | for (i = ofs = 0; i < nb_args; i++) { | 631 | for (i = ofs = 0; i < nb_args; i++) { |
| 638 | if (info[i] & (64 | 32)) { | 632 | if (info[i] & (64 | 32)) { |
| 639 | vrotb(nb_args - i); | 633 | vrotb(S, nb_args - i); |
| 640 | size = type_size(&vtop->type, &align); | 634 | size = type_size(&S->tccgen_vtop->type, &align); |
| 641 | if (info[i] & 64) { | 635 | if (info[i] & 64) { |
| 642 | vset(&char_pointer_type, TREG_SP, 0); | 636 | vset(S, &S->tccgen_char_pointer_type, TREG_SP, 0); |
| 643 | vpushi(stack_adj + (info[i] >> 7)); | 637 | vpushi(S, stack_adj + (info[i] >> 7)); |
| 644 | gen_op('+'); | 638 | gen_op(S, '+'); |
| 645 | vpushv(vtop); // this replaces the old argument | 639 | vpushv(S, S->tccgen_vtop); // this replaces the old argument |
| 646 | vrott(3); | 640 | vrott(S, 3); |
| 647 | indir(); | 641 | indir(S); |
| 648 | vtop->type = vtop[-1].type; | 642 | S->tccgen_vtop->type = S->tccgen_vtop[-1].type; |
| 649 | vswap(); | 643 | vswap(S); |
| 650 | vstore(); | 644 | vstore(S); |
| 651 | vpop(); | 645 | vpop(S); |
| 652 | size = align = 8; | 646 | size = align = 8; |
| 653 | } | 647 | } |
| 654 | if (info[i] & 32) { | 648 | if (info[i] & 32) { |
| 655 | if (align < XLEN) | 649 | if (align < XLEN) |
| 656 | align = XLEN; | 650 | align = XLEN; |
| 657 | /* Once we support offseted regs we can do this: | 651 | /* Once we support offseted regs we can do this: |
| 658 | vset(&vtop->type, TREG_SP | VT_LVAL, ofs); | 652 | vset(S, &S->tccgen_vtop->type, TREG_SP | VT_LVAL, ofs); |
| 659 | to construct the lvalue for the outgoing stack slot, | 653 | to construct the lvalue for the outgoing stack slot, |
| 660 | until then we have to jump through hoops. */ | 654 | until then we have to jump through hoops. */ |
| 661 | vset(&char_pointer_type, TREG_SP, 0); | 655 | vset(S, &S->tccgen_char_pointer_type, TREG_SP, 0); |
| 662 | ofs = (ofs + align - 1) & -align; | 656 | ofs = (ofs + align - 1) & -align; |
| 663 | vpushi(ofs); | 657 | vpushi(S, ofs); |
| 664 | gen_op('+'); | 658 | gen_op(S, '+'); |
| 665 | indir(); | 659 | indir(S); |
| 666 | vtop->type = vtop[-1].type; | 660 | S->tccgen_vtop->type = S->tccgen_vtop[-1].type; |
| 667 | vswap(); | 661 | vswap(S); |
| 668 | vstore(); | 662 | vstore(S); |
| 669 | vtop->r = vtop->r2 = VT_CONST; // this arg is done | 663 | S->tccgen_vtop->r = S->tccgen_vtop->r2 = VT_CONST; // this arg is done |
| 670 | ofs += size; | 664 | ofs += size; |
| 671 | } | 665 | } |
| 672 | vrott(nb_args - i); | 666 | vrott(S, nb_args - i); |
| 673 | } else if (info[i] & 16) { | 667 | } else if (info[i] & 16) { |
| 674 | assert(!splitofs); | 668 | assert(!splitofs); |
| 675 | splitofs = ofs; | 669 | splitofs = ofs; |
| @@ -685,12 +679,12 @@ ST_FUNC void gfunc_call(int nb_args) · 9 unmodified lines | |||
| 685 | r &= 15; | 679 | r &= 15; |
| 686 | r2 = r2 & 64 ? 0 : (r2 >> 7) & 31; | 680 | r2 = r2 & 64 ? 0 : (r2 >> 7) & 31; |
| 687 | assert(r2 <= 16); | 681 | assert(r2 <= 16); |
| 688 | vrotb(i+1); | 682 | vrotb(S, i+1); |
| 689 | origtype = vtop->type; | 683 | origtype = S->tccgen_vtop->type; |
| 690 | size = type_size(&vtop->type, &align); | 684 | size = type_size(&S->tccgen_vtop->type, &align); |
| 691 | if (size == 0) | 685 | if (size == 0) |
| 692 | goto done; | 686 | goto done; |
| 693 | loadt = vtop->type.t & VT_BTYPE; | 687 | loadt = S->tccgen_vtop->type.t & VT_BTYPE; |
| 694 | if (loadt == VT_STRUCT) { | 688 | if (loadt == VT_STRUCT) { |
| 695 | loadt = (ii >> 12) & VT_BTYPE; | 689 | loadt = (ii >> 12) & VT_BTYPE; |
| 696 | } | 690 | } |
| @@ -702,74 +696,74 @@ ST_FUNC void gfunc_call(int nb_args) · 5 unmodified lines | |||
| 702 | assert(r2); | 696 | assert(r2); |
| 703 | r2--; | 697 | r2--; |
| 704 | } else if (r2) { | 698 | } else if (r2) { |
| 705 | test_lvalue(); | 699 | test_lvalue(S); |
| 706 | vpushv(vtop); | 700 | vpushv(S, S->tccgen_vtop); |
| 707 | } | 701 | } |
| 708 | vtop->type.t = loadt | (vtop->type.t & VT_UNSIGNED); | 702 | S->tccgen_vtop->type.t = loadt | (S->tccgen_vtop->type.t & VT_UNSIGNED); |
| 709 | gv(r < 8 ? RC_R(r) : RC_F(r - 8)); | 703 | gv(S, r < 8 ? RC_R(r) : RC_F(r - 8)); |
| 710 | vtop->type = origtype; | 704 | S->tccgen_vtop->type = origtype; |
| 711 | 705 | ||
| 712 | if (r2 && loadt != VT_LDOUBLE) { | 706 | if (r2 && loadt != VT_LDOUBLE) { |
| 713 | r2--; | 707 | r2--; |
| 714 | assert(r2 < 16 || r2 == TREG_RA); | 708 | assert(r2 < 16 || r2 == TREG_RA); |
| 715 | vswap(); | 709 | vswap(S); |
| 716 | gaddrof(); | 710 | gaddrof(S); |
| 717 | vtop->type = char_pointer_type; | 711 | S->tccgen_vtop->type = S->tccgen_char_pointer_type; |
| 718 | vpushi(ii >> 20); | 712 | vpushi(S, ii >> 20); |
| 719 | #ifdef CONFIG_TCC_BCHECK | 713 | #ifdef CONFIG_TCC_BCHECK |
| 720 | if ((origtype.t & VT_BTYPE) == VT_STRUCT) | 714 | if ((origtype.t & VT_BTYPE) == VT_STRUCT) |
| 721 | tcc_state->do_bounds_check = 0; | 715 | S->do_bounds_check = 0; |
| 722 | #endif | 716 | #endif |
| 723 | gen_op('+'); | 717 | gen_op(S, '+'); |
| 724 | #ifdef CONFIG_TCC_BCHECK | 718 | #ifdef CONFIG_TCC_BCHECK |
| 725 | tcc_state->do_bounds_check = bc_save; | 719 | S->do_bounds_check = bc_save; |
| 726 | #endif | 720 | #endif |
| 727 | indir(); | 721 | indir(S); |
| 728 | vtop->type = origtype; | 722 | S->tccgen_vtop->type = origtype; |
| 729 | loadt = vtop->type.t & VT_BTYPE; | 723 | loadt = S->tccgen_vtop->type.t & VT_BTYPE; |
| 730 | if (loadt == VT_STRUCT) { | 724 | if (loadt == VT_STRUCT) { |
| 731 | loadt = (ii >> 16) & VT_BTYPE; | 725 | loadt = (ii >> 16) & VT_BTYPE; |
| 732 | } | 726 | } |
| 733 | save_reg_upstack(r2, 1); | 727 | save_reg_upstack(S, r2, 1); |
| 734 | vtop->type.t = loadt | (vtop->type.t & VT_UNSIGNED); | 728 | S->tccgen_vtop->type.t = loadt | (S->tccgen_vtop->type.t & VT_UNSIGNED); |
| 735 | load(r2, vtop); | 729 | load(S, r2, S->tccgen_vtop); |
| 736 | assert(r2 < VT_CONST); | 730 | assert(r2 < VT_CONST); |
| 737 | vtop--; | 731 | S->tccgen_vtop--; |
| 738 | vtop->r2 = r2; | 732 | S->tccgen_vtop->r2 = r2; |
| 739 | } | 733 | } |
| 740 | if (info[nb_args - 1 - i] & 16) { | 734 | if (info[nb_args - 1 - i] & 16) { |
| 741 | ES(0x23, 3, 2, ireg(vtop->r2), splitofs); // sd t0, ofs(sp) | 735 | ES(S, 0x23, 3, 2, ireg(S->tccgen_vtop->r2), splitofs); // sd t0, ofs(sp) |
| 742 | vtop->r2 = VT_CONST; | 736 | S->tccgen_vtop->r2 = VT_CONST; |
| 743 | } else if (loadt == VT_LDOUBLE && vtop->r2 != r2) { | 737 | } else if (loadt == VT_LDOUBLE && S->tccgen_vtop->r2 != r2) { |
| 744 | assert(vtop->r2 <= 7 && r2 <= 7); | 738 | assert(S->tccgen_vtop->r2 <= 7 && r2 <= 7); |
| 745 | /* XXX we'd like to have 'gv' move directly into | 739 | /* XXX we'd like to have 'gv' move directly into |
| 746 | the right class instead of us fixing it up. */ | 740 | the right class instead of us fixing it up. */ |
| 747 | EI(0x13, 0, ireg(r2), ireg(vtop->r2), 0); // mv Ra+1, RR2 | 741 | EI(S, 0x13, 0, ireg(r2), ireg(S->tccgen_vtop->r2), 0); // mv Ra+1, RR2 |
| 748 | vtop->r2 = r2; | 742 | S->tccgen_vtop->r2 = r2; |
| 749 | } | 743 | } |
| 750 | done: | 744 | done: |
| 751 | vrott(i+1); | 745 | vrott(S, i+1); |
| 752 | } | 746 | } |
| 753 | } | 747 | } |
| 754 | vrotb(nb_args + 1); | 748 | vrotb(S, nb_args + 1); |
| 755 | save_regs(nb_args + 1); | 749 | save_regs(S, nb_args + 1); |
| 756 | gcall_or_jmp(1); | 750 | gcall_or_jmp(S, 1); |
| 757 | vtop -= nb_args + 1; | 751 | S->tccgen_vtop -= nb_args + 1; |
| 758 | if (stack_add) { | 752 | if (stack_add) { |
| 759 | if (stack_add >= 0x1000) { | 753 | if (stack_add >= 0x1000) { |
| 760 | o(0x37 | (5 << 7) | (stack_add & 0xfffff000)); //lui t0, upper(v) | 754 | o(S, 0x37 | (5 << 7) | (stack_add & 0xfffff000)); //lui t0, upper(v) |
| 761 | EI(0x13, 0, 5, 5, stack_add << 20 >> 20); // addi t0, t0, lo(v) | 755 | EI(S, 0x13, 0, 5, 5, stack_add << 20 >> 20); // addi t0, t0, lo(v) |
| 762 | ER(0x33, 0, 2, 2, 5, 0); // add sp, sp, t0 | 756 | ER(S, 0x33, 0, 2, 2, 5, 0); // add sp, sp, t0 |
| 763 | } | 757 | } |
| 764 | else | 758 | else |
| 765 | EI(0x13, 0, 2, 2, stack_add); // addi sp, sp, adj | 759 | EI(S, 0x13, 0, 2, 2, stack_add); // addi sp, sp, adj |
| 766 | } | 760 | } |
| 767 | tcc_free(info); | 761 | tcc_free(S, info); |
| 768 | } | 762 | } |
| 769 | 763 | ||
| 770 | static int func_sub_sp_offset, num_va_regs, func_va_list_ofs; | 764 | static int func_sub_sp_offset, num_va_regs, func_va_list_ofs; |
| 771 | 765 | ||
| 772 | ST_FUNC void gfunc_prolog(Sym *func_sym) | 766 | ST_FUNC void gfunc_prolog(TCCState* S, Sym *func_sym) |
| 773 | { | 767 | { |
| 774 | CType *func_type = &func_sym->type; | 768 | CType *func_type = &func_sym->type; |
| 775 | int i, addr, align, size; | 769 | int i, addr, align, size; |
| @@ -779,19 +773,19 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 3 unmodified lines | |||
| 779 | CType *type; | 773 | CType *type; |
| 780 | 774 | ||
| 781 | sym = func_type->ref; | 775 | sym = func_type->ref; |
| 782 | loc = -16; // for ra and s0 | 776 | S->tccgen_loc = -16; // for ra and s0 |
| 783 | func_sub_sp_offset = ind; | 777 | func_sub_sp_offset = S->tccgen_ind; |
| 784 | ind += 5 * 4; | 778 | S->tccgen_ind += 5 * 4; |
| 785 | 779 | ||
| 786 | areg[0] = 0, areg[1] = 0; | 780 | areg[0] = 0, areg[1] = 0; |
| 787 | addr = 0; | 781 | addr = 0; |
| 788 | /* if the function returns by reference, then add an | 782 | /* if the function returns by reference, then add an |
| 789 | implicit pointer parameter */ | 783 | implicit pointer parameter */ |
| 790 | size = type_size(&func_vt, &align); | 784 | size = type_size(&S->tccgen_func_vt, &align); |
| 791 | if (size > 2 * XLEN) { | 785 | if (size > 2 * XLEN) { |
| 792 | loc -= 8; | 786 | S->tccgen_loc -= 8; |
| 793 | func_vc = loc; | 787 | S->tccgen_func_vc = S->tccgen_loc; |
| 794 | ES(0x23, 3, 8, 10 + areg[0]++, loc); // sd a0, loc(s0) | 788 | ES(S, 0x23, 3, 8, 10 + areg[0]++, S->tccgen_loc); // sd a0, loc(s0) |
| 795 | } | 789 | } |
| 796 | /* define parameters */ | 790 | /* define parameters */ |
| 797 | while ((sym = sym->next) != NULL) { | 791 | while ((sym = sym->next) != NULL) { |
| @@ -801,7 +795,7 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 3 unmodified lines | |||
| 801 | type = &sym->type; | 795 | type = &sym->type; |
| 802 | size = type_size(type, &align); | 796 | size = type_size(type, &align); |
| 803 | if (size > 2 * XLEN) { | 797 | if (size > 2 * XLEN) { |
| 804 | type = &char_pointer_type; | 798 | type = &S->tccgen_char_pointer_type; |
| 805 | size = align = byref = 8; | 799 | size = align = byref = 8; |
| 806 | } | 800 | } |
| 807 | reg_pass(type, prc, fieldofs, 1); | 801 | reg_pass(type, prc, fieldofs, 1); |
| @@ -816,36 +810,36 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 8 unmodified lines | |||
| 816 | param_addr = addr; | 810 | param_addr = addr; |
| 817 | addr += size; | 811 | addr += size; |
| 818 | } else { | 812 | } else { |
| 819 | loc -= regcount * 8; // XXX could reserve only 'size' bytes | 813 | S->tccgen_loc -= regcount * 8; // XXX could reserve only 'size' bytes |
| 820 | param_addr = loc; | 814 | param_addr = S->tccgen_loc; |
| 821 | for (i = 0; i < regcount; i++) { | 815 | for (i = 0; i < regcount; i++) { |
| 822 | if (areg[prc[1+i] - 1] >= 8) { | 816 | if (areg[prc[1+i] - 1] >= 8) { |
| 823 | assert(i == 1 && regcount == 2 && !(addr & 7)); | 817 | assert(i == 1 && regcount == 2 && !(addr & 7)); |
| 824 | EI(0x03, 3, 5, 8, addr); // ld t0, addr(s0) | 818 | EI(S, 0x03, 3, 5, 8, addr); // ld t0, addr(s0) |
| 825 | addr += 8; | 819 | addr += 8; |
| 826 | ES(0x23, 3, 8, 5, loc + i*8); // sd t0, loc(s0) | 820 | ES(S, 0x23, 3, 8, 5, S->tccgen_loc + i*8); // sd t0, loc(s0) |
| 827 | } else if (prc[1+i] == RC_FLOAT) { | 821 | } else if (prc[1+i] == RC_FLOAT) { |
| 828 | ES(0x27, (size / regcount) == 4 ? 2 : 3, 8, 10 + areg[1]++, loc + (fieldofs[i+1] >> 4)); // fs[wd] FAi, loc(s0) | 822 | ES(S, 0x27, (size / regcount) == 4 ? 2 : 3, 8, 10 + areg[1]++, S->tccgen_loc + (fieldofs[i+1] >> 4)); // fs[wd] FAi, loc(s0) |
| 829 | } else { | 823 | } else { |
| 830 | ES(0x23, 3, 8, 10 + areg[0]++, loc + i*8); // sd aX, loc(s0) // XXX | 824 | ES(S, 0x23, 3, 8, 10 + areg[0]++, S->tccgen_loc + i*8); // sd aX, loc(s0) // XXX |
| 831 | } | 825 | } |
| 832 | } | 826 | } |
| 833 | } | 827 | } |
| 834 | sym_push(sym->v & ~SYM_FIELD, &sym->type, | 828 | sym_push(S, sym->v & ~SYM_FIELD, &sym->type, |
| 835 | (byref ? VT_LLOCAL : VT_LOCAL) | VT_LVAL, | 829 | (byref ? VT_LLOCAL : VT_LOCAL) | VT_LVAL, |
| 836 | param_addr); | 830 | param_addr); |
| 837 | } | 831 | } |
| 838 | func_va_list_ofs = addr; | 832 | func_va_list_ofs = addr; |
| 839 | num_va_regs = 0; | 833 | num_va_regs = 0; |
| 840 | if (func_var) { | 834 | if (S->tccgen_func_var) { |
| 841 | for (; areg[0] < 8; areg[0]++) { | 835 | for (; areg[0] < 8; areg[0]++) { |
| 842 | num_va_regs++; | 836 | num_va_regs++; |
| 843 | ES(0x23, 3, 8, 10 + areg[0], -8 + num_va_regs * 8); // sd aX, loc(s0) | 837 | ES(S, 0x23, 3, 8, 10 + areg[0], -8 + num_va_regs * 8); // sd aX, loc(s0) |
| 844 | } | 838 | } |
| 845 | } | 839 | } |
| 846 | #ifdef CONFIG_TCC_BCHECK | 840 | #ifdef CONFIG_TCC_BCHECK |
| 847 | if (tcc_state->do_bounds_check) | 841 | if (S->do_bounds_check) |
| 848 | gen_bounds_prolog(); | 842 | gen_bounds_prolog(S); |
| 849 | #endif | 843 | #endif |
| 850 | } | 844 | } |
| 851 | 845 | ||
| @@ -870,113 +864,113 @@ ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, · 18 unmodified lines | |||
| 870 | return nregs; | 864 | return nregs; |
| 871 | } | 865 | } |
| 872 | 866 | ||
| 873 | ST_FUNC void arch_transfer_ret_regs(int aftercall) | 867 | ST_FUNC void arch_transfer_ret_regs(TCCState* S, int aftercall) |
| 874 | { | 868 | { |
| 875 | int prc[3], fieldofs[3]; | 869 | int prc[3], fieldofs[3]; |
| 876 | reg_pass(&vtop->type, prc, fieldofs, 1); | 870 | reg_pass(&S->tccgen_vtop->type, prc, fieldofs, 1); |
| 877 | assert(prc[0] == 2 && prc[1] != prc[2] && !(fieldofs[1] >> 4)); | 871 | assert(prc[0] == 2 && prc[1] != prc[2] && !(fieldofs[1] >> 4)); |
| 878 | assert(vtop->r == (VT_LOCAL | VT_LVAL)); | 872 | assert(S->tccgen_vtop->r == (VT_LOCAL | VT_LVAL)); |
| 879 | vpushv(vtop); | 873 | vpushv(S, S->tccgen_vtop); |
| 880 | vtop->type.t = fieldofs[1] & VT_BTYPE; | 874 | S->tccgen_vtop->type.t = fieldofs[1] & VT_BTYPE; |
| 881 | (aftercall ? store : load)(prc[1] == RC_INT ? REG_IRET : REG_FRET, vtop); | 875 | (aftercall ? store : load)(S, prc[1] == RC_INT ? REG_IRET : REG_FRET, S->tccgen_vtop); |
| 882 | vtop->c.i += fieldofs[2] >> 4; | 876 | S->tccgen_vtop->c.i += fieldofs[2] >> 4; |
| 883 | vtop->type.t = fieldofs[2] & VT_BTYPE; | 877 | S->tccgen_vtop->type.t = fieldofs[2] & VT_BTYPE; |
| 884 | (aftercall ? store : load)(prc[2] == RC_INT ? REG_IRET : REG_FRET, vtop); | 878 | (aftercall ? store : load)(S, prc[2] == RC_INT ? REG_IRET : REG_FRET, S->tccgen_vtop); |
| 885 | vtop--; | 879 | S->tccgen_vtop--; |
| 886 | } | 880 | } |
| 887 | 881 | ||
| 888 | ST_FUNC void gfunc_epilog(void) | 882 | ST_FUNC void gfunc_epilog(TCCState* S) |
| 889 | { | 883 | { |
| 890 | int v, saved_ind, d, large_ofs_ind; | 884 | int v, saved_ind, d, large_ofs_ind; |
| 891 | 885 | ||
| 892 | #ifdef CONFIG_TCC_BCHECK | 886 | #ifdef CONFIG_TCC_BCHECK |
| 893 | if (tcc_state->do_bounds_check) | 887 | if (S->do_bounds_check) |
| 894 | gen_bounds_epilog(); | 888 | gen_bounds_epilog(S); |
| 895 | #endif | 889 | #endif |
| 896 | 890 | ||
| 897 | loc = (loc - num_va_regs * 8); | 891 | S->tccgen_loc = (S->tccgen_loc - num_va_regs * 8); |
| 898 | d = v = (-loc + 15) & -16; | 892 | d = v = (-S->tccgen_loc + 15) & -16; |
| 899 | 893 | ||
| 900 | if (v >= (1 << 11)) { | 894 | if (v >= (1 << 11)) { |
| 901 | d = 16; | 895 | d = 16; |
| 902 | o(0x37 | (5 << 7) | ((0x800 + (v-16)) & 0xfffff000)); //lui t0, upper(v) | 896 | o(S, 0x37 | (5 << 7) | ((0x800 + (v-16)) & 0xfffff000)); //lui t0, upper(v) |
| 903 | EI(0x13, 0, 5, 5, (v-16) << 20 >> 20); // addi t0, t0, lo(v) | 897 | EI(S, 0x13, 0, 5, 5, (v-16) << 20 >> 20); // addi t0, t0, lo(v) |
| 904 | ER(0x33, 0, 2, 2, 5, 0); // add sp, sp, t0 | 898 | ER(S, 0x33, 0, 2, 2, 5, 0); // add sp, sp, t0 |
| 905 | } | 899 | } |
| 906 | EI(0x03, 3, 1, 2, d - 8 - num_va_regs * 8); // ld ra, v-8(sp) | 900 | EI(S, 0x03, 3, 1, 2, d - 8 - num_va_regs * 8); // ld ra, v-8(sp) |
| 907 | EI(0x03, 3, 8, 2, d - 16 - num_va_regs * 8); // ld s0, v-16(sp) | 901 | EI(S, 0x03, 3, 8, 2, d - 16 - num_va_regs * 8); // ld s0, v-16(sp) |
| 908 | EI(0x13, 0, 2, 2, d); // addi sp, sp, v | 902 | EI(S, 0x13, 0, 2, 2, d); // addi sp, sp, v |
| 909 | EI(0x67, 0, 0, 1, 0); // jalr x0, 0(x1), aka ret | 903 | EI(S, 0x67, 0, 0, 1, 0); // jalr x0, 0(x1), aka ret |
| 910 | large_ofs_ind = ind; | 904 | large_ofs_ind = S->tccgen_ind; |
| 911 | if (v >= (1 << 11)) { | 905 | if (v >= (1 << 11)) { |
| 912 | EI(0x13, 0, 8, 2, d - num_va_regs * 8); // addi s0, sp, d | 906 | EI(S, 0x13, 0, 8, 2, d - num_va_regs * 8); // addi s0, sp, d |
| 913 | o(0x37 | (5 << 7) | ((0x800 + (v-16)) & 0xfffff000)); //lui t0, upper(v) | 907 | o(S, 0x37 | (5 << 7) | ((0x800 + (v-16)) & 0xfffff000)); //lui t0, upper(v) |
| 914 | EI(0x13, 0, 5, 5, (v-16) << 20 >> 20); // addi t0, t0, lo(v) | 908 | EI(S, 0x13, 0, 5, 5, (v-16) << 20 >> 20); // addi t0, t0, lo(v) |
| 915 | ER(0x33, 0, 2, 2, 5, 0x20); // sub sp, sp, t0 | 909 | ER(S, 0x33, 0, 2, 2, 5, 0x20); // sub sp, sp, t0 |
| 916 | gjmp_addr(func_sub_sp_offset + 5*4); | 910 | gjmp_addr(S, func_sub_sp_offset + 5*4); |
| 917 | } | 911 | } |
| 918 | saved_ind = ind; | 912 | saved_ind = S->tccgen_ind; |
| 919 | 913 | ||
| 920 | ind = func_sub_sp_offset; | 914 | S->tccgen_ind = func_sub_sp_offset; |
| 921 | EI(0x13, 0, 2, 2, -d); // addi sp, sp, -d | 915 | EI(S, 0x13, 0, 2, 2, -d); // addi sp, sp, -d |
| 922 | ES(0x23, 3, 2, 1, d - 8 - num_va_regs * 8); // sd ra, d-8(sp) | 916 | ES(S, 0x23, 3, 2, 1, d - 8 - num_va_regs * 8); // sd ra, d-8(sp) |
| 923 | ES(0x23, 3, 2, 8, d - 16 - num_va_regs * 8); // sd s0, d-16(sp) | 917 | ES(S, 0x23, 3, 2, 8, d - 16 - num_va_regs * 8); // sd s0, d-16(sp) |
| 924 | if (v < (1 << 11)) | 918 | if (v < (1 << 11)) |
| 925 | EI(0x13, 0, 8, 2, d - num_va_regs * 8); // addi s0, sp, d | 919 | EI(S, 0x13, 0, 8, 2, d - num_va_regs * 8); // addi s0, sp, d |
| 926 | else | 920 | else |
| 927 | gjmp_addr(large_ofs_ind); | 921 | gjmp_addr(S, large_ofs_ind); |
| 928 | if ((ind - func_sub_sp_offset) != 5*4) | 922 | if ((S->tccgen_ind - func_sub_sp_offset) != 5*4) |
| 929 | EI(0x13, 0, 0, 0, 0); // addi x0, x0, 0 == nop | 923 | EI(S, 0x13, 0, 0, 0, 0); // addi x0, x0, 0 == nop |
| 930 | ind = saved_ind; | 924 | S->tccgen_ind = saved_ind; |
| 931 | } | 925 | } |
| 932 | 926 | ||
| 933 | ST_FUNC void gen_va_start(void) | 927 | ST_FUNC void gen_va_start(TCCState *S) |
| 934 | { | 928 | { |
| 935 | vtop--; | 929 | S->tccgen_vtop--; |
| 936 | vset(&char_pointer_type, VT_LOCAL, func_va_list_ofs); | 930 | vset(S, &S->tccgen_char_pointer_type, VT_LOCAL, func_va_list_ofs); |
| 937 | } | 931 | } |
| 938 | 932 | ||
| 939 | ST_FUNC void gen_fill_nops(int bytes) | 933 | ST_FUNC void gen_fill_nops(TCCState* S, int bytes) |
| 940 | { | 934 | { |
| 941 | if ((bytes & 3)) | 935 | if ((bytes & 3)) |
| 942 | tcc_error("alignment of code section not multiple of 4"); | 936 | tcc_error(S, "alignment of code section not multiple of 4"); |
| 943 | while (bytes > 0) { | 937 | while (bytes > 0) { |
| 944 | EI(0x13, 0, 0, 0, 0); // addi x0, x0, 0 == nop | 938 | EI(S, 0x13, 0, 0, 0, 0); // addi x0, x0, 0 == nop |
| 945 | bytes -= 4; | 939 | bytes -= 4; |
| 946 | } | 940 | } |
| 947 | } | 941 | } |
| 948 | 942 | ||
| 949 | // Generate forward branch to label: | 943 | // Generate forward branch to label: |
| 950 | ST_FUNC int gjmp(int t) | 944 | ST_FUNC int gjmp(TCCState* S, int t) |
| 951 | { | 945 | { |
| 952 | if (nocode_wanted) | 946 | if (S->tccgen_nocode_wanted) |
| 953 | return t; | 947 | return t; |
| 954 | o(t); | 948 | o(S, t); |
| 955 | return ind - 4; | 949 | return S->tccgen_ind - 4; |
| 956 | } | 950 | } |
| 957 | 951 | ||
| 958 | // Generate branch to known address: | 952 | // Generate branch to known address: |
| 959 | ST_FUNC void gjmp_addr(int a) | 953 | ST_FUNC void gjmp_addr(TCCState* S, int a) |
| 960 | { | 954 | { |
| 961 | uint32_t r = a - ind, imm; | 955 | uint32_t r = a - S->tccgen_ind, imm; |
| 962 | if ((r + (1 << 21)) & ~((1U << 22) - 2)) { | 956 | if ((r + (1 << 21)) & ~((1U << 22) - 2)) { |
| 963 | o(0x17 | (5 << 7) | (((r + 0x800) & 0xfffff000))); // lui RR, up(r) | 957 | o(S, 0x17 | (5 << 7) | (((r + 0x800) & 0xfffff000))); // lui RR, up(r) |
| 964 | r = (int)r << 20 >> 20; | 958 | r = (int)r << 20 >> 20; |
| 965 | EI(0x67, 0, 0, 5, r); // jalr x0, r(t0) | 959 | EI(S, 0x67, 0, 0, 5, r); // jalr x0, r(t0) |
| 966 | } else { | 960 | } else { |
| 967 | imm = (((r >> 12) & 0xff) << 12) | 961 | imm = (((r >> 12) & 0xff) << 12) |
| 968 | | (((r >> 11) & 1) << 20) | 962 | | (((r >> 11) & 1) << 20) |
| 969 | | (((r >> 1) & 0x3ff) << 21) | 963 | | (((r >> 1) & 0x3ff) << 21) |
| 970 | | (((r >> 20) & 1) << 31); | 964 | | (((r >> 20) & 1) << 31); |
| 971 | o(0x6f | imm); // jal x0, imm == j imm | 965 | o(S, 0x6f | imm); // jal x0, imm == j imm |
| 972 | } | 966 | } |
| 973 | } | 967 | } |
| 974 | 968 | ||
| 975 | ST_FUNC int gjmp_cond(int op, int t) | 969 | ST_FUNC int gjmp_cond(TCCState* S, int op, int t) |
| 976 | { | 970 | { |
| 977 | int tmp; | 971 | int tmp; |
| 978 | int a = vtop->cmp_r & 0xff; | 972 | int a = S->tccgen_vtop->cmp_r & 0xff; |
| 979 | int b = (vtop->cmp_r >> 8) & 0xff; | 973 | int b = (S->tccgen_vtop->cmp_r >> 8) & 0xff; |
| 980 | switch (op) { | 974 | switch (op) { |
| 981 | case TOK_ULT: op = 6; break; | 975 | case TOK_ULT: op = 6; break; |
| 982 | case TOK_UGE: op = 7; break; | 976 | case TOK_UGE: op = 7; break; |
| @@ -989,11 +983,11 @@ ST_FUNC int gjmp_cond(int op, int t) · 6 unmodified lines | |||
| 989 | case TOK_NE: op = 1; break; | 983 | case TOK_NE: op = 1; break; |
| 990 | case TOK_EQ: op = 0; break; | 984 | case TOK_EQ: op = 0; break; |
| 991 | } | 985 | } |
| 992 | o(0x63 | (op ^ 1) << 12 | a << 15 | b << 20 | 8 << 7); // bOP a,b,+4 | 986 | o(S, 0x63 | (op ^ 1) << 12 | a << 15 | b << 20 | 8 << 7); // bOP a,b,+4 |
| 993 | return gjmp(t); | 987 | return gjmp(S, t); |
| 994 | } | 988 | } |
| 995 | 989 | ||
| 996 | ST_FUNC int gjmp_append(int n, int t) | 990 | ST_FUNC int gjmp_append(TCCState* S, int n, int t) |
| 997 | { | 991 | { |
| 998 | void *p; | 992 | void *p; |
| 999 | /* insert jump list n into t */ | 993 | /* insert jump list n into t */ |
| @@ -1007,23 +1001,23 @@ ST_FUNC int gjmp_append(int n, int t) · 7 unmodified lines | |||
| 1007 | return t; | 1001 | return t; |
| 1008 | } | 1002 | } |
| 1009 | 1003 | ||
| 1010 | static void gen_opil(int op, int ll) | 1004 | static void gen_opil(TCCState* S, int op, int ll) |
| 1011 | { | 1005 | { |
| 1012 | int a, b, d; | 1006 | int a, b, d; |
| 1013 | int func3 = 0; | 1007 | int func3 = 0; |
| 1014 | ll = ll ? 0 : 8; | 1008 | ll = ll ? 0 : 8; |
| 1015 | if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { | 1009 | if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { |
| 1016 | int fc = vtop->c.i; | 1010 | int fc = S->tccgen_vtop->c.i; |
| 1017 | if (fc == vtop->c.i && !(((unsigned)fc + (1 << 11)) >> 12)) { | 1011 | if (fc == S->tccgen_vtop->c.i && !(((unsigned)fc + (1 << 11)) >> 12)) { |
| 1018 | int cll = 0; | 1012 | int cll = 0; |
| 1019 | int m = ll ? 31 : 63; | 1013 | int m = ll ? 31 : 63; |
| 1020 | vswap(); | 1014 | vswap(S); |
| 1021 | gv(RC_INT); | 1015 | gv(S, RC_INT); |
| 1022 | a = ireg(vtop[0].r); | 1016 | a = ireg(S->tccgen_vtop[0].r); |
| 1023 | --vtop; | 1017 | --S->tccgen_vtop; |
| 1024 | d = get_reg(RC_INT); | 1018 | d = get_reg(S, RC_INT); |
| 1025 | ++vtop; | 1019 | ++S->tccgen_vtop; |
| 1026 | vswap(); | 1020 | vswap(S); |
| 1027 | switch (op) { | 1021 | switch (op) { |
| 1028 | case '-': | 1022 | case '-': |
| 1029 | if (fc <= -(1 << 11)) | 1023 | if (fc <= -(1 << 11)) |
| @@ -1033,13 +1027,13 @@ static void gen_opil(int op, int ll) · 3 unmodified lines | |||
| 1033 | func3 = 0; // addi d, a, fc | 1027 | func3 = 0; // addi d, a, fc |
| 1034 | cll = ll; | 1028 | cll = ll; |
| 1035 | do_cop: | 1029 | do_cop: |
| 1036 | EI(0x13 | cll, func3, ireg(d), a, fc); | 1030 | EI(S, 0x13 | cll, func3, ireg(d), a, fc); |
| 1037 | --vtop; | 1031 | --S->tccgen_vtop; |
| 1038 | if (op >= TOK_ULT && op <= TOK_GT) { | 1032 | if (op >= TOK_ULT && op <= TOK_GT) { |
| 1039 | vset_VT_CMP(TOK_NE); | 1033 | vset_VT_CMP(S, TOK_NE); |
| 1040 | vtop->cmp_r = ireg(d) | 0 << 8; | 1034 | S->tccgen_vtop->cmp_r = ireg(d) | 0 << 8; |
| 1041 | } else | 1035 | } else |
| 1042 | vtop[0].r = d; | 1036 | S->tccgen_vtop[0].r = d; |
| 1043 | return; | 1037 | return; |
| 1044 | case TOK_LE: | 1038 | case TOK_LE: |
| 1045 | if (fc >= (1 << 11) - 1) | 1039 | if (fc >= (1 << 11) - 1) |
| @@ -1062,97 +1056,97 @@ static void gen_opil(int op, int ll) · 16 unmodified lines | |||
| 1062 | case TOK_UGT: /* -> TOK_ULE */ | 1056 | case TOK_UGT: /* -> TOK_ULE */ |
| 1063 | case TOK_GE: /* -> TOK_LT */ | 1057 | case TOK_GE: /* -> TOK_LT */ |
| 1064 | case TOK_GT: /* -> TOK_LE */ | 1058 | case TOK_GT: /* -> TOK_LE */ |
| 1065 | gen_opil(op - 1, !ll); | 1059 | gen_opil(S, op - 1, !ll); |
| 1066 | vtop->cmp_op ^= 1; | 1060 | S->tccgen_vtop->cmp_op ^= 1; |
| 1067 | return; | 1061 | return; |
| 1068 | 1062 | ||
| 1069 | case TOK_NE: | 1063 | case TOK_NE: |
| 1070 | case TOK_EQ: | 1064 | case TOK_EQ: |
| 1071 | if (fc) | 1065 | if (fc) |
| 1072 | gen_opil('-', !ll), a = ireg(vtop++->r); | 1066 | gen_opil(S, '-', !ll), a = ireg(S->tccgen_vtop++->r); |
| 1073 | --vtop; | 1067 | --S->tccgen_vtop; |
| 1074 | vset_VT_CMP(op); | 1068 | vset_VT_CMP(S, op); |
| 1075 | vtop->cmp_r = a | 0 << 8; | 1069 | S->tccgen_vtop->cmp_r = a | 0 << 8; |
| 1076 | return; | 1070 | return; |
| 1077 | } | 1071 | } |
| 1078 | } | 1072 | } |
| 1079 | } | 1073 | } |
| 1080 | gv2(RC_INT, RC_INT); | 1074 | gv2(S, RC_INT, RC_INT); |
| 1081 | a = ireg(vtop[-1].r); | 1075 | a = ireg(S->tccgen_vtop[-1].r); |
| 1082 | b = ireg(vtop[0].r); | 1076 | b = ireg(S->tccgen_vtop[0].r); |
| 1083 | vtop -= 2; | 1077 | S->tccgen_vtop -= 2; |
| 1084 | d = get_reg(RC_INT); | 1078 | d = get_reg(S, RC_INT); |
| 1085 | vtop++; | 1079 | S->tccgen_vtop++; |
| 1086 | vtop[0].r = d; | 1080 | S->tccgen_vtop[0].r = d; |
| 1087 | d = ireg(d); | 1081 | d = ireg(d); |
| 1088 | switch (op) { | 1082 | switch (op) { |
| 1089 | default: | 1083 | default: |
| 1090 | if (op >= TOK_ULT && op <= TOK_GT) { | 1084 | if (op >= TOK_ULT && op <= TOK_GT) { |
| 1091 | vset_VT_CMP(op); | 1085 | vset_VT_CMP(S, op); |
| 1092 | vtop->cmp_r = a | b << 8; | 1086 | S->tccgen_vtop->cmp_r = a | b << 8; |
| 1093 | break; | 1087 | break; |
| 1094 | } | 1088 | } |
| 1095 | tcc_error("implement me: %s(%s)", __FUNCTION__, get_tok_str(op, NULL)); | 1089 | tcc_error(S, "implement me: %s(%s)", __FUNCTION__, get_tok_str(S, op, NULL)); |
| 1096 | break; | 1090 | break; |
| 1097 | 1091 | ||
| 1098 | case '+': | 1092 | case '+': |
| 1099 | ER(0x33 | ll, 0, d, a, b, 0); // add d, a, b | 1093 | ER(S, 0x33 | ll, 0, d, a, b, 0); // add d, a, b |
| 1100 | break; | 1094 | break; |
| 1101 | case '-': | 1095 | case '-': |
| 1102 | ER(0x33 | ll, 0, d, a, b, 0x20); // sub d, a, b | 1096 | ER(S, 0x33 | ll, 0, d, a, b, 0x20); // sub d, a, b |
| 1103 | break; | 1097 | break; |
| 1104 | case TOK_SAR: | 1098 | case TOK_SAR: |
| 1105 | ER(0x33 | ll | ll, 5, d, a, b, 0x20); // sra d, a, b | 1099 | ER(S, 0x33 | ll | ll, 5, d, a, b, 0x20); // sra d, a, b |
| 1106 | break; | 1100 | break; |
| 1107 | case TOK_SHR: | 1101 | case TOK_SHR: |
| 1108 | ER(0x33 | ll | ll, 5, d, a, b, 0); // srl d, a, b | 1102 | ER(S, 0x33 | ll | ll, 5, d, a, b, 0); // srl d, a, b |
| 1109 | break; | 1103 | break; |
| 1110 | case TOK_SHL: | 1104 | case TOK_SHL: |
| 1111 | ER(0x33 | ll, 1, d, a, b, 0); // sll d, a, b | 1105 | ER(S, 0x33 | ll, 1, d, a, b, 0); // sll d, a, b |
| 1112 | break; | 1106 | break; |
| 1113 | case '*': | 1107 | case '*': |
| 1114 | ER(0x33 | ll, 0, d, a, b, 1); // mul d, a, b | 1108 | ER(S, 0x33 | ll, 0, d, a, b, 1); // mul d, a, b |
| 1115 | break; | 1109 | break; |
| 1116 | case '/': | 1110 | case '/': |
| 1117 | ER(0x33 | ll, 4, d, a, b, 1); // div d, a, b | 1111 | ER(S, 0x33 | ll, 4, d, a, b, 1); // div d, a, b |
| 1118 | break; | 1112 | break; |
| 1119 | case '&': | 1113 | case '&': |
| 1120 | ER(0x33, 7, d, a, b, 0); // and d, a, b | 1114 | ER(S, 0x33, 7, d, a, b, 0); // and d, a, b |
| 1121 | break; | 1115 | break; |
| 1122 | case '^': | 1116 | case '^': |
| 1123 | ER(0x33, 4, d, a, b, 0); // xor d, a, b | 1117 | ER(S, 0x33, 4, d, a, b, 0); // xor d, a, b |
| 1124 | break; | 1118 | break; |
| 1125 | case '|': | 1119 | case '|': |
| 1126 | ER(0x33, 6, d, a, b, 0); // or d, a, b | 1120 | ER(S, 0x33, 6, d, a, b, 0); // or d, a, b |
| 1127 | break; | 1121 | break; |
| 1128 | case '%': | 1122 | case '%': |
| 1129 | ER(ll ? 0x3b: 0x33, 6, d, a, b, 1); // rem d, a, b | 1123 | ER(S, ll ? 0x3b: 0x33, 6, d, a, b, 1); // rem d, a, b |
| 1130 | break; | 1124 | break; |
| 1131 | case TOK_UMOD: | 1125 | case TOK_UMOD: |
| 1132 | ER(0x33 | ll, 7, d, a, b, 1); // remu d, a, b | 1126 | ER(S, 0x33 | ll, 7, d, a, b, 1); // remu d, a, b |
| 1133 | break; | 1127 | break; |
| 1134 | case TOK_PDIV: | 1128 | case TOK_PDIV: |
| 1135 | case TOK_UDIV: | 1129 | case TOK_UDIV: |
| 1136 | ER(0x33 | ll, 5, d, a, b, 1); // divu d, a, b | 1130 | ER(S, 0x33 | ll, 5, d, a, b, 1); // divu d, a, b |
| 1137 | break; | 1131 | break; |
| 1138 | } | 1132 | } |
| 1139 | } | 1133 | } |
| 1140 | 1134 | ||
| 1141 | ST_FUNC void gen_opi(int op) | 1135 | ST_FUNC void gen_opi(TCCState* S, int op) |
| 1142 | { | 1136 | { |
| 1143 | gen_opil(op, 0); | 1137 | gen_opil(S, op, 0); |
| 1144 | } | 1138 | } |
| 1145 | 1139 | ||
| 1146 | ST_FUNC void gen_opl(int op) | 1140 | ST_FUNC void gen_opl(TCCState* S, int op) |
| 1147 | { | 1141 | { |
| 1148 | gen_opil(op, 1); | 1142 | gen_opil(S, op, 1); |
| 1149 | } | 1143 | } |
| 1150 | 1144 | ||
| 1151 | ST_FUNC void gen_opf(int op) | 1145 | ST_FUNC void gen_opf(TCCState* S, int op) |
| 1152 | { | 1146 | { |
| 1153 | int rs1, rs2, rd, dbl, invert; | 1147 | int rs1, rs2, rd, dbl, invert; |
| 1154 | if (vtop[0].type.t == VT_LDOUBLE) { | 1148 | if (S->tccgen_vtop[0].type.t == VT_LDOUBLE) { |
| 1155 | CType type = vtop[0].type; | 1149 | CType type = S->tccgen_vtop[0].type; |
| 1156 | int func = 0; | 1150 | int func = 0; |
| 1157 | int cond = -1; | 1151 | int cond = -1; |
| 1158 | switch (op) { | 1152 | switch (op) { |
| @@ -1168,27 +1162,27 @@ ST_FUNC void gen_opf(int op) · 9 unmodified lines | |||
| 1168 | case TOK_GT: func = TOK___gttf2; cond = 13; break; | 1162 | case TOK_GT: func = TOK___gttf2; cond = 13; break; |
| 1169 | default: assert(0); break; | 1163 | default: assert(0); break; |
| 1170 | } | 1164 | } |
| 1171 | vpush_helper_func(func); | 1165 | vpush_helper_func(S, func); |
| 1172 | vrott(3); | 1166 | vrott(S, 3); |
| 1173 | gfunc_call(2); | 1167 | gfunc_call(S, 2); |
| 1174 | vpushi(0); | 1168 | vpushi(S, 0); |
| 1175 | vtop->r = REG_IRET; | 1169 | S->tccgen_vtop->r = REG_IRET; |
| 1176 | vtop->r2 = cond < 0 ? TREG_R(1) : VT_CONST; | 1170 | S->tccgen_vtop->r2 = cond < 0 ? TREG_R(1) : VT_CONST; |
| 1177 | if (cond < 0) | 1171 | if (cond < 0) |
| 1178 | vtop->type = type; | 1172 | S->tccgen_vtop->type = type; |
| 1179 | else { | 1173 | else { |
| 1180 | vpushi(0); | 1174 | vpushi(S, 0); |
| 1181 | gen_opil(op, 1); | 1175 | gen_opil(S, op, 1); |
| 1182 | } | 1176 | } |
| 1183 | return; | 1177 | return; |
| 1184 | } | 1178 | } |
| 1185 | 1179 | ||
| 1186 | gv2(RC_FLOAT, RC_FLOAT); | 1180 | gv2(S, RC_FLOAT, RC_FLOAT); |
| 1187 | assert(vtop->type.t == VT_DOUBLE || vtop->type.t == VT_FLOAT); | 1181 | assert(S->tccgen_vtop->type.t == VT_DOUBLE || S->tccgen_vtop->type.t == VT_FLOAT); |
| 1188 | dbl = vtop->type.t == VT_DOUBLE; | 1182 | dbl = S->tccgen_vtop->type.t == VT_DOUBLE; |
| 1189 | rs1 = freg(vtop[-1].r); | 1183 | rs1 = freg(S->tccgen_vtop[-1].r); |
| 1190 | rs2 = freg(vtop->r); | 1184 | rs2 = freg(S->tccgen_vtop->r); |
| 1191 | vtop--; | 1185 | S->tccgen_vtop--; |
| 1192 | invert = 0; | 1186 | invert = 0; |
| 1193 | switch(op) { | 1187 | switch(op) { |
| 1194 | default: | 1188 | default: |
| @@ -1196,10 +1190,10 @@ ST_FUNC void gen_opf(int op) · 1 unmodified line | |||
| 1196 | case '+': | 1190 | case '+': |
| 1197 | op = 0; // fadd | 1191 | op = 0; // fadd |
| 1198 | arithop: | 1192 | arithop: |
| 1199 | rd = get_reg(RC_FLOAT); | 1193 | rd = get_reg(S, RC_FLOAT); |
| 1200 | vtop->r = rd; | 1194 | S->tccgen_vtop->r = rd; |
| 1201 | rd = freg(rd); | 1195 | rd = freg(rd); |
| 1202 | ER(0x53, 7, rd, rs1, rs2, dbl | (op << 2)); // fop.[sd] RD, RS1, RS2 (dyn rm) | 1196 | ER(S, 0x53, 7, rd, rs1, rs2, dbl | (op << 2)); // fop.[sd] RD, RS1, RS2 (dyn rm) |
| 1203 | break; | 1197 | break; |
| 1204 | case '-': | 1198 | case '-': |
| 1205 | op = 1; // fsub | 1199 | op = 1; // fsub |
| @@ -1213,12 +1207,12 @@ ST_FUNC void gen_opf(int op) · 7 unmodified lines | |||
| 1213 | case TOK_EQ: | 1207 | case TOK_EQ: |
| 1214 | op = 2; // EQ | 1208 | op = 2; // EQ |
| 1215 | cmpop: | 1209 | cmpop: |
| 1216 | rd = get_reg(RC_INT); | 1210 | rd = get_reg(S, RC_INT); |
| 1217 | vtop->r = rd; | 1211 | S->tccgen_vtop->r = rd; |
| 1218 | rd = ireg(rd); | 1212 | rd = ireg(rd); |
| 1219 | ER(0x53, op, rd, rs1, rs2, dbl | 0x50); // fcmp.[sd] RD, RS1, RS2 (op == eq/lt/le) | 1213 | ER(S, 0x53, op, rd, rs1, rs2, dbl | 0x50); // fcmp.[sd] RD, RS1, RS2 (op == eq/lt/le) |
| 1220 | if (invert) | 1214 | if (invert) |
| 1221 | EI(0x13, 4, rd, rd, 1); // xori RD, 1 | 1215 | EI(S, 0x13, 4, rd, rd, 1); // xori RD, 1 |
| 1222 | break; | 1216 | break; |
| 1223 | case TOK_NE: | 1217 | case TOK_NE: |
| 1224 | invert = 1; | 1218 | invert = 1; |
| @@ -1241,67 +1235,67 @@ ST_FUNC void gen_opf(int op) · 16 unmodified lines | |||
| 1241 | } | 1235 | } |
| 1242 | } | 1236 | } |
| 1243 | 1237 | ||
| 1244 | ST_FUNC void gen_cvt_sxtw(void) | 1238 | ST_FUNC void gen_cvt_sxtw(TCCState *S) |
| 1245 | { | 1239 | { |
| 1246 | /* XXX on risc-v the registers are usually sign-extended already. | 1240 | /* XXX on risc-v the registers are usually sign-extended already. |
| 1247 | Let's try to not do anything here. */ | 1241 | Let's try to not do anything here. */ |
| 1248 | } | 1242 | } |
| 1249 | 1243 | ||
| 1250 | ST_FUNC void gen_cvt_itof(int t) | 1244 | ST_FUNC void gen_cvt_itof(TCCState* S, int t) |
| 1251 | { | 1245 | { |
| 1252 | int rr = ireg(gv(RC_INT)), dr; | 1246 | int rr = ireg(gv(S, RC_INT)), dr; |
| 1253 | int u = vtop->type.t & VT_UNSIGNED; | 1247 | int u = S->tccgen_vtop->type.t & VT_UNSIGNED; |
| 1254 | int l = (vtop->type.t & VT_BTYPE) == VT_LLONG; | 1248 | int l = (S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG; |
| 1255 | if (t == VT_LDOUBLE) { | 1249 | if (t == VT_LDOUBLE) { |
| 1256 | int func = l ? | 1250 | int func = l ? |
| 1257 | (u ? TOK___floatunditf : TOK___floatditf) : | 1251 | (u ? TOK___floatunditf : TOK___floatditf) : |
| 1258 | (u ? TOK___floatunsitf : TOK___floatsitf); | 1252 | (u ? TOK___floatunsitf : TOK___floatsitf); |
| 1259 | vpush_helper_func(func); | 1253 | vpush_helper_func(S, func); |
| 1260 | vrott(2); | 1254 | vrott(S, 2); |
| 1261 | gfunc_call(1); | 1255 | gfunc_call(S, 1); |
| 1262 | vpushi(0); | 1256 | vpushi(S, 0); |
| 1263 | vtop->type.t = t; | 1257 | S->tccgen_vtop->type.t = t; |
| 1264 | vtop->r = REG_IRET; | 1258 | S->tccgen_vtop->r = REG_IRET; |
| 1265 | vtop->r2 = TREG_R(1); | 1259 | S->tccgen_vtop->r2 = TREG_R(1); |
| 1266 | } else { | 1260 | } else { |
| 1267 | vtop--; | 1261 | S->tccgen_vtop--; |
| 1268 | dr = get_reg(RC_FLOAT); | 1262 | dr = get_reg(S, RC_FLOAT); |
| 1269 | vtop++; | 1263 | S->tccgen_vtop++; |
| 1270 | vtop->r = dr; | 1264 | S->tccgen_vtop->r = dr; |
| 1271 | dr = freg(dr); | 1265 | dr = freg(dr); |
| 1272 | EIu(0x53, 7, dr, rr, ((0x68 | (t == VT_DOUBLE ? 1 : 0)) << 5) | (u ? 1 : 0) | (l ? 2 : 0)); // fcvt.[sd].[wl][u] | 1266 | EIu(S, 0x53, 7, dr, rr, ((0x68 | (t == VT_DOUBLE ? 1 : 0)) << 5) | (u ? 1 : 0) | (l ? 2 : 0)); // fcvt.[sd].[wl][u] |
| 1273 | } | 1267 | } |
| 1274 | } | 1268 | } |
| 1275 | 1269 | ||
| 1276 | ST_FUNC void gen_cvt_ftoi(int t) | 1270 | ST_FUNC void gen_cvt_ftoi(TCCState* S, int t) |
| 1277 | { | 1271 | { |
| 1278 | int ft = vtop->type.t & VT_BTYPE; | 1272 | int ft = S->tccgen_vtop->type.t & VT_BTYPE; |
| 1279 | int l = (t & VT_BTYPE) == VT_LLONG; | 1273 | int l = (t & VT_BTYPE) == VT_LLONG; |
| 1280 | int u = t & VT_UNSIGNED; | 1274 | int u = t & VT_UNSIGNED; |
| 1281 | if (ft == VT_LDOUBLE) { | 1275 | if (ft == VT_LDOUBLE) { |
| 1282 | int func = l ? | 1276 | int func = l ? |
| 1283 | (u ? TOK___fixunstfdi : TOK___fixtfdi) : | 1277 | (u ? TOK___fixunstfdi : TOK___fixtfdi) : |
| 1284 | (u ? TOK___fixunstfsi : TOK___fixtfsi); | 1278 | (u ? TOK___fixunstfsi : TOK___fixtfsi); |
| 1285 | vpush_helper_func(func); | 1279 | vpush_helper_func(S, func); |
| 1286 | vrott(2); | 1280 | vrott(S, 2); |
| 1287 | gfunc_call(1); | 1281 | gfunc_call(S, 1); |
| 1288 | vpushi(0); | 1282 | vpushi(S, 0); |
| 1289 | vtop->type.t = t; | 1283 | S->tccgen_vtop->type.t = t; |
| 1290 | vtop->r = REG_IRET; | 1284 | S->tccgen_vtop->r = REG_IRET; |
| 1291 | } else { | 1285 | } else { |
| 1292 | int rr = freg(gv(RC_FLOAT)), dr; | 1286 | int rr = freg(gv(S, RC_FLOAT)), dr; |
| 1293 | vtop--; | 1287 | S->tccgen_vtop--; |
| 1294 | dr = get_reg(RC_INT); | 1288 | dr = get_reg(S, RC_INT); |
| 1295 | vtop++; | 1289 | S->tccgen_vtop++; |
| 1296 | vtop->r = dr; | 1290 | S->tccgen_vtop->r = dr; |
| 1297 | dr = ireg(dr); | 1291 | dr = ireg(dr); |
| 1298 | EIu(0x53, 1, dr, rr, ((0x60 | (ft == VT_DOUBLE ? 1 : 0)) << 5) | (u ? 1 : 0) | (l ? 2 : 0)); // fcvt.[wl][u].[sd] rtz | 1292 | EIu(S, 0x53, 1, dr, rr, ((0x60 | (ft == VT_DOUBLE ? 1 : 0)) << 5) | (u ? 1 : 0) | (l ? 2 : 0)); // fcvt.[wl][u].[sd] rtz |
| 1299 | } | 1293 | } |
| 1300 | } | 1294 | } |
| 1301 | 1295 | ||
| 1302 | ST_FUNC void gen_cvt_ftof(int dt) | 1296 | ST_FUNC void gen_cvt_ftof(TCCState* S, int dt) |
| 1303 | { | 1297 | { |
| 1304 | int st = vtop->type.t & VT_BTYPE, rs, rd; | 1298 | int st = S->tccgen_vtop->type.t & VT_BTYPE, rs, rd; |
| 1305 | dt &= VT_BTYPE; | 1299 | dt &= VT_BTYPE; |
| 1306 | if (st == dt) | 1300 | if (st == dt) |
| 1307 | return; | 1301 | return; |
| @@ -1313,109 +1307,109 @@ ST_FUNC void gen_cvt_ftof(int dt) · 5 unmodified lines | |||
| 1313 | functions, and on riscv unnamed float args are passed like | 1307 | functions, and on riscv unnamed float args are passed like |
| 1314 | integers. But we really need them in the float argument registers | 1308 | integers. But we really need them in the float argument registers |
| 1315 | for extendsftf2/extenddftf2. So, do it explicitely. */ | 1309 | for extendsftf2/extenddftf2. So, do it explicitely. */ |
| 1316 | save_regs(1); | 1310 | save_regs(S, 1); |
| 1317 | if (dt == VT_LDOUBLE) | 1311 | if (dt == VT_LDOUBLE) |
| 1318 | gv(RC_F(0)); | 1312 | gv(S, RC_F(0)); |
| 1319 | else { | 1313 | else { |
| 1320 | gv(RC_R(0)); | 1314 | gv(S, RC_R(0)); |
| 1321 | assert(vtop->r2 < 7); | 1315 | assert(S->tccgen_vtop->r2 < 7); |
| 1322 | if (vtop->r2 != 1 + vtop->r) { | 1316 | if (S->tccgen_vtop->r2 != 1 + S->tccgen_vtop->r) { |
| 1323 | EI(0x13, 0, ireg(vtop->r) + 1, ireg(vtop->r2), 0); // mv Ra+1, RR2 | 1317 | EI(S, 0x13, 0, ireg(S->tccgen_vtop->r) + 1, ireg(S->tccgen_vtop->r2), 0); // mv Ra+1, RR2 |
| 1324 | vtop->r2 = 1 + vtop->r; | 1318 | S->tccgen_vtop->r2 = 1 + S->tccgen_vtop->r; |
| 1325 | } | 1319 | } |
| 1326 | } | 1320 | } |
| 1327 | vpush_helper_func(func); | 1321 | vpush_helper_func(S, func); |
| 1328 | gcall_or_jmp(1); | 1322 | gcall_or_jmp(S, 1); |
| 1329 | vtop -= 2; | 1323 | S->tccgen_vtop -= 2; |
| 1330 | vpushi(0); | 1324 | vpushi(S, 0); |
| 1331 | vtop->type.t = dt; | 1325 | S->tccgen_vtop->type.t = dt; |
| 1332 | if (dt == VT_LDOUBLE) | 1326 | if (dt == VT_LDOUBLE) |
| 1333 | vtop->r = REG_IRET, vtop->r2 = REG_IRET+1; | 1327 | S->tccgen_vtop->r = REG_IRET, S->tccgen_vtop->r2 = REG_IRET+1; |
| 1334 | else | 1328 | else |
| 1335 | vtop->r = REG_FRET; | 1329 | S->tccgen_vtop->r = REG_FRET; |
| 1336 | } else { | 1330 | } else { |
| 1337 | assert (dt == VT_FLOAT || dt == VT_DOUBLE); | 1331 | assert (dt == VT_FLOAT || dt == VT_DOUBLE); |
| 1338 | assert (st == VT_FLOAT || st == VT_DOUBLE); | 1332 | assert (st == VT_FLOAT || st == VT_DOUBLE); |
| 1339 | rs = gv(RC_FLOAT); | 1333 | rs = gv(S, RC_FLOAT); |
| 1340 | rd = get_reg(RC_FLOAT); | 1334 | rd = get_reg(S, RC_FLOAT); |
| 1341 | if (dt == VT_DOUBLE) | 1335 | if (dt == VT_DOUBLE) |
| 1342 | EI(0x53, 0, freg(rd), freg(rs), 0x21 << 5); // fcvt.d.s RD, RS (no rm) | 1336 | EI(S, 0x53, 0, freg(rd), freg(rs), 0x21 << 5); // fcvt.d.s RD, RS (no rm) |
| 1343 | else | 1337 | else |
| 1344 | EI(0x53, 7, freg(rd), freg(rs), (0x20 << 5) | 1); // fcvt.s.d RD, RS (dyn rm) | 1338 | EI(S, 0x53, 7, freg(rd), freg(rs), (0x20 << 5) | 1); // fcvt.s.d RD, RS (dyn rm) |
| 1345 | vtop->r = rd; | 1339 | S->tccgen_vtop->r = rd; |
| 1346 | } | 1340 | } |
| 1347 | } | 1341 | } |
| 1348 | 1342 | ||
| 1349 | /* increment tcov counter */ | 1343 | /* increment tcov counter */ |
| 1350 | ST_FUNC void gen_increment_tcov (SValue *sv) | 1344 | ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv) |
| 1351 | { | 1345 | { |
| 1352 | int r1, r2; | 1346 | int r1, r2; |
| 1353 | Sym label = {0}; | 1347 | Sym label = {0}; |
| 1354 | label.type.t = VT_VOID | VT_STATIC; | 1348 | label.type.t = VT_VOID | VT_STATIC; |
| 1355 | 1349 | ||
| 1356 | vpushv(sv); | 1350 | vpushv(S, sv); |
| 1357 | vtop->r = r1 = get_reg(RC_INT); | 1351 | S->tccgen_vtop->r = r1 = get_reg(S, RC_INT); |
| 1358 | r2 = get_reg(RC_INT); | 1352 | r2 = get_reg(S, RC_INT); |
| 1359 | r1 = ireg(r1); | 1353 | r1 = ireg(r1); |
| 1360 | r2 = ireg(r2); | 1354 | r2 = ireg(r2); |
| 1361 | greloca(cur_text_section, sv->sym, ind, R_RISCV_PCREL_HI20, 0); | 1355 | greloca(S, cur_text_section, sv->sym, S->tccgen_ind, R_RISCV_PCREL_HI20, 0); |
| 1362 | put_extern_sym(&label, cur_text_section, ind, 0); | 1356 | put_extern_sym(S, &label, cur_text_section, S->tccgen_ind, 0); |
| 1363 | o(0x17 | (r1 << 7)); // auipc RR, 0 %pcrel_hi(sym) | 1357 | o(S, 0x17 | (r1 << 7)); // auipc RR, 0 %pcrel_hi(sym) |
| 1364 | greloca(cur_text_section, &label, ind, R_RISCV_PCREL_LO12_I, 0); | 1358 | greloca(S, cur_text_section, &label, S->tccgen_ind, R_RISCV_PCREL_LO12_I, 0); |
| 1365 | EI(0x03, 3, r2, r1, 0); // ld r2, x[r1] | 1359 | EI(S, 0x03, 3, r2, r1, 0); // ld r2, x[r1] |
| 1366 | EI(0x13, 0, r2, r2, 1); // addi r2, r2, #1 | 1360 | EI(S, 0x13, 0, r2, r2, 1); // addi r2, r2, #1 |
| 1367 | greloca(cur_text_section, sv->sym, ind, R_RISCV_PCREL_HI20, 0); | 1361 | greloca(S, cur_text_section, sv->sym, S->tccgen_ind, R_RISCV_PCREL_HI20, 0); |
| 1368 | label.c = 0; /* force new local ELF symbol */ | 1362 | label.c = 0; /* force new local ELF symbol */ |
| 1369 | put_extern_sym(&label, cur_text_section, ind, 0); | 1363 | put_extern_sym(S, &label, cur_text_section, S->tccgen_ind, 0); |
| 1370 | o(0x17 | (r1 << 7)); // auipc RR, 0 %pcrel_hi(sym) | 1364 | o(S, 0x17 | (r1 << 7)); // auipc RR, 0 %pcrel_hi(sym) |
| 1371 | greloca(cur_text_section, &label, ind, R_RISCV_PCREL_LO12_S, 0); | 1365 | greloca(S, cur_text_section, &label, S->tccgen_ind, R_RISCV_PCREL_LO12_S, 0); |
| 1372 | ES(0x23, 3, r1, r2, 0); // sd r2, [r1] | 1366 | ES(S, 0x23, 3, r1, r2, 0); // sd r2, [r1] |
| 1373 | vpop(); | 1367 | vpop(S); |
| 1374 | } | 1368 | } |
| 1375 | 1369 | ||
| 1376 | ST_FUNC void ggoto(void) | 1370 | ST_FUNC void ggoto(TCCState* S) |
| 1377 | { | 1371 | { |
| 1378 | gcall_or_jmp(0); | 1372 | gcall_or_jmp(S, 0); |
| 1379 | vtop--; | 1373 | S->tccgen_vtop--; |
| 1380 | } | 1374 | } |
| 1381 | 1375 | ||
| 1382 | ST_FUNC void gen_vla_sp_save(int addr) | 1376 | ST_FUNC void gen_vla_sp_save(TCCState* S, int addr) |
| 1383 | { | 1377 | { |
| 1384 | ES(0x23, 3, 8, 2, addr); // sd sp, fc(s0) | 1378 | ES(S, 0x23, 3, 8, 2, addr); // sd sp, fc(s0) |
| 1385 | } | 1379 | } |
| 1386 | 1380 | ||
| 1387 | ST_FUNC void gen_vla_sp_restore(int addr) | 1381 | ST_FUNC void gen_vla_sp_restore(TCCState* S, int addr) |
| 1388 | { | 1382 | { |
| 1389 | EI(0x03, 3, 2, 8, addr); // ld sp, fc(s0) | 1383 | EI(S, 0x03, 3, 2, 8, addr); // ld sp, fc(s0) |
| 1390 | } | 1384 | } |
| 1391 | 1385 | ||
| 1392 | ST_FUNC void gen_vla_alloc(CType *type, int align) | 1386 | ST_FUNC void gen_vla_alloc(TCCState* S, CType *type, int align) |
| 1393 | { | 1387 | { |
| 1394 | int rr; | 1388 | int rr; |
| 1395 | #if defined(CONFIG_TCC_BCHECK) | 1389 | #if defined(CONFIG_TCC_BCHECK) |
| 1396 | if (tcc_state->do_bounds_check) | 1390 | if (S->do_bounds_check) |
| 1397 | vpushv(vtop); | 1391 | vpushv(S, S->tccgen_vtop); |
| 1398 | #endif | 1392 | #endif |
| 1399 | rr = ireg(gv(RC_INT)); | 1393 | rr = ireg(gv(S, RC_INT)); |
| 1400 | #if defined(CONFIG_TCC_BCHECK) | 1394 | #if defined(CONFIG_TCC_BCHECK) |
| 1401 | if (tcc_state->do_bounds_check) | 1395 | if (S->do_bounds_check) |
| 1402 | EI(0x13, 0, rr, rr, 15+1); // addi RR, RR, 15+1 | 1396 | EI(S, 0x13, 0, rr, rr, 15+1); // addi RR, RR, 15+1 |
| 1403 | else | 1397 | else |
| 1404 | #endif | 1398 | #endif |
| 1405 | EI(0x13, 0, rr, rr, 15); // addi RR, RR, 15 | 1399 | EI(S, 0x13, 0, rr, rr, 15); // addi RR, RR, 15 |
| 1406 | EI(0x13, 7, rr, rr, -16); // andi, RR, RR, -16 | 1400 | EI(S, 0x13, 7, rr, rr, -16); // andi, RR, RR, -16 |
| 1407 | ER(0x33, 0, 2, 2, rr, 0x20); // sub sp, sp, rr | 1401 | ER(S, 0x33, 0, 2, 2, rr, 0x20); // sub sp, sp, rr |
| 1408 | vpop(); | 1402 | vpop(S); |
| 1409 | #if defined(CONFIG_TCC_BCHECK) | 1403 | #if defined(CONFIG_TCC_BCHECK) |
| 1410 | if (tcc_state->do_bounds_check) { | 1404 | if (S->do_bounds_check) { |
| 1411 | vpushi(0); | 1405 | vpushi(S, 0); |
| 1412 | vtop->r = TREG_R(0); | 1406 | S->tccgen_vtop->r = TREG_R(0); |
| 1413 | o(0x00010513); /* mv a0,sp */ | 1407 | o(S, 0x00010513); /* mv a0,sp */ |
| 1414 | vswap(); | 1408 | vswap(S); |
| 1415 | vpush_helper_func(TOK___bound_new_region); | 1409 | vpush_helper_func(S, TOK___bound_new_region); |
| 1416 | vrott(3); | 1410 | vrott(S, 3); |
| 1417 | gfunc_call(2); | 1411 | gfunc_call(S, 2); |
| 1418 | func_bound_add_epilog = 1; | 1412 | S->func_bound_add_epilog = 1; |
| 1419 | } | 1413 | } |
| 1420 | #endif | 1414 | #endif |
| 1421 | } | 1415 | } |
| @@ -95,39 +95,39 @@ int gotplt_entry_type (int reloc_type) · 94 unmodified lines | |||
| 95 | return -1; | 95 | return -1; |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr) | 98 | ST_FUNC unsigned create_plt_entry(TCCState *S, unsigned got_offset, struct sym_attr *attr) |
| 99 | { | 99 | { |
| 100 | Section *plt = s1->plt; | 100 | Section *plt = S->plt; |
| 101 | uint8_t *p; | 101 | uint8_t *p; |
| 102 | unsigned plt_offset; | 102 | unsigned plt_offset; |
| 103 | 103 | ||
| 104 | if (plt->data_offset == 0) | 104 | if (plt->data_offset == 0) |
| 105 | section_ptr_add(plt, 32); | 105 | section_ptr_add(S, plt, 32); |
| 106 | plt_offset = plt->data_offset; | 106 | plt_offset = plt->data_offset; |
| 107 | 107 | ||
| 108 | p = section_ptr_add(plt, 16); | 108 | p = section_ptr_add(S, plt, 16); |
| 109 | write64le(p, got_offset); | 109 | write64le(p, got_offset); |
| 110 | return plt_offset; | 110 | return plt_offset; |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | /* relocate the PLT: compute addresses and offsets in the PLT now that final | 113 | /* relocate the PLT: compute addresses and offsets in the PLT now that final |
| 114 | address for PLT and GOT are known (see fill_program_header) */ | 114 | address for PLT and GOT are known (see fill_program_header) */ |
| 115 | ST_FUNC void relocate_plt(TCCState *s1) | 115 | ST_FUNC void relocate_plt(TCCState *S) |
| 116 | { | 116 | { |
| 117 | uint8_t *p, *p_end; | 117 | uint8_t *p, *p_end; |
| 118 | 118 | ||
| 119 | if (!s1->plt) | 119 | if (!S->plt) |
| 120 | return; | 120 | return; |
| 121 | 121 | ||
| 122 | p = s1->plt->data; | 122 | p = S->plt->data; |
| 123 | p_end = p + s1->plt->data_offset; | 123 | p_end = p + S->plt->data_offset; |
| 124 | 124 | ||
| 125 | if (p < p_end) { | 125 | if (p < p_end) { |
| 126 | uint64_t plt = s1->plt->sh_addr; | 126 | uint64_t plt = S->plt->sh_addr; |
| 127 | uint64_t got = s1->got->sh_addr; | 127 | uint64_t got = S->got->sh_addr; |
| 128 | uint64_t off = (got - plt + 0x800) >> 12; | 128 | uint64_t off = (got - plt + 0x800) >> 12; |
| 129 | if ((off + ((uint32_t)1 << 20)) >> 21) | 129 | if ((off + ((uint32_t)1 << 20)) >> 21) |
| 130 | tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt); | 130 | tcc_error(S, "Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt); |
| 131 | write32le(p, 0x397 | (off << 12)); // auipc t2, %pcrel_hi(got) | 131 | write32le(p, 0x397 | (off << 12)); // auipc t2, %pcrel_hi(got) |
| 132 | write32le(p + 4, 0x41c30333); // sub t1, t1, t3 | 132 | write32le(p + 4, 0x41c30333); // sub t1, t1, t3 |
| 133 | write32le(p + 8, 0x0003be03 // ld t3, %pcrel_lo(got)(t2) | 133 | write32le(p + 8, 0x0003be03 // ld t3, %pcrel_lo(got)(t2) |
| @@ -140,11 +140,11 @@ ST_FUNC void relocate_plt(TCCState *s1) · 6 unmodified lines | |||
| 140 | write32le(p + 28, 0x000e0067); // jr t3 | 140 | write32le(p + 28, 0x000e0067); // jr t3 |
| 141 | p += 32; | 141 | p += 32; |
| 142 | while (p < p_end) { | 142 | while (p < p_end) { |
| 143 | uint64_t pc = plt + (p - s1->plt->data); | 143 | uint64_t pc = plt + (p - S->plt->data); |
| 144 | uint64_t addr = got + read64le(p); | 144 | uint64_t addr = got + read64le(p); |
| 145 | uint64_t off = (addr - pc + 0x800) >> 12; | 145 | uint64_t off = (addr - pc + 0x800) >> 12; |
| 146 | if ((off + ((uint32_t)1 << 20)) >> 21) | 146 | if ((off + ((uint32_t)1 << 20)) >> 21) |
| 147 | tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc); | 147 | tcc_error(S, "Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc); |
| 148 | write32le(p, 0xe17 | (off << 12)); // auipc t3, %pcrel_hi(func@got) | 148 | write32le(p, 0xe17 | (off << 12)); // auipc t3, %pcrel_hi(func@got) |
| 149 | write32le(p + 4, 0x000e3e03 // ld t3, %pcrel_lo(func@got)(t3) | 149 | write32le(p + 4, 0x000e3e03 // ld t3, %pcrel_lo(func@got)(t3) |
| 150 | | (((addr - pc) & 0xfff) << 20)); | 150 | | (((addr - pc) & 0xfff) << 20)); |
| @@ -154,16 +154,16 @@ ST_FUNC void relocate_plt(TCCState *s1) · 3 unmodified lines | |||
| 154 | } | 154 | } |
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | if (s1->plt->reloc) { | 157 | if (S->plt->reloc) { |
| 158 | ElfW_Rel *rel; | 158 | ElfW_Rel *rel; |
| 159 | p = s1->got->data; | 159 | p = S->got->data; |
| 160 | for_each_elem(s1->plt->reloc, 0, rel, ElfW_Rel) { | 160 | for_each_elem(S->plt->reloc, 0, rel, ElfW_Rel) { |
| 161 | write64le(p + rel->r_offset, s1->plt->sh_addr); | 161 | write64le(p + rel->r_offset, S->plt->sh_addr); |
| 162 | } | 162 | } |
| 163 | } | 163 | } |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, | 166 | void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, |
| 167 | addr_t addr, addr_t val) | 167 | addr_t addr, addr_t val) |
| 168 | { | 168 | { |
| 169 | uint64_t off64; | 169 | uint64_t off64; |
| @@ -179,7 +179,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 9 unmodified lines | |||
| 179 | case R_RISCV_BRANCH: | 179 | case R_RISCV_BRANCH: |
| 180 | off64 = val - addr; | 180 | off64 = val - addr; |
| 181 | if ((off64 + (1 << 12)) & ~(uint64_t)0x1ffe) | 181 | if ((off64 + (1 << 12)) & ~(uint64_t)0x1ffe) |
| 182 | tcc_error("R_RISCV_BRANCH relocation failed" | 182 | tcc_error(S, "R_RISCV_BRANCH relocation failed" |
| 183 | " (val=%lx, addr=%lx)", (long)val, (long)addr); | 183 | " (val=%lx, addr=%lx)", (long)val, (long)addr); |
| 184 | off32 = off64 >> 1; | 184 | off32 = off64 >> 1; |
| 185 | write32le(ptr, (read32le(ptr) & ~0xfe000f80) | 185 | write32le(ptr, (read32le(ptr) & ~0xfe000f80) |
| @@ -191,7 +191,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 5 unmodified lines | |||
| 191 | case R_RISCV_JAL: | 191 | case R_RISCV_JAL: |
| 192 | off64 = val - addr; | 192 | off64 = val - addr; |
| 193 | if ((off64 + (1 << 21)) & ~(((uint64_t)1 << 22) - 2)) | 193 | if ((off64 + (1 << 21)) & ~(((uint64_t)1 << 22) - 2)) |
| 194 | tcc_error("R_RISCV_JAL relocation failed" | 194 | tcc_error(S, "R_RISCV_JAL relocation failed" |
| 195 | " (val=%lx, addr=%lx)", (long)val, (long)addr); | 195 | " (val=%lx, addr=%lx)", (long)val, (long)addr); |
| 196 | off32 = off64; | 196 | off32 = off64; |
| 197 | write32le(ptr, (read32le(ptr) & 0xfff) | 197 | write32le(ptr, (read32le(ptr) & 0xfff) |
| @@ -213,7 +213,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 15 unmodified lines | |||
| 213 | #endif | 213 | #endif |
| 214 | off64 = (int64_t)(val - addr + 0x800) >> 12; | 214 | off64 = (int64_t)(val - addr + 0x800) >> 12; |
| 215 | if ((off64 + ((uint64_t)1 << 20)) >> 21) | 215 | if ((off64 + ((uint64_t)1 << 20)) >> 21) |
| 216 | tcc_error("R_RISCV_PCREL_HI20 relocation failed: off=%lx cond=%lx sym=%s", | 216 | tcc_error(S, "R_RISCV_PCREL_HI20 relocation failed: off=%lx cond=%lx sym=%s", |
| 217 | (long)off64, (long)((int64_t)(off64 + ((uint64_t)1 << 20)) >> 21), | 217 | (long)off64, (long)((int64_t)(off64 + ((uint64_t)1 << 20)) >> 21), |
| 218 | symtab_section->link->data + sym->st_name); | 218 | symtab_section->link->data + sym->st_name); |
| 219 | write32le(ptr, (read32le(ptr) & 0xfff) | 219 | write32le(ptr, (read32le(ptr) & 0xfff) |
| @@ -222,10 +222,10 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 2 unmodified lines | |||
| 222 | last_hi.val = val; | 222 | last_hi.val = val; |
| 223 | return; | 223 | return; |
| 224 | case R_RISCV_GOT_HI20: | 224 | case R_RISCV_GOT_HI20: |
| 225 | val = s1->got->sh_addr + get_sym_attr(s1, sym_index, 0)->got_offset; | 225 | val = S->got->sh_addr + get_sym_attr(S, sym_index, 0)->got_offset; |
| 226 | off64 = (int64_t)(val - addr + 0x800) >> 12; | 226 | off64 = (int64_t)(val - addr + 0x800) >> 12; |
| 227 | if ((off64 + ((uint64_t)1 << 20)) >> 21) | 227 | if ((off64 + ((uint64_t)1 << 20)) >> 21) |
| 228 | tcc_error("R_RISCV_GOT_HI20 relocation failed"); | 228 | tcc_error(S, "R_RISCV_GOT_HI20 relocation failed"); |
| 229 | last_hi.addr = addr; | 229 | last_hi.addr = addr; |
| 230 | last_hi.val = val; | 230 | last_hi.val = val; |
| 231 | write32le(ptr, (read32le(ptr) & 0xfff) | 231 | write32le(ptr, (read32le(ptr) & 0xfff) |
| @@ -236,7 +236,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 4 unmodified lines | |||
| 236 | printf("PCREL_LO12_I: val=%lx addr=%lx\n", (long)val, (long)addr); | 236 | printf("PCREL_LO12_I: val=%lx addr=%lx\n", (long)val, (long)addr); |
| 237 | #endif | 237 | #endif |
| 238 | if (val != last_hi.addr) | 238 | if (val != last_hi.addr) |
| 239 | tcc_error("unsupported hi/lo pcrel reloc scheme"); | 239 | tcc_error(S, "unsupported hi/lo pcrel reloc scheme"); |
| 240 | val = last_hi.val; | 240 | val = last_hi.val; |
| 241 | addr = last_hi.addr; | 241 | addr = last_hi.addr; |
| 242 | write32le(ptr, (read32le(ptr) & 0xfffff) | 242 | write32le(ptr, (read32le(ptr) & 0xfffff) |
| @@ -244,7 +244,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 1 unmodified line | |||
| 244 | return; | 244 | return; |
| 245 | case R_RISCV_PCREL_LO12_S: | 245 | case R_RISCV_PCREL_LO12_S: |
| 246 | if (val != last_hi.addr) | 246 | if (val != last_hi.addr) |
| 247 | tcc_error("unsupported hi/lo pcrel reloc scheme"); | 247 | tcc_error(S, "unsupported hi/lo pcrel reloc scheme"); |
| 248 | val = last_hi.val; | 248 | val = last_hi.val; |
| 249 | addr = last_hi.addr; | 249 | addr = last_hi.addr; |
| 250 | off32 = val - addr; | 250 | off32 = val - addr; |
| @@ -256,7 +256,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 5 unmodified lines | |||
| 256 | case R_RISCV_RVC_BRANCH: | 256 | case R_RISCV_RVC_BRANCH: |
| 257 | off64 = (val - addr); | 257 | off64 = (val - addr); |
| 258 | if ((off64 + (1 << 8)) & ~(uint64_t)0x1fe) | 258 | if ((off64 + (1 << 8)) & ~(uint64_t)0x1fe) |
| 259 | tcc_error("R_RISCV_RVC_BRANCH relocation failed" | 259 | tcc_error(S, "R_RISCV_RVC_BRANCH relocation failed" |
| 260 | " (val=%lx, addr=%lx)", (long)val, (long)addr); | 260 | " (val=%lx, addr=%lx)", (long)val, (long)addr); |
| 261 | off32 = off64; | 261 | off32 = off64; |
| 262 | write16le(ptr, (read16le(ptr) & 0xe383) | 262 | write16le(ptr, (read16le(ptr) & 0xe383) |
| @@ -269,7 +269,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 6 unmodified lines | |||
| 269 | case R_RISCV_RVC_JUMP: | 269 | case R_RISCV_RVC_JUMP: |
| 270 | off64 = (val - addr); | 270 | off64 = (val - addr); |
| 271 | if ((off64 + (1 << 11)) & ~(uint64_t)0xffe) | 271 | if ((off64 + (1 << 11)) & ~(uint64_t)0xffe) |
| 272 | tcc_error("R_RISCV_RVC_BRANCH relocation failed" | 272 | tcc_error(S, "R_RISCV_RVC_BRANCH relocation failed" |
| 273 | " (val=%lx, addr=%lx)", (long)val, (long)addr); | 273 | " (val=%lx, addr=%lx)", (long)val, (long)addr); |
| 274 | off32 = off64; | 274 | off32 = off64; |
| 275 | write16le(ptr, (read16le(ptr) & 0xe003) | 275 | write16le(ptr, (read16le(ptr) & 0xe003) |
| @@ -284,7 +284,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 8 unmodified lines | |||
| 284 | return; | 284 | return; |
| 285 | 285 | ||
| 286 | case R_RISCV_32: | 286 | case R_RISCV_32: |
| 287 | if (s1->output_type == TCC_OUTPUT_DLL) { | 287 | if (S->output_type == TCC_OUTPUT_DLL) { |
| 288 | /* XXX: this logic may depend on TCC's codegen | 288 | /* XXX: this logic may depend on TCC's codegen |
| 289 | now TCC uses R_RISCV_RELATIVE even for a 64bit pointer */ | 289 | now TCC uses R_RISCV_RELATIVE even for a 64bit pointer */ |
| 290 | qrel->r_offset = rel->r_offset; | 290 | qrel->r_offset = rel->r_offset; |
| @@ -296,8 +296,8 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 5 unmodified lines | |||
| 296 | add32le(ptr, val); | 296 | add32le(ptr, val); |
| 297 | return; | 297 | return; |
| 298 | case R_RISCV_64: | 298 | case R_RISCV_64: |
| 299 | if (s1->output_type == TCC_OUTPUT_DLL) { | 299 | if (S->output_type == TCC_OUTPUT_DLL) { |
| 300 | esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index; | 300 | esym_index = get_sym_attr(S, sym_index, 0)->dyn_index; |
| 301 | qrel->r_offset = rel->r_offset; | 301 | qrel->r_offset = rel->r_offset; |
| 302 | if (esym_index) { | 302 | if (esym_index) { |
| 303 | qrel->r_info = ELFW(R_INFO)(esym_index, R_RISCV_64); | 303 | qrel->r_info = ELFW(R_INFO)(esym_index, R_RISCV_64); |
| @@ -199,40 +199,40 @@ static void print_dirs(const char *msg, char **paths, int nb_paths) · 198 unmodified lines | |||
| 199 | printf(" %s\n", paths[i]); | 199 | printf(" %s\n", paths[i]); |
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | static void print_search_dirs(TCCState *s) | 202 | static void print_search_dirs(TCCState *S) |
| 203 | { | 203 | { |
| 204 | printf("install: %s\n", s->tcc_lib_path); | 204 | printf("install: %s\n", S->tcc_lib_path); |
| 205 | /* print_dirs("programs", NULL, 0); */ | 205 | /* print_dirs("programs", NULL, 0); */ |
| 206 | print_dirs("include", s->sysinclude_paths, s->nb_sysinclude_paths); | 206 | print_dirs("include", S->sysinclude_paths, S->nb_sysinclude_paths); |
| 207 | print_dirs("libraries", s->library_paths, s->nb_library_paths); | 207 | print_dirs("libraries", S->library_paths, S->nb_library_paths); |
| 208 | #ifdef TCC_TARGET_PE | 208 | #ifdef TCC_TARGET_PE |
| 209 | printf("libtcc1:\n %s/lib/"TCC_LIBTCC1"\n", s->tcc_lib_path); | 209 | printf("libtcc1:\n %s/lib/"TCC_LIBTCC1"\n", S->tcc_lib_path); |
| 210 | #else | 210 | #else |
| 211 | printf("libtcc1:\n %s/"TCC_LIBTCC1"\n", s->tcc_lib_path); | 211 | printf("libtcc1:\n %s/"TCC_LIBTCC1"\n", S->tcc_lib_path); |
| 212 | print_dirs("crt", s->crt_paths, s->nb_crt_paths); | 212 | print_dirs("crt", S->crt_paths, S->nb_crt_paths); |
| 213 | printf("elfinterp:\n %s\n", DEFAULT_ELFINTERP(s)); | 213 | printf("elfinterp:\n %s\n", DEFAULT_ELFINTERP(S)); |
| 214 | #endif | 214 | #endif |
| 215 | } | 215 | } |
| 216 | 216 | ||
| 217 | static void set_environment(TCCState *s) | 217 | static void set_environment(TCCState *S) |
| 218 | { | 218 | { |
| 219 | char * path; | 219 | char * path; |
| 220 | 220 | ||
| 221 | path = getenv("C_INCLUDE_PATH"); | 221 | path = getenv("C_INCLUDE_PATH"); |
| 222 | if(path != NULL) { | 222 | if(path != NULL) { |
| 223 | tcc_add_sysinclude_path(s, path); | 223 | tcc_add_sysinclude_path(S, path); |
| 224 | } | 224 | } |
| 225 | path = getenv("CPATH"); | 225 | path = getenv("CPATH"); |
| 226 | if(path != NULL) { | 226 | if(path != NULL) { |
| 227 | tcc_add_include_path(s, path); | 227 | tcc_add_include_path(S, path); |
| 228 | } | 228 | } |
| 229 | path = getenv("LIBRARY_PATH"); | 229 | path = getenv("LIBRARY_PATH"); |
| 230 | if(path != NULL) { | 230 | if(path != NULL) { |
| 231 | tcc_add_library_path(s, path); | 231 | tcc_add_library_path(S, path); |
| 232 | } | 232 | } |
| 233 | } | 233 | } |
| 234 | 234 | ||
| 235 | static char *default_outputfile(TCCState *s, const char *first_file) | 235 | static char *default_outputfile(TCCState *S, const char *first_file) |
| 236 | { | 236 | { |
| 237 | char buf[1024]; | 237 | char buf[1024]; |
| 238 | char *ext; | 238 | char *ext; |
| @@ -243,18 +243,18 @@ static char *default_outputfile(TCCState *s, const char *first_file) · 4 unmodified lines | |||
| 243 | snprintf(buf, sizeof(buf), "%s", name); | 243 | snprintf(buf, sizeof(buf), "%s", name); |
| 244 | ext = tcc_fileextension(buf); | 244 | ext = tcc_fileextension(buf); |
| 245 | #ifdef TCC_TARGET_PE | 245 | #ifdef TCC_TARGET_PE |
| 246 | if (s->output_type == TCC_OUTPUT_DLL) | 246 | if (S->output_type == TCC_OUTPUT_DLL) |
| 247 | strcpy(ext, ".dll"); | 247 | strcpy(ext, ".dll"); |
| 248 | else | 248 | else |
| 249 | if (s->output_type == TCC_OUTPUT_EXE) | 249 | if (S->output_type == TCC_OUTPUT_EXE) |
| 250 | strcpy(ext, ".exe"); | 250 | strcpy(ext, ".exe"); |
| 251 | else | 251 | else |
| 252 | #endif | 252 | #endif |
| 253 | if ((s->just_deps || s->output_type == TCC_OUTPUT_OBJ) && !s->option_r && *ext) | 253 | if ((S->just_deps || S->output_type == TCC_OUTPUT_OBJ) && !S->option_r && *ext) |
| 254 | strcpy(ext, ".o"); | 254 | strcpy(ext, ".o"); |
| 255 | else | 255 | else |
| 256 | strcpy(buf, "a.out"); | 256 | strcpy(buf, "a.out"); |
| 257 | return tcc_strdup(buf); | 257 | return tcc_strdup(S, buf); |
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | static unsigned getclock_ms(void) | 260 | static unsigned getclock_ms(void) |
| @@ -268,9 +268,101 @@ static unsigned getclock_ms(void) · 7 unmodified lines | |||
| 268 | #endif | 268 | #endif |
| 269 | } | 269 | } |
| 270 | 270 | ||
| 271 | #ifdef WITH_ATTACHMENTS | ||
| 272 | #include "tcc_attachments.h" | ||
| 273 | #define ATTACH_PREFIX "/_attach_" | ||
| 274 | |||
| 275 | static vio_module_t vio_module; | ||
| 276 | |||
| 277 | typedef struct vio_memfile_t { | ||
| 278 | off_t size; | ||
| 279 | off_t pos; | ||
| 280 | const unsigned char *mem; | ||
| 281 | } vio_memfile_t; | ||
| 282 | |||
| 283 | static int vio_mem_open(vio_fd *fd, const char *fn, int oflag) { | ||
| 284 | //printf("%d:%s\n", fd->fd, fn); | ||
| 285 | if(fd->vio_module && strncmp(ATTACH_PREFIX, fn, sizeof(ATTACH_PREFIX)-1) == 0){ | ||
| 286 | int i, count = sizeof(bin2c_filesAttached)/sizeof(bin2c_filesAttached_st); | ||
| 287 | for(i=0; i < count; ++i) { | ||
| 288 | //printf("%s:%s\n", fn, bin2c_filesAttached[i].file_name); | ||
| 289 | if(strcmp(fn, bin2c_filesAttached[i].file_name) == 0) { | ||
| 290 | vio_memfile_t *mf = (vio_memfile_t*)tcc_malloc(S, fd->vio_module->tcc_state); | ||
| 291 | mf->mem = bin2c_filesAttached[i].sym_name; | ||
| 292 | mf->size = bin2c_filesAttached[i].size; | ||
| 293 | mf->pos = 0; | ||
| 294 | fd->fd = 1; | ||
| 295 | fd->vio_udata = mf; | ||
| 296 | //printf("%d:%s\n", fd->fd, fn); | ||
| 297 | return fd->fd; | ||
| 298 | } | ||
| 299 | } | ||
| 300 | } | ||
| 301 | return -1; | ||
| 302 | } | ||
| 303 | |||
| 304 | static off_t vio_mem_lseek(vio_fd fd, off_t offset, int whence) { | ||
| 305 | if(fd.vio_udata) { | ||
| 306 | off_t loffset = 0; | ||
| 307 | vio_memfile_t *mf = (vio_memfile_t*)fd.vio_udata; | ||
| 308 | if (whence == SEEK_CUR) | ||
| 309 | loffset = mf->pos + offset; | ||
| 310 | else if (whence == SEEK_SET) | ||
| 311 | loffset = offset; | ||
| 312 | else if (whence == SEEK_END) | ||
| 313 | loffset = ((off_t)mf->size) + offset; | ||
| 314 | |||
| 315 | if (loffset < 0 && loffset > mf->size) | ||
| 316 | return -1; | ||
| 317 | |||
| 318 | mf->pos = loffset; | ||
| 319 | |||
| 320 | return mf->pos; | ||
| 321 | } | ||
| 322 | return lseek(fd.fd, offset, whence); | ||
| 323 | } | ||
| 324 | |||
| 325 | static size_t vio_mem_read(vio_fd fd, void *buf, size_t bytes) { | ||
| 326 | if(fd.vio_udata) { | ||
| 327 | vio_memfile_t *mf = (vio_memfile_t*)fd.vio_udata; | ||
| 328 | if( (mf->pos + bytes) > mf->size) { | ||
| 329 | long bc = mf->size - mf->pos; | ||
| 330 | if(bc > 0) { | ||
| 331 | memcpy(buf, mf->mem + mf->pos, bc); | ||
| 332 | mf->pos = mf->size; | ||
| 333 | return bc; | ||
| 334 | } | ||
| 335 | return 0; | ||
| 336 | } | ||
| 337 | memcpy(buf, mf->mem + mf->pos, bytes); | ||
| 338 | mf->pos += bytes; | ||
| 339 | return bytes; | ||
| 340 | } | ||
| 341 | return 0; | ||
| 342 | } | ||
| 343 | |||
| 344 | static int vio_mem_close(vio_fd *fd) { | ||
| 345 | if(fd->vio_udata){ | ||
| 346 | tcc_free(S, fd->vio_udata); | ||
| 347 | } | ||
| 348 | return 0; | ||
| 349 | } | ||
| 350 | |||
| 351 | void set_vio_module(TCCState *S){ | ||
| 352 | vio_module.user_data = NULL; | ||
| 353 | vio_module.call_vio_open_flags = CALL_VIO_OPEN_FIRST; | ||
| 354 | vio_module.vio_open = &vio_mem_open; | ||
| 355 | vio_module.vio_lseek = &vio_mem_lseek; | ||
| 356 | vio_module.vio_read = &vio_mem_read; | ||
| 357 | vio_module.vio_close = &vio_mem_close; | ||
| 358 | tcc_set_vio_module(s, &vio_module); | ||
| 359 | } | ||
| 360 | |||
| 361 | #endif | ||
| 362 | |||
| 271 | int main(int argc0, char **argv0) | 363 | int main(int argc0, char **argv0) |
| 272 | { | 364 | { |
| 273 | TCCState *s, *s1; | 365 | TCCState *S, *s1; |
| 274 | int ret, opt, n = 0, t = 0, done; | 366 | int ret, opt, n = 0, t = 0, done; |
| 275 | unsigned start_time = 0, end_time = 0; | 367 | unsigned start_time = 0, end_time = 0; |
| 276 | const char *first_file; | 368 | const char *first_file; |
| @@ -279,13 +371,19 @@ int main(int argc0, char **argv0) · 2 unmodified lines | |||
| 279 | 371 | ||
| 280 | redo: | 372 | redo: |
| 281 | argc = argc0, argv = argv0; | 373 | argc = argc0, argv = argv0; |
| 282 | s = s1 = tcc_new(); | 374 | S = s1 = tcc_new(); |
| 283 | opt = tcc_parse_args(s, &argc, &argv, 1); | 375 | opt = tcc_parse_args(S, &argc, &argv, 1); |
| 376 | |||
| 377 | #ifdef WITH_ATTACHMENTS | ||
| 378 | tcc_set_lib_path(S, ATTACH_PREFIX); | ||
| 379 | tcc_add_include_path(S, ATTACH_PREFIX); | ||
| 380 | set_vio_module(S); | ||
| 381 | #endif | ||
| 284 | 382 | ||
| 285 | if (n == 0) { | 383 | if (n == 0) { |
| 286 | if (opt == OPT_HELP) { | 384 | if (opt == OPT_HELP) { |
| 287 | fputs(help, stdout); | 385 | fputs(help, stdout); |
| 288 | if (!s->verbose) | 386 | if (!S->verbose) |
| 289 | return 0; | 387 | return 0; |
| 290 | ++opt; | 388 | ++opt; |
| 291 | } | 389 | } |
| @@ -294,57 +392,57 @@ redo: · 2 unmodified lines | |||
| 294 | return 0; | 392 | return 0; |
| 295 | } | 393 | } |
| 296 | if (opt == OPT_M32 || opt == OPT_M64) | 394 | if (opt == OPT_M32 || opt == OPT_M64) |
| 297 | tcc_tool_cross(s, argv, opt); /* never returns */ | 395 | tcc_tool_cross(S, argv, opt); /* never returns */ |
| 298 | if (s->verbose) | 396 | if (S->verbose) |
| 299 | printf(version); | 397 | printf(version); |
| 300 | if (opt == OPT_AR) | 398 | if (opt == OPT_AR) |
| 301 | return tcc_tool_ar(s, argc, argv); | 399 | return tcc_tool_ar(S, argc, argv); |
| 302 | #ifdef TCC_TARGET_PE | 400 | #ifdef TCC_TARGET_PE |
| 303 | if (opt == OPT_IMPDEF) | 401 | if (opt == OPT_IMPDEF) |
| 304 | return tcc_tool_impdef(s, argc, argv); | 402 | return tcc_tool_impdef(S, argc, argv); |
| 305 | #endif | 403 | #endif |
| 306 | if (opt == OPT_V) | 404 | if (opt == OPT_V) |
| 307 | return 0; | 405 | return 0; |
| 308 | if (opt == OPT_PRINT_DIRS) { | 406 | if (opt == OPT_PRINT_DIRS) { |
| 309 | /* initialize search dirs */ | 407 | /* initialize search dirs */ |
| 310 | set_environment(s); | 408 | set_environment(S); |
| 311 | tcc_set_output_type(s, TCC_OUTPUT_MEMORY); | 409 | tcc_set_output_type(S, TCC_OUTPUT_MEMORY); |
| 312 | print_search_dirs(s); | 410 | print_search_dirs(S); |
| 313 | return 0; | 411 | return 0; |
| 314 | } | 412 | } |
| 315 | 413 | ||
| 316 | if (s->nb_files == 0) | 414 | if (S->nb_files == 0) |
| 317 | tcc_error("no input files"); | 415 | tcc_error(S, "no input files"); |
| 318 | 416 | ||
| 319 | if (s->output_type == TCC_OUTPUT_PREPROCESS) { | 417 | if (S->output_type == TCC_OUTPUT_PREPROCESS) { |
| 320 | if (s->outfile && 0!=strcmp("-",s->outfile)) { | 418 | if (S->outfile && 0!=strcmp("-",S->outfile)) { |
| 321 | ppfp = fopen(s->outfile, "w"); | 419 | ppfp = fopen(S->outfile, "w"); |
| 322 | if (!ppfp) | 420 | if (!ppfp) |
| 323 | tcc_error("could not write '%s'", s->outfile); | 421 | tcc_error(S, "could not write '%s'", S->outfile); |
| 324 | } | 422 | } |
| 325 | } else if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) { | 423 | } else if (S->output_type == TCC_OUTPUT_OBJ && !S->option_r) { |
| 326 | if (s->nb_libraries) | 424 | if (S->nb_libraries) |
| 327 | tcc_error("cannot specify libraries with -c"); | 425 | tcc_error(S, "cannot specify libraries with -c"); |
| 328 | if (s->nb_files > 1 && s->outfile) | 426 | if (S->nb_files > 1 && S->outfile) |
| 329 | tcc_error("cannot specify output file with -c many files"); | 427 | tcc_error(S, "cannot specify output file with -c many files"); |
| 330 | } | 428 | } |
| 331 | 429 | ||
| 332 | if (s->do_bench) | 430 | if (S->do_bench) |
| 333 | start_time = getclock_ms(); | 431 | start_time = getclock_ms(); |
| 334 | } | 432 | } |
| 335 | 433 | ||
| 336 | set_environment(s); | 434 | set_environment(S); |
| 337 | if (s->output_type == 0) | 435 | if (S->output_type == 0) |
| 338 | s->output_type = TCC_OUTPUT_EXE; | 436 | S->output_type = TCC_OUTPUT_EXE; |
| 339 | tcc_set_output_type(s, s->output_type); | 437 | tcc_set_output_type(S, S->output_type); |
| 340 | s->ppfp = ppfp; | 438 | S->ppfp = ppfp; |
| 341 | 439 | ||
| 342 | if ((s->output_type == TCC_OUTPUT_MEMORY | 440 | if ((S->output_type == TCC_OUTPUT_MEMORY |
| 343 | || s->output_type == TCC_OUTPUT_PREPROCESS) | 441 | || S->output_type == TCC_OUTPUT_PREPROCESS) |
| 344 | && (s->dflag & 16)) { /* -dt option */ | 442 | && (S->dflag & TCC_OPTION_d_t)) { /* -dt option */ |
| 345 | if (t) | 443 | if (t) |
| 346 | s->dflag |= 32; | 444 | S->dflag |= TCC_OPTION_d_32; |
| 347 | s->run_test = ++t; | 445 | S->run_test = ++t; |
| 348 | if (n) | 446 | if (n) |
| 349 | --n; | 447 | --n; |
| 350 | } | 448 | } |
| @@ -352,48 +450,48 @@ redo: · 1 unmodified line | |||
| 352 | /* compile or add each files or library */ | 450 | /* compile or add each files or library */ |
| 353 | first_file = NULL, ret = 0; | 451 | first_file = NULL, ret = 0; |
| 354 | do { | 452 | do { |
| 355 | struct filespec *f = s->files[n]; | 453 | struct filespec *f = S->files[n]; |
| 356 | s->filetype = f->type; | 454 | S->filetype = f->type; |
| 357 | if (f->type & AFF_TYPE_LIB) { | 455 | if (f->type & AFF_TYPE_LIB) { |
| 358 | if (tcc_add_library_err(s, f->name) < 0) | 456 | if (tcc_add_library_err(S, f->name) < 0) |
| 359 | ret = 1; | 457 | ret = 1; |
| 360 | } else { | 458 | } else { |
| 361 | if (1 == s->verbose) | 459 | if (1 == S->verbose) |
| 362 | printf("-> %s\n", f->name); | 460 | printf("-> %s\n", f->name); |
| 363 | if (!first_file) | 461 | if (!first_file) |
| 364 | first_file = f->name; | 462 | first_file = f->name; |
| 365 | if (tcc_add_file(s, f->name) < 0) | 463 | if (tcc_add_file(S, f->name) < 0) |
| 366 | ret = 1; | 464 | ret = 1; |
| 367 | } | 465 | } |
| 368 | done = ret || ++n >= s->nb_files; | 466 | done = ret || ++n >= S->nb_files; |
| 369 | } while (!done && (s->output_type != TCC_OUTPUT_OBJ || s->option_r)); | 467 | } while (!done && (S->output_type != TCC_OUTPUT_OBJ || S->option_r)); |
| 370 | 468 | ||
| 371 | if (s->do_bench) | 469 | if (S->do_bench) |
| 372 | end_time = getclock_ms(); | 470 | end_time = getclock_ms(); |
| 373 | 471 | ||
| 374 | if (s->run_test) { | 472 | if (S->run_test) { |
| 375 | t = 0; | 473 | t = 0; |
| 376 | } else if (s->output_type == TCC_OUTPUT_PREPROCESS) { | 474 | } else if (S->output_type == TCC_OUTPUT_PREPROCESS) { |
| 377 | ; | 475 | ; |
| 378 | } else if (0 == ret) { | 476 | } else if (0 == ret) { |
| 379 | if (s->output_type == TCC_OUTPUT_MEMORY) { | 477 | if (S->output_type == TCC_OUTPUT_MEMORY) { |
| 380 | #ifdef TCC_IS_NATIVE | 478 | #ifdef TCC_IS_NATIVE |
| 381 | ret = tcc_run(s, argc, argv); | 479 | ret = tcc_run(S, argc, argv); |
| 382 | #endif | 480 | #endif |
| 383 | } else { | 481 | } else { |
| 384 | if (!s->outfile) | 482 | if (!S->outfile) |
| 385 | s->outfile = default_outputfile(s, first_file); | 483 | S->outfile = default_outputfile(S, first_file); |
| 386 | if (!s->just_deps && tcc_output_file(s, s->outfile)) | 484 | if (!S->just_deps && tcc_output_file(S, S->outfile)) |
| 387 | ret = 1; | 485 | ret = 1; |
| 388 | else if (s->gen_deps) | 486 | else if (S->gen_deps) |
| 389 | gen_makedeps(s, s->outfile, s->deps_outfile); | 487 | gen_makedeps(S, S->outfile, S->deps_outfile); |
| 390 | } | 488 | } |
| 391 | } | 489 | } |
| 392 | 490 | ||
| 393 | if (done && 0 == t && 0 == ret && s->do_bench) | 491 | if (done && 0 == t && 0 == ret && S->do_bench) |
| 394 | tcc_print_stats(s, end_time - start_time); | 492 | tcc_print_stats(S, end_time - start_time); |
| 395 | 493 | ||
| 396 | tcc_delete(s); | 494 | tcc_delete(S); |
| 397 | if (!done) | 495 | if (!done) |
| 398 | goto redo; /* compile more files with -c */ | 496 | goto redo; /* compile more files with -c */ |
| 399 | if (t) | 497 | if (t) |
| @@ -585,7 +585,7 @@ typedef struct Section { · 584 unmodified lines | |||
| 585 | unsigned long data_offset; /* current data offset */ | 585 | unsigned long data_offset; /* current data offset */ |
| 586 | unsigned char *data; /* section data */ | 586 | unsigned char *data; /* section data */ |
| 587 | unsigned long data_allocated; /* used for realloc() handling */ | 587 | unsigned long data_allocated; /* used for realloc() handling */ |
| 588 | TCCState *s1; | 588 | TCCState *S; |
| 589 | int sh_name; /* elf section name (only used during output) */ | 589 | int sh_name; /* elf section name (only used during output) */ |
| 590 | int sh_num; /* elf section number */ | 590 | int sh_num; /* elf section number */ |
| 591 | int sh_type; /* elf section type */ | 591 | int sh_type; /* elf section type */ |
| @@ -743,6 +743,78 @@ struct sym_attr { · 151 unmodified lines | |||
| 743 | #endif | 743 | #endif |
| 744 | }; | 744 | }; |
| 745 | 745 | ||
| 746 | /*From tccpp.c*/ | ||
| 747 | typedef struct TinyAlloc { | ||
| 748 | unsigned limit; | ||
| 749 | unsigned size; | ||
| 750 | uint8_t *buffer; | ||
| 751 | uint8_t *p; | ||
| 752 | unsigned nb_allocs; | ||
| 753 | struct TinyAlloc *next, *top; | ||
| 754 | #ifdef TAL_INFO | ||
| 755 | unsigned nb_peak; | ||
| 756 | unsigned nb_total; | ||
| 757 | unsigned nb_missed; | ||
| 758 | uint8_t *peak_p; | ||
| 759 | #endif | ||
| 760 | } TinyAlloc; | ||
| 761 | |||
| 762 | /*From tccgen.c*/ | ||
| 763 | typedef struct scope_t { | ||
| 764 | struct scope_t *prev; | ||
| 765 | struct { int loc, locorig, num; } vla; | ||
| 766 | struct { Sym *s; int n; } cl; | ||
| 767 | int *bsym, *csym; | ||
| 768 | Sym *lstk, *llstk; | ||
| 769 | } scope_t; | ||
| 770 | |||
| 771 | typedef struct switch_t { | ||
| 772 | struct case_t { | ||
| 773 | int64_t v1, v2; | ||
| 774 | int sym; | ||
| 775 | } **p; int n; /* list of case ranges */ | ||
| 776 | int def_sym; /* default symbol */ | ||
| 777 | int *bsym; | ||
| 778 | scope_t *scope; | ||
| 779 | struct switch_t *prev; | ||
| 780 | SValue sv; | ||
| 781 | } switch_t; | ||
| 782 | |||
| 783 | #define MAX_TEMP_LOCAL_VARIABLE_NUMBER 8 | ||
| 784 | /*list of temporary local variables on the stack in current function. */ | ||
| 785 | typedef struct temp_local_variable_t { | ||
| 786 | int location; //offset on stack. Svalue.c.i | ||
| 787 | short size; | ||
| 788 | short align; | ||
| 789 | } temp_local_variable_t; | ||
| 790 | |||
| 791 | typedef struct { | ||
| 792 | unsigned long offset; | ||
| 793 | unsigned long last_file_name; | ||
| 794 | unsigned long last_func_name; | ||
| 795 | int ind; | ||
| 796 | int line; | ||
| 797 | } tcov_data_t; | ||
| 798 | |||
| 799 | typedef struct { | ||
| 800 | int debug_type; | ||
| 801 | Sym *type; | ||
| 802 | } debug_hash_t; | ||
| 803 | |||
| 804 | typedef struct debug_info_t { | ||
| 805 | int start; | ||
| 806 | int end; | ||
| 807 | int n_sym; | ||
| 808 | struct debug_sym { | ||
| 809 | int type; | ||
| 810 | unsigned long value; | ||
| 811 | char *str; | ||
| 812 | Section *sec; | ||
| 813 | int sym_index; | ||
| 814 | } *sym; | ||
| 815 | struct debug_info_t *child, *next, *last, *parent; | ||
| 816 | } debug_info_t; | ||
| 817 | |||
| 746 | struct TCCState { | 818 | struct TCCState { |
| 747 | unsigned char verbose; /* if true, display some information during compilation */ | 819 | unsigned char verbose; /* if true, display some information during compilation */ |
| 748 | unsigned char nostdinc; /* if true, no standard headers are added */ | 820 | unsigned char nostdinc; /* if true, no standard headers are added */ |
| @@ -927,11 +999,11 @@ struct TCCState { · 178 unmodified lines | |||
| 927 | int nb_sym_attrs; | 999 | int nb_sym_attrs; |
| 928 | /* ptr to next reloc entry reused */ | 1000 | /* ptr to next reloc entry reused */ |
| 929 | ElfW_Rel *qrel; | 1001 | ElfW_Rel *qrel; |
| 930 | #define qrel s1->qrel | 1002 | #define qrel S->qrel |
| 931 | 1003 | ||
| 932 | #ifdef TCC_TARGET_RISCV64 | 1004 | #ifdef TCC_TARGET_RISCV64 |
| 933 | struct pcrel_hi { addr_t addr, val; } last_hi; | 1005 | struct pcrel_hi { addr_t addr, val; } last_hi; |
| 934 | #define last_hi s1->last_hi | 1006 | #define last_hi S->last_hi |
| 935 | #endif | 1007 | #endif |
| 936 | 1008 | ||
| 937 | #ifdef TCC_TARGET_PE | 1009 | #ifdef TCC_TARGET_PE |
| @@ -962,6 +1034,10 @@ struct TCCState { · 24 unmodified lines | |||
| 962 | const char *runtime_main; | 1034 | const char *runtime_main; |
| 963 | void **runtime_mem; | 1035 | void **runtime_mem; |
| 964 | int nb_runtime_mem; | 1036 | int nb_runtime_mem; |
| 1037 | # ifdef HAVE_SELINUX | ||
| 1038 | void *write_mem; | ||
| 1039 | unsigned long mem_size; | ||
| 1040 | # endif | ||
| 965 | #endif | 1041 | #endif |
| 966 | 1042 | ||
| 967 | #ifdef CONFIG_TCC_BACKTRACE | 1043 | #ifdef CONFIG_TCC_BACKTRACE |
| @@ -991,6 +1067,117 @@ struct TCCState { · 23 unmodified lines | |||
| 991 | char *deps_outfile; /* option -MF */ | 1067 | char *deps_outfile; /* option -MF */ |
| 992 | int argc; | 1068 | int argc; |
| 993 | char **argv; | 1069 | char **argv; |
| 1070 | |||
| 1071 | /* Entries needed to make it reentrant */ | ||
| 1072 | vio_module_t *vio_module; | ||
| 1073 | |||
| 1074 | /* ------------ tccpp.c ------------ */ | ||
| 1075 | |||
| 1076 | struct BufferedFile *tccpp_file; | ||
| 1077 | int tccpp_ch, tccpp_tok; | ||
| 1078 | CValue tccpp_tokc; | ||
| 1079 | const int *tccpp_macro_ptr; | ||
| 1080 | int tccpp_parse_flags; | ||
| 1081 | int tccpp_tok_flags; | ||
| 1082 | CString tccpp_tokcstr; /* current parsed string, if any */ | ||
| 1083 | CString tccpp_cstr_buf; | ||
| 1084 | CString tccpp_macro_equal_buf; | ||
| 1085 | TokenString tccpp_tokstr_buf; | ||
| 1086 | TokenString *tccpp_macro_stack; | ||
| 1087 | |||
| 1088 | /* display benchmark infos */ | ||
| 1089 | int tccpp_total_lines; | ||
| 1090 | int tccpp_total_bytes; | ||
| 1091 | int tccpp_tok_ident; | ||
| 1092 | TokenSym **tccpp_table_ident; | ||
| 1093 | |||
| 1094 | int *tccpp_macro_ptr_allocated; | ||
| 1095 | const int *tccpp_unget_saved_macro_ptr; | ||
| 1096 | int tccpp_unget_saved_buffer[TOK_MAX_SIZE + 1]; | ||
| 1097 | int tccpp_unget_buffer_enabled; | ||
| 1098 | TokenSym *tccpp_hash_ident[TOK_HASH_SIZE]; | ||
| 1099 | char tccpp_token_buf[STRING_MAX_SIZE + 1]; | ||
| 1100 | /* true if isid(c) || isnum(c) */ | ||
| 1101 | unsigned char tccpp_isidnum_table[256-CH_EOF]; | ||
| 1102 | |||
| 1103 | int tccpp_pp_debug_tok, tccpp_pp_debug_symv; | ||
| 1104 | int tccpp_pp_once; | ||
| 1105 | int tccpp_pp_expr; | ||
| 1106 | int tccpp_pp_counter; | ||
| 1107 | |||
| 1108 | TinyAlloc *tccpp_toksym_alloc; | ||
| 1109 | TinyAlloc *tccpp_tokstr_alloc; | ||
| 1110 | |||
| 1111 | /*----------- tccasm.c --------*/ | ||
| 1112 | Section *tccasm_last_text_section; /* to handle .previous asm directive */ | ||
| 1113 | |||
| 1114 | /* ------------ tccgen.c ------------ */ | ||
| 1115 | |||
| 1116 | Sym *tccgen_global_stack; | ||
| 1117 | Sym *tccgen_local_stack; | ||
| 1118 | Sym *tccgen_local_label_stack; | ||
| 1119 | Sym *tccgen_global_label_stack; | ||
| 1120 | Sym *tccgen_define_stack; | ||
| 1121 | CType tccgen_int_type, tccgen_func_old_type, tccgen_char_type, tccgen_char_pointer_type; | ||
| 1122 | SValue *tccgen_vtop; | ||
| 1123 | SValue tccgen__vstack[1 + VSTACK_SIZE]; | ||
| 1124 | int tccgen_rsym, tccgen_anon_sym, tccgen_ind, tccgen_loc; | ||
| 1125 | char tccgen_debug_modes; | ||
| 1126 | |||
| 1127 | int tccgen_const_wanted; /* true if constant wanted */ | ||
| 1128 | int tccgen_nocode_wanted; /* true if no code generation wanted for an expression */ | ||
| 1129 | int tccgen_global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */ | ||
| 1130 | CType tccgen_func_vt; /* current function return type (used by return instruction) */ | ||
| 1131 | int tccgen_func_var; /* true if current function is variadic */ | ||
| 1132 | int tccgen_func_vc; | ||
| 1133 | const char *tccgen_funcname; | ||
| 1134 | |||
| 1135 | Sym *tccgen_sym_free_first; | ||
| 1136 | void **tccgen_sym_pools; | ||
| 1137 | int tccgen_nb_sym_pools; | ||
| 1138 | Sym *tccgen_all_cleanups, *tccgen_pending_gotos; | ||
| 1139 | int tccgen_local_scope; | ||
| 1140 | int tccgen_in_sizeof; | ||
| 1141 | int tccgen_in_generic; | ||
| 1142 | int tccgen_section_sym; | ||
| 1143 | |||
| 1144 | int tccgen_last_line_num, tccgen_new_file, tccgen_func_ind; /* debug info control */ | ||
| 1145 | CString tccgen_initstr; | ||
| 1146 | |||
| 1147 | switch_t *tccgen_cur_switch; /* current switch */ | ||
| 1148 | |||
| 1149 | temp_local_variable_t tccgen_arr_temp_local_vars[MAX_TEMP_LOCAL_VARIABLE_NUMBER]; | ||
| 1150 | int tccgen_nb_temp_local_vars; | ||
| 1151 | |||
| 1152 | scope_t *tccgen_cur_scope, *tccgen_loop_scope, *tccgen_root_scope; | ||
| 1153 | |||
| 1154 | tcov_data_t tccgen_tcov_data; | ||
| 1155 | int tccgen_debug_next_type; | ||
| 1156 | debug_hash_t *tccgen_debug_hash; | ||
| 1157 | int tccgen_n_debug_hash; | ||
| 1158 | debug_info_t *tccgen_debug_info, *tccgen_debug_info_root; | ||
| 1159 | |||
| 1160 | unsigned char tccgen_prec[256]; | ||
| 1161 | |||
| 1162 | /*--------armg-gen.c-----------*/ | ||
| 1163 | /*#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)*/ | ||
| 1164 | CType armgen_float_type, armgen_double_type, armgen_func_float_type, armgen_func_double_type; | ||
| 1165 | /*#endif*/ | ||
| 1166 | |||
| 1167 | /*------- tccrun.c ------------*/ | ||
| 1168 | |||
| 1169 | /*--------x86_64-gen.c --------*/ | ||
| 1170 | unsigned long x86_64_gen_func_sub_sp_offset; | ||
| 1171 | int x86_64_gen_func_ret_sub; | ||
| 1172 | #if defined(CONFIG_TCC_BCHECK) | ||
| 1173 | addr_t func_bound_offset; | ||
| 1174 | unsigned long func_bound_ind; | ||
| 1175 | int func_bound_add_epilog; | ||
| 1176 | #endif | ||
| 1177 | #ifdef TCC_TARGET_PE | ||
| 1178 | int x86_64_gen_func_scratch, x86_64_gen_func_alloca; | ||
| 1179 | #endif | ||
| 1180 | |||
| 994 | }; | 1181 | }; |
| 995 | 1182 | ||
| 996 | struct filespec { | 1183 | struct filespec { |
| @@ -1174,7 +1361,7 @@ enum tcc_token { · 177 unmodified lines | |||
| 1174 | 1361 | ||
| 1175 | /* ------------ libtcc.c ------------ */ | 1362 | /* ------------ libtcc.c ------------ */ |
| 1176 | 1363 | ||
| 1177 | ST_DATA struct TCCState *tcc_state; | 1364 | //ST_DATA struct TCCState *S; |
| 1178 | 1365 | ||
| 1179 | /* public functions currently used by the tcc main function */ | 1366 | /* public functions currently used by the tcc main function */ |
| 1180 | ST_FUNC char *pstrcpy(char *buf, size_t buf_size, const char *s); | 1367 | ST_FUNC char *pstrcpy(char *buf, size_t buf_size, const char *s); |
| @@ -1183,53 +1370,56 @@ ST_FUNC char *pstrncpy(char *out, const char *in, size_t num); · 2 unmodified lines | |||
| 1183 | PUB_FUNC char *tcc_basename(const char *name); | 1370 | PUB_FUNC char *tcc_basename(const char *name); |
| 1184 | PUB_FUNC char *tcc_fileextension (const char *name); | 1371 | PUB_FUNC char *tcc_fileextension (const char *name); |
| 1185 | 1372 | ||
| 1373 | PUB_FUNC void tcc_free_base(void *ptr); | ||
| 1374 | PUB_FUNC void *tcc_malloc_base(unsigned long size); | ||
| 1375 | PUB_FUNC void *tcc_mallocz_base(unsigned long size); | ||
| 1186 | #ifndef MEM_DEBUG | 1376 | #ifndef MEM_DEBUG |
| 1187 | PUB_FUNC void tcc_free(void *ptr); | 1377 | PUB_FUNC void tcc_free(TCCState* S, void *ptr); |
| 1188 | PUB_FUNC void *tcc_malloc(unsigned long size); | 1378 | PUB_FUNC void *tcc_malloc(TCCState* S, unsigned long size); |
| 1189 | PUB_FUNC void *tcc_mallocz(unsigned long size); | 1379 | PUB_FUNC void *tcc_mallocz(TCCState* S, unsigned long size); |
| 1190 | PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size); | 1380 | PUB_FUNC void *tcc_realloc(TCCState* S, void *ptr, unsigned long size); |
| 1191 | PUB_FUNC char *tcc_strdup(const char *str); | 1381 | PUB_FUNC char *tcc_strdup(TCCState* S, const char *str); |
| 1192 | #else | 1382 | #else |
| 1193 | #define tcc_free(ptr) tcc_free_debug(ptr) | 1383 | #define tcc_free(s, ptr) tcc_free_debug(s, ptr) |
| 1194 | #define tcc_malloc(size) tcc_malloc_debug(size, __FILE__, __LINE__) | 1384 | #define tcc_malloc(s, size) tcc_malloc_debug(s, size, __FILE__, __LINE__) |
| 1195 | #define tcc_mallocz(size) tcc_mallocz_debug(size, __FILE__, __LINE__) | 1385 | #define tcc_mallocz(s, size) tcc_mallocz_debug(s, size, __FILE__, __LINE__) |
| 1196 | #define tcc_realloc(ptr,size) tcc_realloc_debug(ptr, size, __FILE__, __LINE__) | 1386 | #define tcc_realloc(s, ptr, size) tcc_realloc_debug(s, ptr, size, __FILE__, __LINE__) |
| 1197 | #define tcc_strdup(str) tcc_strdup_debug(str, __FILE__, __LINE__) | 1387 | #define tcc_strdup(s, str) tcc_strdup_debug(s, str, __FILE__, __LINE__) |
| 1198 | PUB_FUNC void tcc_free_debug(void *ptr); | 1388 | PUB_FUNC void tcc_free_debug(TCCState* S, void *ptr); |
| 1199 | PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line); | 1389 | PUB_FUNC void *tcc_malloc_debug(TCCState* S, unsigned long size, const char *file, int line); |
| 1200 | PUB_FUNC void *tcc_mallocz_debug(unsigned long size, const char *file, int line); | 1390 | PUB_FUNC void *tcc_mallocz_debug(TCCState* S, unsigned long size, const char *file, int line); |
| 1201 | PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file, int line); | 1391 | PUB_FUNC void *tcc_realloc_debug(TCCState* S, void *ptr, unsigned long size, const char *file, int line); |
| 1202 | PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line); | 1392 | PUB_FUNC char *tcc_strdup_debug(TCCState* S, const char *str, const char *file, int line); |
| 1203 | #endif | 1393 | #endif |
| 1204 | 1394 | ||
| 1205 | #define free(p) use_tcc_free(p) | 1395 | #define free(p) use_tcc_free(S, p) |
| 1206 | #define malloc(s) use_tcc_malloc(s) | 1396 | #define malloc(s) use_tcc_malloc(S, s) |
| 1207 | #define realloc(p, s) use_tcc_realloc(p, s) | 1397 | #define realloc(p, s) use_tcc_realloc(S, p, s) |
| 1208 | #undef strdup | 1398 | #undef strdup |
| 1209 | #define strdup(s) use_tcc_strdup(s) | 1399 | #define strdup(s) use_tcc_strdup(S, s) |
| 1210 | PUB_FUNC void _tcc_error_noabort(const char *fmt, ...) PRINTF_LIKE(1,2); | 1400 | PUB_FUNC void _tcc_error_noabort(TCCState* S, const char *fmt, ...) PRINTF_LIKE(2,3); |
| 1211 | PUB_FUNC NORETURN void _tcc_error(const char *fmt, ...) PRINTF_LIKE(1,2); | 1401 | PUB_FUNC NORETURN void _tcc_error(TCCState* S, const char *fmt, ...) PRINTF_LIKE(2,3); |
| 1212 | PUB_FUNC void _tcc_warning(const char *fmt, ...) PRINTF_LIKE(1,2); | 1402 | PUB_FUNC void _tcc_warning(TCCState* S, const char *fmt, ...) PRINTF_LIKE(2,3); |
| 1213 | #define tcc_internal_error(msg) tcc_error("internal compiler error\n"\ | 1403 | #define tcc_internal_error(S, msg) tcc_error(S, "internal compiler error\n"\ |
| 1214 | "%s:%d: in %s(): " msg, __FILE__,__LINE__,__FUNCTION__) | 1404 | "%s:%d: in %s(): " msg, __FILE__,__LINE__,__FUNCTION__) |
| 1215 | 1405 | ||
| 1216 | /* other utilities */ | 1406 | /* other utilities */ |
| 1217 | ST_FUNC void dynarray_add(void *ptab, int *nb_ptr, void *data); | 1407 | ST_FUNC void dynarray_add(TCCState* S, void *ptab, int *nb_ptr, void *data); |
| 1218 | ST_FUNC void dynarray_reset(void *pp, int *n); | 1408 | ST_FUNC void dynarray_reset(TCCState* S, void *pp, int *n); |
| 1219 | ST_INLN void cstr_ccat(CString *cstr, int ch); | 1409 | ST_INLN void cstr_ccat(TCCState* S, CString *cstr, int ch); |
| 1220 | ST_FUNC void cstr_cat(CString *cstr, const char *str, int len); | 1410 | ST_FUNC void cstr_cat(TCCState* S, CString *cstr, const char *str, int len); |
| 1221 | ST_FUNC void cstr_wccat(CString *cstr, int ch); | 1411 | ST_FUNC void cstr_wccat(TCCState* S, CString *cstr, int ch); |
| 1222 | ST_FUNC void cstr_new(CString *cstr); | 1412 | ST_FUNC void cstr_new(TCCState* S, CString *cstr); |
| 1223 | ST_FUNC void cstr_free(CString *cstr); | 1413 | ST_FUNC void cstr_free(TCCState* S, CString *cstr); |
| 1224 | ST_FUNC int cstr_printf(CString *cs, const char *fmt, ...) PRINTF_LIKE(2,3); | 1414 | ST_FUNC int cstr_printf(TCCState* S, CString *cs, const char *fmt, ...) PRINTF_LIKE(3,4); |
| 1225 | ST_FUNC int cstr_vprintf(CString *cstr, const char *fmt, va_list ap); | 1415 | ST_FUNC int cstr_vprintf(TCCState* S, CString *cstr, const char *fmt, va_list ap); |
| 1226 | ST_FUNC void cstr_reset(CString *cstr); | 1416 | ST_FUNC void cstr_reset(CString *cstr); |
| 1227 | 1417 | ||
| 1228 | ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen); | 1418 | ST_FUNC void tcc_open_bf(TCCState *S, const char *filename, int initlen); |
| 1229 | ST_FUNC int tcc_open(TCCState *s1, const char *filename); | 1419 | ST_FUNC int tcc_open(TCCState *S, const char *filename); |
| 1230 | ST_FUNC void tcc_close(void); | 1420 | ST_FUNC void tcc_close(TCCState *S); |
| 1231 | 1421 | ||
| 1232 | ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags); | 1422 | ST_FUNC int tcc_add_file_internal(TCCState *S, const char *filename, int flags); |
| 1233 | /* flags: */ | 1423 | /* flags: */ |
| 1234 | #define AFF_PRINT_ERROR 0x10 /* print error if file not found */ | 1424 | #define AFF_PRINT_ERROR 0x10 /* print error if file not found */ |
| 1235 | #define AFF_REFERENCED_DLL 0x20 /* load a referenced dll from another dll */ | 1425 | #define AFF_REFERENCED_DLL 0x20 /* load a referenced dll from another dll */ |
| @@ -1249,26 +1439,26 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 13 unmodified lines | |||
| 1249 | #define AFF_BINTYPE_C67 4 | 1439 | #define AFF_BINTYPE_C67 4 |
| 1250 | 1440 | ||
| 1251 | #ifndef ELF_OBJ_ONLY | 1441 | #ifndef ELF_OBJ_ONLY |
| 1252 | ST_FUNC int tcc_add_crt(TCCState *s, const char *filename); | 1442 | ST_FUNC int tcc_add_crt(TCCState *S, const char *filename); |
| 1253 | #endif | 1443 | #endif |
| 1254 | #ifndef TCC_TARGET_MACHO | 1444 | #ifndef TCC_TARGET_MACHO |
| 1255 | ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags); | 1445 | ST_FUNC int tcc_add_dll(TCCState *S, const char *filename, int flags); |
| 1256 | #endif | 1446 | #endif |
| 1257 | #ifdef CONFIG_TCC_BCHECK | 1447 | #ifdef CONFIG_TCC_BCHECK |
| 1258 | ST_FUNC void tcc_add_bcheck(TCCState *s1); | 1448 | ST_FUNC void tcc_add_bcheck(TCCState *S); |
| 1259 | #endif | 1449 | #endif |
| 1260 | #ifdef CONFIG_TCC_BACKTRACE | 1450 | #ifdef CONFIG_TCC_BACKTRACE |
| 1261 | ST_FUNC void tcc_add_btstub(TCCState *s1); | 1451 | ST_FUNC void tcc_add_btstub(TCCState *S); |
| 1262 | #endif | 1452 | #endif |
| 1263 | ST_FUNC void tcc_add_pragma_libs(TCCState *s1); | 1453 | ST_FUNC void tcc_add_pragma_libs(TCCState *S); |
| 1264 | PUB_FUNC int tcc_add_library_err(TCCState *s, const char *f); | 1454 | PUB_FUNC int tcc_add_library_err(TCCState *S, const char *f); |
| 1265 | PUB_FUNC void tcc_print_stats(TCCState *s, unsigned total_time); | 1455 | PUB_FUNC void tcc_print_stats(TCCState *S, unsigned total_time); |
| 1266 | PUB_FUNC int tcc_parse_args(TCCState *s, int *argc, char ***argv, int optind); | 1456 | PUB_FUNC int tcc_parse_args(TCCState *S, int *argc, char ***argv, int optind); |
| 1267 | #ifdef _WIN32 | 1457 | #ifdef _WIN32 |
| 1268 | ST_FUNC char *normalize_slashes(char *path); | 1458 | ST_FUNC char *normalize_slashes(char *path); |
| 1269 | #endif | 1459 | #endif |
| 1270 | ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllname); | 1460 | ST_FUNC DLLReference *tcc_add_dllref(TCCState *S, const char *dllname); |
| 1271 | ST_FUNC char *tcc_load_text(int fd); | 1461 | ST_FUNC char *tcc_load_text(TCCState *S, int fd); |
| 1272 | 1462 | ||
| 1273 | /* tcc_parse_args return codes: */ | 1463 | /* tcc_parse_args return codes: */ |
| 1274 | #define OPT_HELP 1 | 1464 | #define OPT_HELP 1 |
| @@ -1282,18 +1472,6 @@ ST_FUNC char *tcc_load_text(int fd); · 7 unmodified lines | |||
| 1282 | 1472 | ||
| 1283 | /* ------------ tccpp.c ------------ */ | 1473 | /* ------------ tccpp.c ------------ */ |
| 1284 | 1474 | ||
| 1285 | ST_DATA struct BufferedFile *file; | ||
| 1286 | ST_DATA int ch, tok; | ||
| 1287 | ST_DATA CValue tokc; | ||
| 1288 | ST_DATA const int *macro_ptr; | ||
| 1289 | ST_DATA int parse_flags; | ||
| 1290 | ST_DATA int tok_flags; | ||
| 1291 | ST_DATA CString tokcstr; /* current parsed string, if any */ | ||
| 1292 | |||
| 1293 | /* display benchmark infos */ | ||
| 1294 | ST_DATA int tok_ident; | ||
| 1295 | ST_DATA TokenSym **table_ident; | ||
| 1296 | |||
| 1297 | #define TOK_FLAG_BOL 0x0001 /* beginning of line before */ | 1475 | #define TOK_FLAG_BOL 0x0001 /* beginning of line before */ |
| 1298 | #define TOK_FLAG_BOF 0x0002 /* beginning of file before */ | 1476 | #define TOK_FLAG_BOF 0x0002 /* beginning of file before */ |
| 1299 | #define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */ | 1477 | #define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */ |
| @@ -1321,36 +1499,36 @@ enum line_macro_output_format { · 21 unmodified lines | |||
| 1321 | LINE_MACRO_OUTPUT_FORMAT_P10 = 11 | 1499 | LINE_MACRO_OUTPUT_FORMAT_P10 = 11 |
| 1322 | }; | 1500 | }; |
| 1323 | 1501 | ||
| 1324 | ST_FUNC TokenSym *tok_alloc(const char *str, int len); | 1502 | ST_FUNC TokenSym *tok_alloc(TCCState* S, const char *str, int len); |
| 1325 | ST_FUNC int tok_alloc_const(const char *str); | 1503 | ST_FUNC int tok_alloc_const(TCCState* S, const char *str); |
| 1326 | ST_FUNC const char *get_tok_str(int v, CValue *cv); | 1504 | ST_FUNC const char *get_tok_str(TCCState* S, int v, CValue *cv); |
| 1327 | ST_FUNC void begin_macro(TokenString *str, int alloc); | 1505 | ST_FUNC void begin_macro(TCCState* S, TokenString *str, int alloc); |
| 1328 | ST_FUNC void end_macro(void); | 1506 | ST_FUNC void end_macro(TCCState* S); |
| 1329 | ST_FUNC int set_idnum(int c, int val); | 1507 | ST_FUNC int set_idnum(TCCState* S, int c, int val); |
| 1330 | ST_INLN void tok_str_new(TokenString *s); | 1508 | ST_INLN void tok_str_new(TokenString *s); |
| 1331 | ST_FUNC TokenString *tok_str_alloc(void); | 1509 | ST_FUNC TokenString *tok_str_alloc(TCCState* S); |
| 1332 | ST_FUNC void tok_str_free(TokenString *s); | 1510 | ST_FUNC void tok_str_free(TCCState* S, TokenString *s); |
| 1333 | ST_FUNC void tok_str_free_str(int *str); | 1511 | ST_FUNC void tok_str_free_str(TCCState* S, int *str); |
| 1334 | ST_FUNC void tok_str_add(TokenString *s, int t); | 1512 | ST_FUNC void tok_str_add(TCCState* S, TokenString *s, int t); |
| 1335 | ST_FUNC void tok_str_add_tok(TokenString *s); | 1513 | ST_FUNC void tok_str_add_tok(TCCState* S, TokenString *s); |
| 1336 | ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg); | 1514 | ST_INLN void define_push(TCCState* S, int v, int macro_type, int *str, Sym *first_arg); |
| 1337 | ST_FUNC void define_undef(Sym *s); | 1515 | ST_FUNC void define_undef(TCCState* S, Sym *s); |
| 1338 | ST_INLN Sym *define_find(int v); | 1516 | ST_INLN Sym *define_find(TCCState* S, int v); |
| 1339 | ST_FUNC void free_defines(Sym *b); | 1517 | ST_FUNC void free_defines(TCCState* S, Sym *b); |
| 1340 | ST_FUNC Sym *label_find(int v); | 1518 | ST_FUNC Sym *label_find(TCCState* S, int v); |
| 1341 | ST_FUNC Sym *label_push(Sym **ptop, int v, int flags); | 1519 | ST_FUNC Sym *label_push(TCCState* S, Sym **ptop, int v, int flags); |
| 1342 | ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep); | 1520 | ST_FUNC void label_pop(TCCState* S, Sym **ptop, Sym *slast, int keep); |
| 1343 | ST_FUNC void parse_define(void); | 1521 | ST_FUNC void parse_define(TCCState* S); |
| 1344 | ST_FUNC void preprocess(int is_bof); | 1522 | ST_FUNC void preprocess(TCCState* S, int is_bof); |
| 1345 | ST_FUNC void next(void); | 1523 | ST_FUNC void next(TCCState* S); |
| 1346 | ST_INLN void unget_tok(int last_tok); | 1524 | ST_INLN void unget_tok(TCCState* S, int last_tok); |
| 1347 | ST_FUNC void preprocess_start(TCCState *s1, int filetype); | 1525 | ST_FUNC void preprocess_start(TCCState *S, int filetype); |
| 1348 | ST_FUNC void preprocess_end(TCCState *s1); | 1526 | ST_FUNC void preprocess_end(TCCState *S); |
| 1349 | ST_FUNC void tccpp_new(TCCState *s); | 1527 | ST_FUNC void tccpp_new(TCCState *S); |
| 1350 | ST_FUNC void tccpp_delete(TCCState *s); | 1528 | ST_FUNC void tccpp_delete(TCCState *S); |
| 1351 | ST_FUNC int tcc_preprocess(TCCState *s1); | 1529 | ST_FUNC int tcc_preprocess(TCCState *S); |
| 1352 | ST_FUNC void skip(int c); | 1530 | ST_FUNC void skip(TCCState* S, int c); |
| 1353 | ST_FUNC NORETURN void expect(const char *msg); | 1531 | ST_FUNC NORETURN void expect(TCCState* S, const char *msg); |
| 1354 | 1532 | ||
| 1355 | /* space excluding newline */ | 1533 | /* space excluding newline */ |
| 1356 | static inline int is_space(int ch) { | 1534 | static inline int is_space(int ch) { |
| @@ -1372,104 +1550,85 @@ static inline int toup(int c) { · 15 unmodified lines | |||
| 1372 | /* ------------ tccgen.c ------------ */ | 1550 | /* ------------ tccgen.c ------------ */ |
| 1373 | 1551 | ||
| 1374 | #define SYM_POOL_NB (8192 / sizeof(Sym)) | 1552 | #define SYM_POOL_NB (8192 / sizeof(Sym)) |
| 1553 | ST_FUNC void tcc_debug_start(TCCState *S); | ||
| 1554 | ST_FUNC void tcc_debug_end(TCCState *S); | ||
| 1555 | ST_FUNC void tcc_debug_bincl(TCCState *S); | ||
| 1556 | ST_FUNC void tcc_debug_eincl(TCCState *S); | ||
| 1557 | ST_FUNC void tcc_debug_putfile(TCCState *S, const char *filename); | ||
| 1375 | 1558 | ||
| 1376 | ST_DATA Sym *global_stack; | 1559 | ST_FUNC void tccgen_init(TCCState *S); |
| 1377 | ST_DATA Sym *local_stack; | 1560 | ST_FUNC int tccgen_compile(TCCState *S); |
| 1378 | ST_DATA Sym *local_label_stack; | 1561 | ST_FUNC void tccgen_finish(TCCState *S); |
| 1379 | ST_DATA Sym *global_label_stack; | 1562 | ST_FUNC void check_vstack(TCCState* S); |
| 1380 | ST_DATA Sym *define_stack; | ||
| 1381 | ST_DATA CType int_type, func_old_type, char_pointer_type; | ||
| 1382 | ST_DATA SValue *vtop; | ||
| 1383 | ST_DATA int rsym, anon_sym, ind, loc; | ||
| 1384 | ST_DATA char debug_modes; | ||
| 1385 | |||
| 1386 | ST_DATA int const_wanted; /* true if constant wanted */ | ||
| 1387 | ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */ | ||
| 1388 | ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */ | ||
| 1389 | ST_DATA CType func_vt; /* current function return type (used by return instruction) */ | ||
| 1390 | ST_DATA int func_var; /* true if current function is variadic */ | ||
| 1391 | ST_DATA int func_vc; | ||
| 1392 | ST_DATA const char *funcname; | ||
| 1393 | |||
| 1394 | ST_FUNC void tcc_debug_start(TCCState *s1); | ||
| 1395 | ST_FUNC void tcc_debug_end(TCCState *s1); | ||
| 1396 | ST_FUNC void tcc_debug_bincl(TCCState *s1); | ||
| 1397 | ST_FUNC void tcc_debug_eincl(TCCState *s1); | ||
| 1398 | ST_FUNC void tcc_debug_putfile(TCCState *s1, const char *filename); | ||
| 1399 | |||
| 1400 | ST_FUNC void tccgen_init(TCCState *s1); | ||
| 1401 | ST_FUNC int tccgen_compile(TCCState *s1); | ||
| 1402 | ST_FUNC void tccgen_finish(TCCState *s1); | ||
| 1403 | ST_FUNC void check_vstack(void); | ||
| 1404 | 1563 | ||
| 1405 | ST_INLN int is_float(int t); | 1564 | ST_INLN int is_float(int t); |
| 1406 | ST_FUNC int ieee_finite(double d); | 1565 | ST_FUNC int ieee_finite(double d); |
| 1407 | ST_FUNC int exact_log2p1(int i); | 1566 | ST_FUNC int exact_log2p1(int i); |
| 1408 | ST_FUNC void test_lvalue(void); | 1567 | ST_FUNC void test_lvalue(TCCState* S); |
| 1409 | 1568 | ||
| 1410 | ST_FUNC ElfSym *elfsym(Sym *); | 1569 | ST_FUNC ElfSym *elfsym(TCCState* S, Sym *); |
| 1411 | ST_FUNC void update_storage(Sym *sym); | 1570 | ST_FUNC void update_storage(TCCState* S, Sym *sym); |
| 1412 | ST_FUNC void put_extern_sym2(Sym *sym, int sh_num, addr_t value, unsigned long size, int can_add_underscore); | 1571 | ST_FUNC void put_extern_sym2(TCCState* S, Sym *sym, int sh_num, addr_t value, unsigned long size, int can_add_underscore); |
| 1413 | ST_FUNC void put_extern_sym(Sym *sym, Section *section, addr_t value, unsigned long size); | 1572 | ST_FUNC void put_extern_sym(TCCState* S, Sym *sym, Section *section, addr_t value, unsigned long size); |
| 1414 | #if PTR_SIZE == 4 | 1573 | #if PTR_SIZE == 4 |
| 1415 | ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type); | 1574 | ST_FUNC void greloc(TCCState* S, Section *s, Sym *sym, unsigned long offset, int type); |
| 1416 | #endif | 1575 | #endif |
| 1417 | ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type, addr_t addend); | 1576 | ST_FUNC void greloca(TCCState* S, Section *s, Sym *sym, unsigned long offset, int type, addr_t addend); |
| 1418 | 1577 | ||
| 1419 | ST_INLN void sym_free(Sym *sym); | 1578 | ST_INLN void sym_free(TCCState* S, Sym *sym); |
| 1420 | ST_FUNC Sym *sym_push(int v, CType *type, int r, int c); | 1579 | ST_FUNC Sym *sym_push(TCCState* S, int v, CType *type, int r, int c); |
| 1421 | ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep); | 1580 | ST_FUNC void sym_pop(TCCState* S, Sym **ptop, Sym *b, int keep); |
| 1422 | ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, int c); | 1581 | ST_FUNC Sym *sym_push2(TCCState* S, Sym **ps, int v, int t, int c); |
| 1423 | ST_FUNC Sym *sym_find2(Sym *s, int v); | 1582 | ST_FUNC Sym *sym_find2(Sym *s, int v); |
| 1424 | ST_INLN Sym *sym_find(int v); | 1583 | ST_INLN Sym *sym_find(TCCState* S, int v); |
| 1425 | ST_INLN Sym *struct_find(int v); | 1584 | ST_INLN Sym *struct_find(TCCState* S, int v); |
| 1426 | 1585 | ||
| 1427 | ST_FUNC Sym *global_identifier_push(int v, int t, int c); | 1586 | ST_FUNC Sym *global_identifier_push(TCCState* S, int v, int t, int c); |
| 1428 | ST_FUNC Sym *external_global_sym(int v, CType *type); | 1587 | ST_FUNC Sym *external_global_sym(TCCState* S, int v, CType *type); |
| 1429 | ST_FUNC Sym *external_helper_sym(int v); | 1588 | ST_FUNC Sym *external_helper_sym(TCCState* S, int v); |
| 1430 | ST_FUNC void vpush_helper_func(int v); | 1589 | ST_FUNC void vpush_helper_func(TCCState* S, int v); |
| 1431 | ST_FUNC void vset(CType *type, int r, int v); | 1590 | ST_FUNC void vset(TCCState* S, CType *type, int r, int v); |
| 1432 | ST_FUNC void vset_VT_CMP(int op); | 1591 | ST_FUNC void vset_VT_CMP(TCCState* S, int op); |
| 1433 | ST_FUNC void vpushi(int v); | 1592 | ST_FUNC void vpushi(TCCState* S, int v); |
| 1434 | ST_FUNC void vpushv(SValue *v); | 1593 | ST_FUNC void vpushv(TCCState* S, SValue *v); |
| 1435 | ST_FUNC void vpushsym(CType *type, Sym *sym); | 1594 | ST_FUNC void vpushsym(TCCState* S, CType *type, Sym *sym); |
| 1436 | ST_FUNC void vswap(void); | 1595 | ST_FUNC void vswap(TCCState* S); |
| 1437 | ST_FUNC void vrote(SValue *e, int n); | 1596 | ST_FUNC void vrote(TCCState* S, SValue *e, int n); |
| 1438 | ST_FUNC void vrott(int n); | 1597 | ST_FUNC void vrott(TCCState* S, int n); |
| 1439 | ST_FUNC void vrotb(int n); | 1598 | ST_FUNC void vrotb(TCCState* S, int n); |
| 1440 | ST_FUNC void vpop(void); | 1599 | ST_FUNC void vpop(TCCState* S); |
| 1441 | #if PTR_SIZE == 4 | 1600 | #if PTR_SIZE == 4 |
| 1442 | ST_FUNC void lexpand(void); | 1601 | ST_FUNC void lexpand(TCCState* S); |
| 1443 | #endif | 1602 | #endif |
| 1444 | #ifdef TCC_TARGET_ARM | 1603 | #ifdef TCC_TARGET_ARM |
| 1445 | ST_FUNC int get_reg_ex(int rc, int rc2); | 1604 | ST_FUNC int get_reg_ex(TCCState* S, int rc, int rc2); |
| 1446 | #endif | 1605 | #endif |
| 1447 | ST_FUNC void save_reg(int r); | 1606 | ST_FUNC void save_reg(TCCState* S, int r); |
| 1448 | ST_FUNC void save_reg_upstack(int r, int n); | 1607 | ST_FUNC void save_reg_upstack(TCCState* S, int r, int n); |
| 1449 | ST_FUNC int get_reg(int rc); | 1608 | ST_FUNC int get_reg(TCCState* S, int rc); |
| 1450 | ST_FUNC void save_regs(int n); | 1609 | ST_FUNC void save_regs(TCCState* S, int n); |
| 1451 | ST_FUNC void gaddrof(void); | 1610 | ST_FUNC void gaddrof(TCCState* S); |
| 1452 | ST_FUNC int gv(int rc); | 1611 | ST_FUNC int gv(TCCState* S, int rc); |
| 1453 | ST_FUNC void gv2(int rc1, int rc2); | 1612 | ST_FUNC void gv2(TCCState* S, int rc1, int rc2); |
| 1454 | ST_FUNC void gen_op(int op); | 1613 | ST_FUNC void gen_op(TCCState* S, int op); |
| 1455 | ST_FUNC int type_size(CType *type, int *a); | 1614 | ST_FUNC int type_size(CType *type, int *a); |
| 1456 | ST_FUNC void mk_pointer(CType *type); | 1615 | ST_FUNC void mk_pointer(TCCState* S, CType *type); |
| 1457 | ST_FUNC void vstore(void); | 1616 | ST_FUNC void vstore(TCCState* S); |
| 1458 | ST_FUNC void inc(int post, int c); | 1617 | ST_FUNC void inc(TCCState* S, int post, int c); |
| 1459 | ST_FUNC void parse_mult_str (CString *astr, const char *msg); | 1618 | ST_FUNC void parse_mult_str (TCCState* S, CString *astr, const char *msg); |
| 1460 | ST_FUNC void parse_asm_str(CString *astr); | 1619 | ST_FUNC void parse_asm_str(TCCState* S, CString *astr); |
| 1461 | ST_FUNC void indir(void); | 1620 | ST_FUNC void indir(TCCState* S); |
| 1462 | ST_FUNC void unary(void); | 1621 | ST_FUNC void unary(TCCState* S); |
| 1463 | ST_FUNC void gexpr(void); | 1622 | ST_FUNC void gexpr(TCCState* S); |
| 1464 | ST_FUNC int expr_const(void); | 1623 | ST_FUNC int expr_const(TCCState* S); |
| 1465 | #if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C67 | 1624 | #if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C67 |
| 1466 | ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size); | 1625 | ST_FUNC Sym *get_sym_ref(TCCState* S, CType *type, Section *sec, unsigned long offset, unsigned long size); |
| 1467 | #endif | 1626 | #endif |
| 1468 | #if defined TCC_TARGET_X86_64 && !defined TCC_TARGET_PE | 1627 | #if defined TCC_TARGET_X86_64 && !defined TCC_TARGET_PE |
| 1469 | ST_FUNC int classify_x86_64_va_arg(CType *ty); | 1628 | ST_FUNC int classify_x86_64_va_arg(CType *ty); |
| 1470 | #endif | 1629 | #endif |
| 1471 | #ifdef CONFIG_TCC_BCHECK | 1630 | #ifdef CONFIG_TCC_BCHECK |
| 1472 | ST_FUNC void gbound_args(int nb_args); | 1631 | ST_FUNC void gbound_args(TCCState* S, int nb_args); |
| 1473 | ST_DATA int func_bound_add_epilog; | 1632 | ST_DATA int func_bound_add_epilog; |
| 1474 | #endif | 1633 | #endif |
| 1475 | 1634 | ||
| @@ -1489,51 +1648,51 @@ typedef struct { · 13 unmodified lines | |||
| 1489 | unsigned int n_value; /* value of symbol */ | 1648 | unsigned int n_value; /* value of symbol */ |
| 1490 | } Stab_Sym; | 1649 | } Stab_Sym; |
| 1491 | 1650 | ||
| 1492 | ST_FUNC void tccelf_new(TCCState *s); | 1651 | ST_FUNC void tccelf_new(TCCState *S); |
| 1493 | ST_FUNC void tccelf_delete(TCCState *s); | 1652 | ST_FUNC void tccelf_delete(TCCState *S); |
| 1494 | ST_FUNC void tccelf_stab_new(TCCState *s); | 1653 | ST_FUNC void tccelf_stab_new(TCCState *S); |
| 1495 | ST_FUNC void tccelf_begin_file(TCCState *s1); | 1654 | ST_FUNC void tccelf_begin_file(TCCState *S); |
| 1496 | ST_FUNC void tccelf_end_file(TCCState *s1); | 1655 | ST_FUNC void tccelf_end_file(TCCState *S); |
| 1497 | #ifdef CONFIG_TCC_BCHECK | 1656 | #ifdef CONFIG_TCC_BCHECK |
| 1498 | ST_FUNC void tccelf_bounds_new(TCCState *s); | 1657 | ST_FUNC void tccelf_bounds_new(TCCState *S); |
| 1499 | #endif | 1658 | #endif |
| 1500 | ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags); | 1659 | ST_FUNC Section *new_section(TCCState *S, const char *name, int sh_type, int sh_flags); |
| 1501 | ST_FUNC void section_realloc(Section *sec, unsigned long new_size); | 1660 | ST_FUNC void section_realloc(TCCState* S, Section *sec, unsigned long new_size); |
| 1502 | ST_FUNC size_t section_add(Section *sec, addr_t size, int align); | 1661 | ST_FUNC size_t section_add(TCCState* S, Section *sec, addr_t size, int align); |
| 1503 | ST_FUNC void *section_ptr_add(Section *sec, addr_t size); | 1662 | ST_FUNC void *section_ptr_add(TCCState* S, Section *sec, addr_t size); |
| 1504 | ST_FUNC Section *find_section(TCCState *s1, const char *name); | 1663 | ST_FUNC Section *find_section(TCCState *S, const char *name); |
| 1505 | ST_FUNC Section *new_symtab(TCCState *s1, const char *symtab_name, int sh_type, int sh_flags, const char *strtab_name, const char *hash_name, int hash_sh_flags); | 1664 | ST_FUNC Section *new_symtab(TCCState *S, const char *symtab_name, int sh_type, int sh_flags, const char *strtab_name, const char *hash_name, int hash_sh_flags); |
| 1506 | 1665 | ||
| 1507 | ST_FUNC int put_elf_str(Section *s, const char *sym); | 1666 | ST_FUNC int put_elf_str(TCCState* S, Section *s, const char *sym); |
| 1508 | ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int shndx, const char *name); | 1667 | ST_FUNC int put_elf_sym(TCCState* S, Section *s, addr_t value, unsigned long size, int info, int other, int shndx, const char *name); |
| 1509 | ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int shndx, const char *name); | 1668 | ST_FUNC int set_elf_sym(Section *S, addr_t value, unsigned long size, int info, int other, int shndx, const char *name); |
| 1510 | ST_FUNC int find_elf_sym(Section *s, const char *name); | 1669 | ST_FUNC int find_elf_sym(Section *S, const char *name); |
| 1511 | ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, int type, int symbol); | 1670 | ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, int type, int symbol); |
| 1512 | ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset, int type, int symbol, addr_t addend); | 1671 | ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset, int type, int symbol, addr_t addend); |
| 1513 | 1672 | ||
| 1514 | ST_FUNC void put_stabs(TCCState *s1, const char *str, int type, int other, int desc, unsigned long value); | 1673 | ST_FUNC void put_stabs(TCCState *S, const char *str, int type, int other, int desc, unsigned long value); |
| 1515 | ST_FUNC void put_stabs_r(TCCState *s1, const char *str, int type, int other, int desc, unsigned long value, Section *sec, int sym_index); | 1674 | ST_FUNC void put_stabs_r(TCCState *S, const char *str, int type, int other, int desc, unsigned long value, Section *sec, int sym_index); |
| 1516 | ST_FUNC void put_stabn(TCCState *s1, int type, int other, int desc, int value); | 1675 | ST_FUNC void put_stabn(TCCState *S, int type, int other, int desc, int value); |
| 1517 | 1676 | ||
| 1518 | ST_FUNC void resolve_common_syms(TCCState *s1); | 1677 | ST_FUNC void resolve_common_syms(TCCState *S); |
| 1519 | ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve); | 1678 | ST_FUNC void relocate_syms(TCCState *S, Section *symtab, int do_resolve); |
| 1520 | ST_FUNC void relocate_sections(TCCState *s1); | 1679 | ST_FUNC void relocate_sections(TCCState *S); |
| 1521 | 1680 | ||
| 1522 | ST_FUNC ssize_t full_read(int fd, void *buf, size_t count); | 1681 | ST_FUNC ssize_t full_read(int fd, void *buf, size_t count); |
| 1523 | ST_FUNC void *load_data(int fd, unsigned long file_offset, unsigned long size); | 1682 | ST_FUNC void *load_data(TCCState* S, int fd, unsigned long file_offset, unsigned long size); |
| 1524 | ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h); | 1683 | ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h); |
| 1525 | ST_FUNC int tcc_load_object_file(TCCState *s1, int fd, unsigned long file_offset); | 1684 | ST_FUNC int tcc_load_object_file(TCCState *S, int fd, unsigned long file_offset); |
| 1526 | ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte); | 1685 | ST_FUNC int tcc_load_archive(TCCState *S, int fd, int alacarte); |
| 1527 | ST_FUNC void add_array(TCCState *s1, const char *sec, int c); | 1686 | ST_FUNC void add_array(TCCState *S, const char *sec, int c); |
| 1528 | 1687 | ||
| 1529 | #if !defined(ELF_OBJ_ONLY) || (defined(TCC_TARGET_MACHO) && defined TCC_IS_NATIVE) | 1688 | #if !defined(ELF_OBJ_ONLY) || (defined(TCC_TARGET_MACHO) && defined TCC_IS_NATIVE) |
| 1530 | ST_FUNC void build_got_entries(TCCState *s1); | 1689 | ST_FUNC void build_got_entries(TCCState *S); |
| 1531 | #endif | 1690 | #endif |
| 1532 | ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc); | 1691 | ST_FUNC struct sym_attr *get_sym_attr(TCCState *S, int index, int alloc); |
| 1533 | ST_FUNC addr_t get_sym_addr(TCCState *s, const char *name, int err, int forc); | 1692 | ST_FUNC addr_t get_sym_addr(TCCState *S, const char *name, int err, int forc); |
| 1534 | ST_FUNC void list_elf_symbols(TCCState *s, void *ctx, | 1693 | ST_FUNC void list_elf_symbols(TCCState *S, void *ctx, |
| 1535 | void (*symbol_cb)(void *ctx, const char *name, const void *val)); | 1694 | void (*symbol_cb)(void *ctx, const char *name, const void *val)); |
| 1536 | ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs); | 1695 | ST_FUNC int set_global_sym(TCCState *S, const char *name, Section *sec, addr_t offs); |
| 1537 | 1696 | ||
| 1538 | /* Browse each elem of type <type> in section <sec> starting at elem <startoff> | 1697 | /* Browse each elem of type <type> in section <sec> starting at elem <startoff> |
| 1539 | using variable <elem> */ | 1698 | using variable <elem> */ |
| @@ -1542,11 +1701,11 @@ ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t · 2 unmodified lines | |||
| 1542 | elem < (type *) (sec->data + sec->data_offset); elem++) | 1701 | elem < (type *) (sec->data + sec->data_offset); elem++) |
| 1543 | 1702 | ||
| 1544 | #ifndef ELF_OBJ_ONLY | 1703 | #ifndef ELF_OBJ_ONLY |
| 1545 | ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level); | 1704 | ST_FUNC int tcc_load_dll(TCCState *S, int fd, const char *filename, int level); |
| 1546 | ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd); | 1705 | ST_FUNC int tcc_load_ldscript(TCCState *S, int fd); |
| 1547 | #endif | 1706 | #endif |
| 1548 | #ifndef TCC_TARGET_PE | 1707 | #ifndef TCC_TARGET_PE |
| 1549 | ST_FUNC void tcc_add_runtime(TCCState *s1); | 1708 | ST_FUNC void tcc_add_runtime(TCCState *S); |
| 1550 | #endif | 1709 | #endif |
| 1551 | 1710 | ||
| 1552 | /* ------------ xxx-link.c ------------ */ | 1711 | /* ------------ xxx-link.c ------------ */ |
| @@ -1564,41 +1723,41 @@ enum gotplt_entry { · 11 unmodified lines | |||
| 1564 | ST_FUNC int code_reloc (int reloc_type); | 1723 | ST_FUNC int code_reloc (int reloc_type); |
| 1565 | ST_FUNC int gotplt_entry_type (int reloc_type); | 1724 | ST_FUNC int gotplt_entry_type (int reloc_type); |
| 1566 | #if !defined(TCC_TARGET_MACHO) || defined TCC_IS_NATIVE | 1725 | #if !defined(TCC_TARGET_MACHO) || defined TCC_IS_NATIVE |
| 1567 | ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr); | 1726 | ST_FUNC unsigned create_plt_entry(TCCState *S, unsigned got_offset, struct sym_attr *attr); |
| 1568 | ST_FUNC void relocate_plt(TCCState *s1); | 1727 | ST_FUNC void relocate_plt(TCCState *S); |
| 1569 | #endif | 1728 | #endif |
| 1570 | #endif | 1729 | #endif |
| 1571 | ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val); | 1730 | ST_FUNC void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val); |
| 1572 | 1731 | ||
| 1573 | /* ------------ xxx-gen.c ------------ */ | 1732 | /* ------------ xxx-gen.c ------------ */ |
| 1574 | ST_DATA const char * const target_machine_defs; | 1733 | ST_DATA const char * const target_machine_defs; |
| 1575 | ST_DATA const int reg_classes[NB_REGS]; | 1734 | ST_DATA const int reg_classes[NB_REGS]; |
| 1576 | 1735 | ||
| 1577 | ST_FUNC void gsym_addr(int t, int a); | 1736 | ST_FUNC void gsym_addr(TCCState* S, int t, int a); |
| 1578 | ST_FUNC void gsym(int t); | 1737 | ST_FUNC void gsym(TCCState* S, int t); |
| 1579 | ST_FUNC void load(int r, SValue *sv); | 1738 | ST_FUNC void load(TCCState *S, int r, SValue *sv); |
| 1580 | ST_FUNC void store(int r, SValue *v); | 1739 | ST_FUNC void store(TCCState *S, int r, SValue *v); |
| 1581 | ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *align, int *regsize); | 1740 | ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *align, int *regsize); |
| 1582 | ST_FUNC void gfunc_call(int nb_args); | 1741 | ST_FUNC void gfunc_call(TCCState *S, int nb_args); |
| 1583 | ST_FUNC void gfunc_prolog(Sym *func_sym); | 1742 | ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym); |
| 1584 | ST_FUNC void gfunc_epilog(void); | 1743 | ST_FUNC void gfunc_epilog(TCCState *S); |
| 1585 | ST_FUNC void gen_fill_nops(int); | 1744 | ST_FUNC void gen_fill_nops(TCCState* S, int); |
| 1586 | ST_FUNC int gjmp(int t); | 1745 | ST_FUNC int gjmp(TCCState* S, int t); |
| 1587 | ST_FUNC void gjmp_addr(int a); | 1746 | ST_FUNC void gjmp_addr(TCCState* S, int a); |
| 1588 | ST_FUNC int gjmp_cond(int op, int t); | 1747 | ST_FUNC int gjmp_cond(TCCState* S, int op, int t); |
| 1589 | ST_FUNC int gjmp_append(int n, int t); | 1748 | ST_FUNC int gjmp_append(TCCState *S, int n, int t); |
| 1590 | ST_FUNC void gen_opi(int op); | 1749 | ST_FUNC void gen_opi(TCCState* S, int op); |
| 1591 | ST_FUNC void gen_opf(int op); | 1750 | ST_FUNC void gen_opf(TCCState* S, int op); |
| 1592 | ST_FUNC void gen_cvt_ftoi(int t); | 1751 | ST_FUNC void gen_cvt_ftoi(TCCState *S, int t); |
| 1593 | ST_FUNC void gen_cvt_itof(int t); | 1752 | ST_FUNC void gen_cvt_itof(TCCState *S, int t); |
| 1594 | ST_FUNC void gen_cvt_ftof(int t); | 1753 | ST_FUNC void gen_cvt_ftof(TCCState *S, int t); |
| 1595 | ST_FUNC void ggoto(void); | 1754 | ST_FUNC void ggoto(TCCState *S); |
| 1596 | #ifndef TCC_TARGET_C67 | 1755 | #ifndef TCC_TARGET_C67 |
| 1597 | ST_FUNC void o(unsigned int c); | 1756 | ST_FUNC void o(TCCState* S, unsigned int c); |
| 1598 | #endif | 1757 | #endif |
| 1599 | ST_FUNC void gen_vla_sp_save(int addr); | 1758 | ST_FUNC void gen_vla_sp_save(TCCState* S, int addr); |
| 1600 | ST_FUNC void gen_vla_sp_restore(int addr); | 1759 | ST_FUNC void gen_vla_sp_restore(TCCState* S, int addr); |
| 1601 | ST_FUNC void gen_vla_alloc(CType *type, int align); | 1760 | ST_FUNC void gen_vla_alloc(TCCState* S, CType *type, int align); |
| 1602 | 1761 | ||
| 1603 | static inline uint16_t read16le(unsigned char *p) { | 1762 | static inline uint16_t read16le(unsigned char *p) { |
| 1604 | return p[0] | (uint16_t)p[1] << 8; | 1763 | return p[0] | (uint16_t)p[1] << 8; |
| @@ -1627,57 +1786,57 @@ static inline void add64le(unsigned char *p, int64_t x) { · 22 unmodified lines | |||
| 1627 | 1786 | ||
| 1628 | /* ------------ i386-gen.c ------------ */ | 1787 | /* ------------ i386-gen.c ------------ */ |
| 1629 | #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM | 1788 | #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM |
| 1630 | ST_FUNC void g(int c); | 1789 | ST_FUNC void g(TCCState* S, int c); |
| 1631 | ST_FUNC void gen_le16(int c); | 1790 | ST_FUNC void gen_le16(TCCState* S, int c); |
| 1632 | ST_FUNC void gen_le32(int c); | 1791 | ST_FUNC void gen_le32(TCCState* S, int c); |
| 1633 | #endif | 1792 | #endif |
| 1634 | #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 | 1793 | #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 |
| 1635 | ST_FUNC void gen_addr32(int r, Sym *sym, int c); | 1794 | ST_FUNC void gen_addr32(TCCState* S, int r, Sym *sym, int c); |
| 1636 | ST_FUNC void gen_addrpc32(int r, Sym *sym, int c); | 1795 | ST_FUNC void gen_addrpc32(TCCState* S, int r, Sym *sym, int c); |
| 1637 | ST_FUNC void gen_cvt_csti(int t); | 1796 | ST_FUNC void gen_cvt_csti(TCCState* S, int t); |
| 1638 | ST_FUNC void gen_increment_tcov (SValue *sv); | 1797 | ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv); |
| 1639 | #endif | 1798 | #endif |
| 1640 | 1799 | ||
| 1641 | /* ------------ x86_64-gen.c ------------ */ | 1800 | /* ------------ x86_64-gen.c ------------ */ |
| 1642 | #ifdef TCC_TARGET_X86_64 | 1801 | #ifdef TCC_TARGET_X86_64 |
| 1643 | ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c); | 1802 | ST_FUNC void gen_addr64(TCCState* S, int r, Sym *sym, int64_t c); |
| 1644 | ST_FUNC void gen_opl(int op); | 1803 | ST_FUNC void gen_opl(TCCState* S, int op); |
| 1645 | #ifdef TCC_TARGET_PE | 1804 | #ifdef TCC_TARGET_PE |
| 1646 | ST_FUNC void gen_vla_result(int addr); | 1805 | ST_FUNC void gen_vla_result(TCCState* S, int addr); |
| 1647 | #endif | 1806 | #endif |
| 1648 | ST_FUNC void gen_cvt_sxtw(void); | 1807 | ST_FUNC void gen_cvt_sxtw(TCCState *S); |
| 1649 | ST_FUNC void gen_cvt_csti(int t); | 1808 | ST_FUNC void gen_cvt_csti(TCCState* S, int t); |
| 1650 | #endif | 1809 | #endif |
| 1651 | 1810 | ||
| 1652 | /* ------------ arm-gen.c ------------ */ | 1811 | /* ------------ arm-gen.c ------------ */ |
| 1653 | #ifdef TCC_TARGET_ARM | 1812 | #ifdef TCC_TARGET_ARM |
| 1654 | #if defined(TCC_ARM_EABI) && !defined(CONFIG_TCC_ELFINTERP) | 1813 | #if defined(TCC_ARM_EABI) && !defined(CONFIG_TCC_ELFINTERP) |
| 1655 | PUB_FUNC const char *default_elfinterp(struct TCCState *s); | 1814 | PUB_FUNC const char *default_elfinterp(TCCState *S); |
| 1656 | #endif | 1815 | #endif |
| 1657 | ST_FUNC void arm_init(struct TCCState *s); | 1816 | ST_FUNC void arm_init(TCCState *S); |
| 1658 | ST_FUNC void gen_increment_tcov (SValue *sv); | 1817 | ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv); |
| 1659 | #endif | 1818 | #endif |
| 1660 | 1819 | ||
| 1661 | /* ------------ arm64-gen.c ------------ */ | 1820 | /* ------------ arm64-gen.c ------------ */ |
| 1662 | #ifdef TCC_TARGET_ARM64 | 1821 | #ifdef TCC_TARGET_ARM64 |
| 1663 | ST_FUNC void gen_opl(int op); | 1822 | ST_FUNC void gen_opl(TCCState* S, int op); |
| 1664 | ST_FUNC void gfunc_return(CType *func_type); | 1823 | ST_FUNC void gfunc_return(TCCState *S, CType *func_type); |
| 1665 | ST_FUNC void gen_va_start(void); | 1824 | ST_FUNC void gen_va_start(TCCState *S); |
| 1666 | ST_FUNC void gen_va_arg(CType *t); | 1825 | ST_FUNC void gen_va_arg(TCCState *S, CType *t); |
| 1667 | ST_FUNC void gen_clear_cache(void); | 1826 | ST_FUNC void gen_clear_cache(TCCState *S); |
| 1668 | ST_FUNC void gen_cvt_sxtw(void); | 1827 | ST_FUNC void gen_cvt_sxtw(TCCState *S); |
| 1669 | ST_FUNC void gen_cvt_csti(int t); | 1828 | ST_FUNC void gen_cvt_csti(TCCState *S, int t); |
| 1670 | ST_FUNC void gen_increment_tcov (SValue *sv); | 1829 | ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv); |
| 1671 | #endif | 1830 | #endif |
| 1672 | 1831 | ||
| 1673 | /* ------------ riscv64-gen.c ------------ */ | 1832 | /* ------------ riscv64-gen.c ------------ */ |
| 1674 | #ifdef TCC_TARGET_RISCV64 | 1833 | #ifdef TCC_TARGET_RISCV64 |
| 1675 | ST_FUNC void gen_opl(int op); | 1834 | ST_FUNC void gen_opl(TCCState* S, int op); |
| 1676 | //ST_FUNC void gfunc_return(CType *func_type); | 1835 | //ST_FUNC void gfunc_return(TCCState *S, CType *func_type); |
| 1677 | ST_FUNC void gen_va_start(void); | 1836 | ST_FUNC void gen_va_start(TCCState *S); |
| 1678 | ST_FUNC void arch_transfer_ret_regs(int); | 1837 | ST_FUNC void arch_transfer_ret_regs(TCCState* S, int); |
| 1679 | ST_FUNC void gen_cvt_sxtw(void); | 1838 | ST_FUNC void gen_cvt_sxtw(TCCState *S); |
| 1680 | ST_FUNC void gen_increment_tcov (SValue *sv); | 1839 | ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv); |
| 1681 | #endif | 1840 | #endif |
| 1682 | 1841 | ||
| 1683 | /* ------------ c67-gen.c ------------ */ | 1842 | /* ------------ c67-gen.c ------------ */ |
| @@ -1687,44 +1846,44 @@ ST_FUNC void gen_increment_tcov (SValue *sv); · 3 unmodified lines | |||
| 1687 | /* ------------ tcccoff.c ------------ */ | 1846 | /* ------------ tcccoff.c ------------ */ |
| 1688 | 1847 | ||
| 1689 | #ifdef TCC_TARGET_COFF | 1848 | #ifdef TCC_TARGET_COFF |
| 1690 | ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f); | 1849 | ST_FUNC int tcc_output_coff(TCCState *S, FILE *f); |
| 1691 | ST_FUNC int tcc_load_coff(TCCState * s1, int fd); | 1850 | ST_FUNC int tcc_load_coff(TCCState *S, int fd); |
| 1692 | #endif | 1851 | #endif |
| 1693 | 1852 | ||
| 1694 | /* ------------ tccasm.c ------------ */ | 1853 | /* ------------ tccasm.c ------------ */ |
| 1695 | ST_FUNC void asm_instr(void); | 1854 | ST_FUNC void asm_instr(TCCState* S); |
| 1696 | ST_FUNC void asm_global_instr(void); | 1855 | ST_FUNC void asm_global_instr(TCCState* S); |
| 1697 | ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess); | 1856 | ST_FUNC int tcc_assemble(TCCState *S, int do_preprocess); |
| 1698 | #ifdef CONFIG_TCC_ASM | 1857 | #ifdef CONFIG_TCC_ASM |
| 1699 | ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands, const char *name, const char **pp); | 1858 | ST_FUNC int find_constraint(TCCState* S, ASMOperand *operands, int nb_operands, const char *name, const char **pp); |
| 1700 | ST_FUNC Sym* get_asm_sym(int name, Sym *csym); | 1859 | ST_FUNC Sym* get_asm_sym(TCCState* S, int name, Sym *csym); |
| 1701 | ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe); | 1860 | ST_FUNC void asm_expr(TCCState *S, ExprValue *pe); |
| 1702 | ST_FUNC int asm_int_expr(TCCState *s1); | 1861 | ST_FUNC int asm_int_expr(TCCState *S); |
| 1703 | /* ------------ i386-asm.c ------------ */ | 1862 | /* ------------ i386-asm.c ------------ */ |
| 1704 | ST_FUNC void gen_expr32(ExprValue *pe); | 1863 | ST_FUNC void gen_expr32(TCCState* S, ExprValue *pe); |
| 1705 | #ifdef TCC_TARGET_X86_64 | 1864 | #ifdef TCC_TARGET_X86_64 |
| 1706 | ST_FUNC void gen_expr64(ExprValue *pe); | 1865 | ST_FUNC void gen_expr64(TCCState* S, ExprValue *pe); |
| 1707 | #endif | 1866 | #endif |
| 1708 | ST_FUNC void asm_opcode(TCCState *s1, int opcode); | 1867 | ST_FUNC void asm_opcode(TCCState *S, int opcode); |
| 1709 | ST_FUNC int asm_parse_regvar(int t); | 1868 | ST_FUNC int asm_parse_regvar(TCCState* S, int t); |
| 1710 | ST_FUNC void asm_compute_constraints(ASMOperand *operands, int nb_operands, int nb_outputs, const uint8_t *clobber_regs, int *pout_reg); | 1869 | ST_FUNC void asm_compute_constraints(TCCState* S, ASMOperand *operands, int nb_operands, int nb_outputs, const uint8_t *clobber_regs, int *pout_reg); |
| 1711 | ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier); | 1870 | ST_FUNC void subst_asm_operand(TCCState* S, CString *add_str, SValue *sv, int modifier); |
| 1712 | ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, int nb_outputs, int is_output, uint8_t *clobber_regs, int out_reg); | 1871 | ST_FUNC void asm_gen_code(TCCState* S, ASMOperand *operands, int nb_operands, int nb_outputs, int is_output, uint8_t *clobber_regs, int out_reg); |
| 1713 | ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str); | 1872 | ST_FUNC void asm_clobber(TCCState* S, uint8_t *clobber_regs, const char *str); |
| 1714 | #endif | 1873 | #endif |
| 1715 | 1874 | ||
| 1716 | /* ------------ tccpe.c -------------- */ | 1875 | /* ------------ tccpe.c -------------- */ |
| 1717 | #ifdef TCC_TARGET_PE | 1876 | #ifdef TCC_TARGET_PE |
| 1718 | ST_FUNC int pe_load_file(struct TCCState *s1, int fd, const char *filename); | 1877 | ST_FUNC int pe_load_file(struct TCCState *S, int fd, const char *filename); |
| 1719 | ST_FUNC int pe_output_file(TCCState * s1, const char *filename); | 1878 | ST_FUNC int pe_output_file(TCCState * S, const char *filename); |
| 1720 | ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t value); | 1879 | ST_FUNC int pe_putimport(TCCState *S, int dllindex, const char *name, addr_t value); |
| 1721 | #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 | 1880 | #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 |
| 1722 | ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2); | 1881 | ST_FUNC SValue *pe_getimport(TCCState * S, SValue *sv, SValue *v2); |
| 1723 | #endif | 1882 | #endif |
| 1724 | #ifdef TCC_TARGET_X86_64 | 1883 | #ifdef TCC_TARGET_X86_64 |
| 1725 | ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack); | 1884 | ST_FUNC void pe_add_unwind_data(TCCState* S, unsigned start, unsigned end, unsigned stack); |
| 1726 | #endif | 1885 | #endif |
| 1727 | PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp); | 1886 | PUB_FUNC int tcc_get_dllexports(TCCState* S, const char *filename, char **pp); |
| 1728 | /* symbol properties stored in Elf32_Sym->st_other */ | 1887 | /* symbol properties stored in Elf32_Sym->st_other */ |
| 1729 | # define ST_PE_EXPORT 0x10 | 1888 | # define ST_PE_EXPORT 0x10 |
| 1730 | # define ST_PE_IMPORT 0x20 | 1889 | # define ST_PE_IMPORT 0x20 |
| @@ -1734,11 +1893,11 @@ PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp); · 3 unmodified lines | |||
| 1734 | 1893 | ||
| 1735 | /* ------------ tccmacho.c ----------------- */ | 1894 | /* ------------ tccmacho.c ----------------- */ |
| 1736 | #ifdef TCC_TARGET_MACHO | 1895 | #ifdef TCC_TARGET_MACHO |
| 1737 | ST_FUNC int macho_output_file(TCCState * s1, const char *filename); | 1896 | ST_FUNC int macho_output_file(TCCState * S, const char *filename); |
| 1738 | ST_FUNC int macho_load_dll(TCCState *s1, int fd, const char *filename, int lev); | 1897 | ST_FUNC int macho_load_dll(TCCState *S, int fd, const char *filename, int lev); |
| 1739 | ST_FUNC int macho_load_tbd(TCCState *s1, int fd, const char *filename, int lev); | 1898 | ST_FUNC int macho_load_tbd(TCCState *S, int fd, const char *filename, int lev); |
| 1740 | #ifdef TCC_IS_NATIVE | 1899 | #ifdef TCC_IS_NATIVE |
| 1741 | ST_FUNC void tcc_add_macos_sdkpath(TCCState* s); | 1900 | ST_FUNC void tcc_add_macos_sdkpath(TCCState* S); |
| 1742 | ST_FUNC const char* macho_tbd_soname(const char* filename); | 1901 | ST_FUNC const char* macho_tbd_soname(const char* filename); |
| 1743 | #endif | 1902 | #endif |
| 1744 | #endif | 1903 | #endif |
| @@ -1755,17 +1914,17 @@ ST_FUNC void dlclose(void *p); · 10 unmodified lines | |||
| 1755 | ST_FUNC const char *dlerror(void); | 1914 | ST_FUNC const char *dlerror(void); |
| 1756 | ST_FUNC void *dlsym(void *handle, const char *symbol); | 1915 | ST_FUNC void *dlsym(void *handle, const char *symbol); |
| 1757 | #endif | 1916 | #endif |
| 1758 | ST_FUNC void tcc_run_free(TCCState *s1); | 1917 | ST_FUNC void tcc_run_free(TCCState *S); |
| 1759 | #endif | 1918 | #endif |
| 1760 | 1919 | ||
| 1761 | /* ------------ tcctools.c ----------------- */ | 1920 | /* ------------ tcctools.c ----------------- */ |
| 1762 | #if 0 /* included in tcc.c */ | 1921 | #if 0 /* included in tcc.c */ |
| 1763 | ST_FUNC int tcc_tool_ar(TCCState *s, int argc, char **argv); | 1922 | ST_FUNC int tcc_tool_ar(TCCState *S, int argc, char **argv); |
| 1764 | #ifdef TCC_TARGET_PE | 1923 | #ifdef TCC_TARGET_PE |
| 1765 | ST_FUNC int tcc_tool_impdef(TCCState *s, int argc, char **argv); | 1924 | ST_FUNC int tcc_tool_impdef(TCCState *S, int argc, char **argv); |
| 1766 | #endif | 1925 | #endif |
| 1767 | ST_FUNC void tcc_tool_cross(TCCState *s, char **argv, int option); | 1926 | ST_FUNC void tcc_tool_cross(TCCState *S, char **argv, int option); |
| 1768 | ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename); | 1927 | ST_FUNC void gen_makedeps(TCCState *S, const char *target, const char *filename); |
| 1769 | #endif | 1928 | #endif |
| 1770 | 1929 | ||
| 1771 | /********************************************************/ | 1930 | /********************************************************/ |
| @@ -1820,12 +1979,12 @@ ST_FUNC void post_sem(TCCSem *p); · 48 unmodified lines | |||
| 1820 | #define total_lines TCC_STATE_VAR(total_lines) | 1979 | #define total_lines TCC_STATE_VAR(total_lines) |
| 1821 | #define total_bytes TCC_STATE_VAR(total_bytes) | 1980 | #define total_bytes TCC_STATE_VAR(total_bytes) |
| 1822 | 1981 | ||
| 1823 | PUB_FUNC void tcc_enter_state(TCCState *s1); | 1982 | PUB_FUNC void tcc_enter_state(TCCState *S); |
| 1824 | PUB_FUNC void tcc_exit_state(TCCState *s1); | 1983 | PUB_FUNC void tcc_exit_state(TCCState *S); |
| 1825 | 1984 | ||
| 1826 | /* conditional warning depending on switch */ | 1985 | /* conditional warning depending on switch */ |
| 1827 | #define tcc_warning_c(sw) TCC_SET_STATE((\ | 1986 | #define tcc_warning_c(sw) TCC_SET_STATE((\ |
| 1828 | tcc_state->warn_num = offsetof(TCCState, sw) \ | 1987 | S->warn_num = offsetof(TCCState, sw) \ |
| 1829 | - offsetof(TCCState, warn_none), _tcc_warning)) | 1988 | - offsetof(TCCState, warn_none), _tcc_warning)) |
| 1830 | 1989 | ||
| 1831 | /********************************************************/ | 1990 | /********************************************************/ |
| @@ -1835,10 +1994,10 @@ PUB_FUNC void tcc_exit_state(TCCState *s1); · 3 unmodified lines | |||
| 1835 | #undef TCC_SET_STATE | 1994 | #undef TCC_SET_STATE |
| 1836 | 1995 | ||
| 1837 | #ifdef USING_GLOBALS | 1996 | #ifdef USING_GLOBALS |
| 1838 | # define TCC_STATE_VAR(sym) tcc_state->sym | 1997 | # define TCC_STATE_VAR(sym) S->sym |
| 1839 | # define TCC_SET_STATE(fn) fn | 1998 | # define TCC_SET_STATE(fn) fn |
| 1840 | # undef USING_GLOBALS | 1999 | # undef USING_GLOBALS |
| 1841 | #else | 2000 | #else |
| 1842 | # define TCC_STATE_VAR(sym) s1->sym | 2001 | # define TCC_STATE_VAR(sym) S->sym |
| 1843 | # define TCC_SET_STATE(fn) (tcc_enter_state(s1),fn) | 2002 | # define TCC_SET_STATE(fn) (tcc_enter_state(S),fn) |
| 1844 | #endif | 2003 | #endif |
| @@ -22,18 +22,16 @@ · 21 unmodified lines | |||
| 22 | #include "tcc.h" | 22 | #include "tcc.h" |
| 23 | #ifdef CONFIG_TCC_ASM | 23 | #ifdef CONFIG_TCC_ASM |
| 24 | 24 | ||
| 25 | static Section *last_text_section; /* to handle .previous asm directive */ | 25 | ST_FUNC int asm_get_local_label_name(TCCState *S, unsigned int n) |
| 26 | |||
| 27 | ST_FUNC int asm_get_local_label_name(TCCState *s1, unsigned int n) | ||
| 28 | { | 26 | { |
| 29 | char buf[64]; | 27 | char buf[64]; |
| 30 | snprintf(buf, sizeof(buf), "L..%u", n); | 28 | snprintf(buf, sizeof(buf), "L..%u", n); |
| 31 | return tok_alloc_const(buf); | 29 | return tok_alloc_const(S, buf); |
| 32 | } | 30 | } |
| 33 | 31 | ||
| 34 | static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global); | 32 | static int tcc_assemble_internal(TCCState *S, int do_preprocess, int global); |
| 35 | static Sym* asm_new_label(TCCState *s1, int label, int is_local); | 33 | static Sym* asm_new_label(TCCState *S, int label, int is_local); |
| 36 | static Sym* asm_new_label1(TCCState *s1, int label, int is_local, int sh_num, int value); | 34 | static Sym* asm_new_label1(TCCState *S, int label, int is_local, int sh_num, int value); |
| 37 | 35 | ||
| 38 | /* If a C name has an _ prepended then only asm labels that start | 36 | /* If a C name has an _ prepended then only asm labels that start |
| 39 | with _ are representable in C, by removing the first _. ASM names | 37 | with _ are representable in C, by removing the first _. ASM names |
| @@ -41,44 +39,44 @@ static Sym* asm_new_label1(TCCState *s1, int label, int is_local, int sh_num, in · 1 unmodified line | |||
| 41 | the global C symbol table to track ASM names as well, so we need to | 39 | the global C symbol table to track ASM names as well, so we need to |
| 42 | transform those into ones that don't conflict with a C name, | 40 | transform those into ones that don't conflict with a C name, |
| 43 | so prepend a '.' for them, but force the ELF asm name to be set. */ | 41 | so prepend a '.' for them, but force the ELF asm name to be set. */ |
| 44 | static int asm2cname(int v, int *addeddot) | 42 | static int asm2cname(TCCState* S, int v, int *addeddot) |
| 45 | { | 43 | { |
| 46 | const char *name; | 44 | const char *name; |
| 47 | *addeddot = 0; | 45 | *addeddot = 0; |
| 48 | if (!tcc_state->leading_underscore) | 46 | if (!S->leading_underscore) |
| 49 | return v; | 47 | return v; |
| 50 | name = get_tok_str(v, NULL); | 48 | name = get_tok_str(S, v, NULL); |
| 51 | if (!name) | 49 | if (!name) |
| 52 | return v; | 50 | return v; |
| 53 | if (name[0] == '_') { | 51 | if (name[0] == '_') { |
| 54 | v = tok_alloc_const(name + 1); | 52 | v = tok_alloc_const(S, name + 1); |
| 55 | } else if (!strchr(name, '.')) { | 53 | } else if (!strchr(name, '.')) { |
| 56 | char newname[256]; | 54 | char newname[256]; |
| 57 | snprintf(newname, sizeof newname, ".%s", name); | 55 | snprintf(newname, sizeof newname, ".%s", name); |
| 58 | v = tok_alloc_const(newname); | 56 | v = tok_alloc_const(S, newname); |
| 59 | *addeddot = 1; | 57 | *addeddot = 1; |
| 60 | } | 58 | } |
| 61 | return v; | 59 | return v; |
| 62 | } | 60 | } |
| 63 | 61 | ||
| 64 | static Sym *asm_label_find(int v) | 62 | static Sym *asm_label_find(TCCState* S, int v) |
| 65 | { | 63 | { |
| 66 | Sym *sym; | 64 | Sym *sym; |
| 67 | int addeddot; | 65 | int addeddot; |
| 68 | v = asm2cname(v, &addeddot); | 66 | v = asm2cname(S, v, &addeddot); |
| 69 | sym = sym_find(v); | 67 | sym = sym_find(S, v); |
| 70 | while (sym && sym->sym_scope && !(sym->type.t & VT_STATIC)) | 68 | while (sym && sym->sym_scope && !(sym->type.t & VT_STATIC)) |
| 71 | sym = sym->prev_tok; | 69 | sym = sym->prev_tok; |
| 72 | return sym; | 70 | return sym; |
| 73 | } | 71 | } |
| 74 | 72 | ||
| 75 | static Sym *asm_label_push(int v) | 73 | static Sym *asm_label_push(TCCState* S, int v) |
| 76 | { | 74 | { |
| 77 | int addeddot, v2 = asm2cname(v, &addeddot); | 75 | int addeddot, v2 = asm2cname(S, v, &addeddot); |
| 78 | /* We always add VT_EXTERN, for sym definition that's tentative | 76 | /* We always add VT_EXTERN, for sym definition that's tentative |
| 79 | (for .set, removed for real defs), for mere references it's correct | 77 | (for .set, removed for real defs), for mere references it's correct |
| 80 | as is. */ | 78 | as is. */ |
| 81 | Sym *sym = global_identifier_push(v2, VT_ASM | VT_EXTERN | VT_STATIC, 0); | 79 | Sym *sym = global_identifier_push(S, v2, VT_ASM | VT_EXTERN | VT_STATIC, 0); |
| 82 | if (addeddot) | 80 | if (addeddot) |
| 83 | sym->asm_label = v; | 81 | sym->asm_label = v; |
| 84 | return sym; | 82 | return sym; |
| @@ -94,55 +92,55 @@ static Sym *asm_label_push(int v) · 9 unmodified lines | |||
| 94 | are anonymous in C, in this case CSYM can be used to transfer | 92 | are anonymous in C, in this case CSYM can be used to transfer |
| 95 | all information from that symbol to the (possibly newly created) | 93 | all information from that symbol to the (possibly newly created) |
| 96 | asm symbol. */ | 94 | asm symbol. */ |
| 97 | ST_FUNC Sym* get_asm_sym(int name, Sym *csym) | 95 | ST_FUNC Sym* get_asm_sym(TCCState* S, int name, Sym *csym) |
| 98 | { | 96 | { |
| 99 | Sym *sym = asm_label_find(name); | 97 | Sym *sym = asm_label_find(S, name); |
| 100 | if (!sym) { | 98 | if (!sym) { |
| 101 | sym = asm_label_push(name); | 99 | sym = asm_label_push(S, name); |
| 102 | if (csym) | 100 | if (csym) |
| 103 | sym->c = csym->c; | 101 | sym->c = csym->c; |
| 104 | } | 102 | } |
| 105 | return sym; | 103 | return sym; |
| 106 | } | 104 | } |
| 107 | 105 | ||
| 108 | static Sym* asm_section_sym(TCCState *s1, Section *sec) | 106 | static Sym* asm_section_sym(TCCState *S, Section *sec) |
| 109 | { | 107 | { |
| 110 | char buf[100]; int label; Sym *sym; | 108 | char buf[100]; int label; Sym *sym; |
| 111 | snprintf(buf, sizeof buf, "L.%s", sec->name); | 109 | snprintf(buf, sizeof buf, "L.%s", sec->name); |
| 112 | label = tok_alloc_const(buf); | 110 | label = tok_alloc_const(S, buf); |
| 113 | sym = asm_label_find(label); | 111 | sym = asm_label_find(S, label); |
| 114 | return sym ? sym : asm_new_label1(s1, label, 1, sec->sh_num, 0); | 112 | return sym ? sym : asm_new_label1(S, label, 1, sec->sh_num, 0); |
| 115 | } | 113 | } |
| 116 | 114 | ||
| 117 | /* We do not use the C expression parser to handle symbols. Maybe the | 115 | /* We do not use the C expression parser to handle symbols. Maybe the |
| 118 | C expression parser could be tweaked to do so. */ | 116 | C expression parser could be tweaked to do so. */ |
| 119 | 117 | ||
| 120 | static void asm_expr_unary(TCCState *s1, ExprValue *pe) | 118 | static void asm_expr_unary(TCCState *S, ExprValue *pe) |
| 121 | { | 119 | { |
| 122 | Sym *sym; | 120 | Sym *sym; |
| 123 | int op, label; | 121 | int op, label; |
| 124 | uint64_t n; | 122 | uint64_t n; |
| 125 | const char *p; | 123 | const char *p; |
| 126 | 124 | ||
| 127 | switch(tok) { | 125 | switch(S->tccpp_tok) { |
| 128 | case TOK_PPNUM: | 126 | case TOK_PPNUM: |
| 129 | p = tokc.str.data; | 127 | p = S->tccpp_tokc.str.data; |
| 130 | n = strtoull(p, (char **)&p, 0); | 128 | n = strtoull(p, (char **)&p, 0); |
| 131 | if (*p == 'b' || *p == 'f') { | 129 | if (*p == 'b' || *p == 'f') { |
| 132 | /* backward or forward label */ | 130 | /* backward or forward label */ |
| 133 | label = asm_get_local_label_name(s1, n); | 131 | label = asm_get_local_label_name(S, n); |
| 134 | sym = asm_label_find(label); | 132 | sym = asm_label_find(S, label); |
| 135 | if (*p == 'b') { | 133 | if (*p == 'b') { |
| 136 | /* backward : find the last corresponding defined label */ | 134 | /* backward : find the last corresponding defined label */ |
| 137 | if (sym && (!sym->c || elfsym(sym)->st_shndx == SHN_UNDEF)) | 135 | if (sym && (!sym->c || elfsym(S, sym)->st_shndx == SHN_UNDEF)) |
| 138 | sym = sym->prev_tok; | 136 | sym = sym->prev_tok; |
| 139 | if (!sym) | 137 | if (!sym) |
| 140 | tcc_error("local label '%d' not found backward", (int)n); | 138 | tcc_error(S, "local label '%d' not found backward", (int)n); |
| 141 | } else { | 139 | } else { |
| 142 | /* forward */ | 140 | /* forward */ |
| 143 | if (!sym || (sym->c && elfsym(sym)->st_shndx != SHN_UNDEF)) { | 141 | if (!sym || (sym->c && elfsym(S, sym)->st_shndx != SHN_UNDEF)) { |
| 144 | /* if the last label is defined, then define a new one */ | 142 | /* if the last label is defined, then define a new one */ |
| 145 | sym = asm_label_push(label); | 143 | sym = asm_label_push(S, label); |
| 146 | } | 144 | } |
| 147 | } | 145 | } |
| 148 | pe->v = 0; | 146 | pe->v = 0; |
| @@ -153,21 +151,21 @@ static void asm_expr_unary(TCCState *s1, ExprValue *pe) · 4 unmodified lines | |||
| 153 | pe->sym = NULL; | 151 | pe->sym = NULL; |
| 154 | pe->pcrel = 0; | 152 | pe->pcrel = 0; |
| 155 | } else { | 153 | } else { |
| 156 | tcc_error("invalid number syntax"); | 154 | tcc_error(S, "invalid number syntax"); |
| 157 | } | 155 | } |
| 158 | next(); | 156 | next(S); |
| 159 | break; | 157 | break; |
| 160 | case '+': | 158 | case '+': |
| 161 | next(); | 159 | next(S); |
| 162 | asm_expr_unary(s1, pe); | 160 | asm_expr_unary(S, pe); |
| 163 | break; | 161 | break; |
| 164 | case '-': | 162 | case '-': |
| 165 | case '~': | 163 | case '~': |
| 166 | op = tok; | 164 | op = S->tccpp_tok; |
| 167 | next(); | 165 | next(S); |
| 168 | asm_expr_unary(s1, pe); | 166 | asm_expr_unary(S, pe); |
| 169 | if (pe->sym) | 167 | if (pe->sym) |
| 170 | tcc_error("invalid operation with label"); | 168 | tcc_error(S, "invalid operation with label"); |
| 171 | if (op == '-') | 169 | if (op == '-') |
| 172 | pe->v = -pe->v; | 170 | pe->v = -pe->v; |
| 173 | else | 171 | else |
| @@ -175,28 +173,28 @@ static void asm_expr_unary(TCCState *s1, ExprValue *pe) · 1 unmodified line | |||
| 175 | break; | 173 | break; |
| 176 | case TOK_CCHAR: | 174 | case TOK_CCHAR: |
| 177 | case TOK_LCHAR: | 175 | case TOK_LCHAR: |
| 178 | pe->v = tokc.i; | 176 | pe->v = S->tccpp_tokc.i; |
| 179 | pe->sym = NULL; | 177 | pe->sym = NULL; |
| 180 | pe->pcrel = 0; | 178 | pe->pcrel = 0; |
| 181 | next(); | 179 | next(S); |
| 182 | break; | 180 | break; |
| 183 | case '(': | 181 | case '(': |
| 184 | next(); | 182 | next(S); |
| 185 | asm_expr(s1, pe); | 183 | asm_expr(S, pe); |
| 186 | skip(')'); | 184 | skip(S, ')'); |
| 187 | break; | 185 | break; |
| 188 | case '.': | 186 | case '.': |
| 189 | pe->v = ind; | 187 | pe->v = S->tccgen_ind; |
| 190 | pe->sym = asm_section_sym(s1, cur_text_section); | 188 | pe->sym = asm_section_sym(S, cur_text_section); |
| 191 | pe->pcrel = 0; | 189 | pe->pcrel = 0; |
| 192 | next(); | 190 | next(S); |
| 193 | break; | 191 | break; |
| 194 | default: | 192 | default: |
| 195 | if (tok >= TOK_IDENT) { | 193 | if (S->tccpp_tok >= TOK_IDENT) { |
| 196 | ElfSym *esym; | 194 | ElfSym *esym; |
| 197 | /* label case : if the label was not found, add one */ | 195 | /* label case : if the label was not found, add one */ |
| 198 | sym = get_asm_sym(tok, NULL); | 196 | sym = get_asm_sym(S, S->tccpp_tok, NULL); |
| 199 | esym = elfsym(sym); | 197 | esym = elfsym(S, sym); |
| 200 | if (esym && esym->st_shndx == SHN_ABS) { | 198 | if (esym && esym->st_shndx == SHN_ABS) { |
| 201 | /* if absolute symbol, no need to put a symbol value */ | 199 | /* if absolute symbol, no need to put a symbol value */ |
| 202 | pe->v = esym->st_value; | 200 | pe->v = esym->st_value; |
| @@ -207,29 +205,29 @@ static void asm_expr_unary(TCCState *s1, ExprValue *pe) · 4 unmodified lines | |||
| 207 | pe->sym = sym; | 205 | pe->sym = sym; |
| 208 | pe->pcrel = 0; | 206 | pe->pcrel = 0; |
| 209 | } | 207 | } |
| 210 | next(); | 208 | next(S); |
| 211 | } else { | 209 | } else { |
| 212 | tcc_error("bad expression syntax [%s]", get_tok_str(tok, &tokc)); | 210 | tcc_error(S, "bad expression syntax [%s]", get_tok_str(S, S->tccpp_tok, &S->tccpp_tokc)); |
| 213 | } | 211 | } |
| 214 | break; | 212 | break; |
| 215 | } | 213 | } |
| 216 | } | 214 | } |
| 217 | 215 | ||
| 218 | static void asm_expr_prod(TCCState *s1, ExprValue *pe) | 216 | static void asm_expr_prod(TCCState *S, ExprValue *pe) |
| 219 | { | 217 | { |
| 220 | int op; | 218 | int op; |
| 221 | ExprValue e2; | 219 | ExprValue e2; |
| 222 | 220 | ||
| 223 | asm_expr_unary(s1, pe); | 221 | asm_expr_unary(S, pe); |
| 224 | for(;;) { | 222 | for(;;) { |
| 225 | op = tok; | 223 | op = S->tccpp_tok; |
| 226 | if (op != '*' && op != '/' && op != '%' && | 224 | if (op != '*' && op != '/' && op != '%' && |
| 227 | op != TOK_SHL && op != TOK_SAR) | 225 | op != TOK_SHL && op != TOK_SAR) |
| 228 | break; | 226 | break; |
| 229 | next(); | 227 | next(S); |
| 230 | asm_expr_unary(s1, &e2); | 228 | asm_expr_unary(S, &e2); |
| 231 | if (pe->sym || e2.sym) | 229 | if (pe->sym || e2.sym) |
| 232 | tcc_error("invalid operation with label"); | 230 | tcc_error(S, "invalid operation with label"); |
| 233 | switch(op) { | 231 | switch(op) { |
| 234 | case '*': | 232 | case '*': |
| 235 | pe->v *= e2.v; | 233 | pe->v *= e2.v; |
| @@ -237,7 +235,7 @@ static void asm_expr_prod(TCCState *s1, ExprValue *pe) · 1 unmodified line | |||
| 237 | case '/': | 235 | case '/': |
| 238 | if (e2.v == 0) { | 236 | if (e2.v == 0) { |
| 239 | div_error: | 237 | div_error: |
| 240 | tcc_error("division by zero"); | 238 | tcc_error(S, "division by zero"); |
| 241 | } | 239 | } |
| 242 | pe->v /= e2.v; | 240 | pe->v /= e2.v; |
| 243 | break; | 241 | break; |
| @@ -257,20 +255,20 @@ static void asm_expr_prod(TCCState *s1, ExprValue *pe) · 13 unmodified lines | |||
| 257 | } | 255 | } |
| 258 | } | 256 | } |
| 259 | 257 | ||
| 260 | static void asm_expr_logic(TCCState *s1, ExprValue *pe) | 258 | static void asm_expr_logic(TCCState *S, ExprValue *pe) |
| 261 | { | 259 | { |
| 262 | int op; | 260 | int op; |
| 263 | ExprValue e2; | 261 | ExprValue e2; |
| 264 | 262 | ||
| 265 | asm_expr_prod(s1, pe); | 263 | asm_expr_prod(S, pe); |
| 266 | for(;;) { | 264 | for(;;) { |
| 267 | op = tok; | 265 | op = S->tccpp_tok; |
| 268 | if (op != '&' && op != '|' && op != '^') | 266 | if (op != '&' && op != '|' && op != '^') |
| 269 | break; | 267 | break; |
| 270 | next(); | 268 | next(S); |
| 271 | asm_expr_prod(s1, &e2); | 269 | asm_expr_prod(S, &e2); |
| 272 | if (pe->sym || e2.sym) | 270 | if (pe->sym || e2.sym) |
| 273 | tcc_error("invalid operation with label"); | 271 | tcc_error(S, "invalid operation with label"); |
| 274 | switch(op) { | 272 | switch(op) { |
| 275 | case '&': | 273 | case '&': |
| 276 | pe->v &= e2.v; | 274 | pe->v &= e2.v; |
| @@ -286,18 +284,18 @@ static void asm_expr_logic(TCCState *s1, ExprValue *pe) · 9 unmodified lines | |||
| 286 | } | 284 | } |
| 287 | } | 285 | } |
| 288 | 286 | ||
| 289 | static inline void asm_expr_sum(TCCState *s1, ExprValue *pe) | 287 | static inline void asm_expr_sum(TCCState *S, ExprValue *pe) |
| 290 | { | 288 | { |
| 291 | int op; | 289 | int op; |
| 292 | ExprValue e2; | 290 | ExprValue e2; |
| 293 | 291 | ||
| 294 | asm_expr_logic(s1, pe); | 292 | asm_expr_logic(S, pe); |
| 295 | for(;;) { | 293 | for(;;) { |
| 296 | op = tok; | 294 | op = S->tccpp_tok; |
| 297 | if (op != '+' && op != '-') | 295 | if (op != '+' && op != '-') |
| 298 | break; | 296 | break; |
| 299 | next(); | 297 | next(S); |
| 300 | asm_expr_logic(s1, &e2); | 298 | asm_expr_logic(S, &e2); |
| 301 | if (op == '+') { | 299 | if (op == '+') { |
| 302 | if (pe->sym != NULL && e2.sym != NULL) | 300 | if (pe->sym != NULL && e2.sym != NULL) |
| 303 | goto cannot_relocate; | 301 | goto cannot_relocate; |
| @@ -315,8 +313,8 @@ static inline void asm_expr_sum(TCCState *s1, ExprValue *pe) · 11 unmodified lines | |||
| 315 | pe->sym = NULL; /* same symbols can be subtracted to NULL */ | 313 | pe->sym = NULL; /* same symbols can be subtracted to NULL */ |
| 316 | } else { | 314 | } else { |
| 317 | ElfSym *esym1, *esym2; | 315 | ElfSym *esym1, *esym2; |
| 318 | esym1 = elfsym(pe->sym); | 316 | esym1 = elfsym(S, pe->sym); |
| 319 | esym2 = elfsym(e2.sym); | 317 | esym2 = elfsym(S, e2.sym); |
| 320 | if (esym1 && esym1->st_shndx == esym2->st_shndx | 318 | if (esym1 && esym1->st_shndx == esym2->st_shndx |
| 321 | && esym1->st_shndx != SHN_UNDEF) { | 319 | && esym1->st_shndx != SHN_UNDEF) { |
| 322 | /* we also accept defined symbols in the same section */ | 320 | /* we also accept defined symbols in the same section */ |
| @@ -325,33 +323,33 @@ static inline void asm_expr_sum(TCCState *s1, ExprValue *pe) · 2 unmodified lines | |||
| 325 | } else if (esym2->st_shndx == cur_text_section->sh_num) { | 323 | } else if (esym2->st_shndx == cur_text_section->sh_num) { |
| 326 | /* When subtracting a defined symbol in current section | 324 | /* When subtracting a defined symbol in current section |
| 327 | this actually makes the value PC-relative. */ | 325 | this actually makes the value PC-relative. */ |
| 328 | pe->v -= esym2->st_value - ind - 4; | 326 | pe->v -= esym2->st_value - S->tccgen_ind - 4; |
| 329 | pe->pcrel = 1; | 327 | pe->pcrel = 1; |
| 330 | e2.sym = NULL; | 328 | e2.sym = NULL; |
| 331 | } else { | 329 | } else { |
| 332 | cannot_relocate: | 330 | cannot_relocate: |
| 333 | tcc_error("invalid operation with label"); | 331 | tcc_error(S, "invalid operation with label"); |
| 334 | } | 332 | } |
| 335 | } | 333 | } |
| 336 | } | 334 | } |
| 337 | } | 335 | } |
| 338 | } | 336 | } |
| 339 | 337 | ||
| 340 | static inline void asm_expr_cmp(TCCState *s1, ExprValue *pe) | 338 | static inline void asm_expr_cmp(TCCState *S, ExprValue *pe) |
| 341 | { | 339 | { |
| 342 | int op; | 340 | int op; |
| 343 | ExprValue e2; | 341 | ExprValue e2; |
| 344 | 342 | ||
| 345 | asm_expr_sum(s1, pe); | 343 | asm_expr_sum(S, pe); |
| 346 | for(;;) { | 344 | for(;;) { |
| 347 | op = tok; | 345 | op = S->tccpp_tok; |
| 348 | if (op != TOK_EQ && op != TOK_NE | 346 | if (op != TOK_EQ && op != TOK_NE |
| 349 | && (op > TOK_GT || op < TOK_ULE)) | 347 | && (op > TOK_GT || op < TOK_ULE)) |
| 350 | break; | 348 | break; |
| 351 | next(); | 349 | next(S); |
| 352 | asm_expr_sum(s1, &e2); | 350 | asm_expr_sum(S, &e2); |
| 353 | if (pe->sym || e2.sym) | 351 | if (pe->sym || e2.sym) |
| 354 | tcc_error("invalid operation with label"); | 352 | tcc_error(S, "invalid operation with label"); |
| 355 | switch(op) { | 353 | switch(op) { |
| 356 | case TOK_EQ: | 354 | case TOK_EQ: |
| 357 | pe->v = pe->v == e2.v; | 355 | pe->v = pe->v == e2.v; |
| @@ -379,29 +377,29 @@ static inline void asm_expr_cmp(TCCState *s1, ExprValue *pe) · 21 unmodified lines | |||
| 379 | } | 377 | } |
| 380 | } | 378 | } |
| 381 | 379 | ||
| 382 | ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe) | 380 | ST_FUNC void asm_expr(TCCState *S, ExprValue *pe) |
| 383 | { | 381 | { |
| 384 | asm_expr_cmp(s1, pe); | 382 | asm_expr_cmp(S, pe); |
| 385 | } | 383 | } |
| 386 | 384 | ||
| 387 | ST_FUNC int asm_int_expr(TCCState *s1) | 385 | ST_FUNC int asm_int_expr(TCCState *S) |
| 388 | { | 386 | { |
| 389 | ExprValue e; | 387 | ExprValue e; |
| 390 | asm_expr(s1, &e); | 388 | asm_expr(S, &e); |
| 391 | if (e.sym) | 389 | if (e.sym) |
| 392 | expect("constant"); | 390 | expect(S, "constant"); |
| 393 | return e.v; | 391 | return e.v; |
| 394 | } | 392 | } |
| 395 | 393 | ||
| 396 | static Sym* asm_new_label1(TCCState *s1, int label, int is_local, | 394 | static Sym* asm_new_label1(TCCState *S, int label, int is_local, |
| 397 | int sh_num, int value) | 395 | int sh_num, int value) |
| 398 | { | 396 | { |
| 399 | Sym *sym; | 397 | Sym *sym; |
| 400 | ElfSym *esym; | 398 | ElfSym *esym; |
| 401 | 399 | ||
| 402 | sym = asm_label_find(label); | 400 | sym = asm_label_find(S, label); |
| 403 | if (sym) { | 401 | if (sym) { |
| 404 | esym = elfsym(sym); | 402 | esym = elfsym(S, sym); |
| 405 | /* A VT_EXTERN symbol, even if it has a section is considered | 403 | /* A VT_EXTERN symbol, even if it has a section is considered |
| 406 | overridable. This is how we "define" .set targets. Real | 404 | overridable. This is how we "define" .set targets. Real |
| 407 | definitions won't have VT_EXTERN set. */ | 405 | definitions won't have VT_EXTERN set. */ |
| @@ -411,16 +409,16 @@ static Sym* asm_new_label1(TCCState *s1, int label, int is_local, · 3 unmodified lines | |||
| 411 | && (is_local == 1 || (sym->type.t & VT_EXTERN))) | 409 | && (is_local == 1 || (sym->type.t & VT_EXTERN))) |
| 412 | goto new_label; | 410 | goto new_label; |
| 413 | if (!(sym->type.t & VT_EXTERN)) | 411 | if (!(sym->type.t & VT_EXTERN)) |
| 414 | tcc_error("assembler label '%s' already defined", | 412 | tcc_error(S, "assembler label '%s' already defined", |
| 415 | get_tok_str(label, NULL)); | 413 | get_tok_str(S, label, NULL)); |
| 416 | } | 414 | } |
| 417 | } else { | 415 | } else { |
| 418 | new_label: | 416 | new_label: |
| 419 | sym = asm_label_push(label); | 417 | sym = asm_label_push(S, label); |
| 420 | } | 418 | } |
| 421 | if (!sym->c) | 419 | if (!sym->c) |
| 422 | put_extern_sym2(sym, SHN_UNDEF, 0, 0, 1); | 420 | put_extern_sym2(S, sym, SHN_UNDEF, 0, 0, 1); |
| 423 | esym = elfsym(sym); | 421 | esym = elfsym(S, sym); |
| 424 | esym->st_shndx = sh_num; | 422 | esym->st_shndx = sh_num; |
| 425 | esym->st_value = value; | 423 | esym->st_value = value; |
| 426 | if (is_local != 2) | 424 | if (is_local != 2) |
| @@ -428,61 +426,61 @@ static Sym* asm_new_label1(TCCState *s1, int label, int is_local, · 1 unmodified line | |||
| 428 | return sym; | 426 | return sym; |
| 429 | } | 427 | } |
| 430 | 428 | ||
| 431 | static Sym* asm_new_label(TCCState *s1, int label, int is_local) | 429 | static Sym* asm_new_label(TCCState *S, int label, int is_local) |
| 432 | { | 430 | { |
| 433 | return asm_new_label1(s1, label, is_local, cur_text_section->sh_num, ind); | 431 | return asm_new_label1(S, label, is_local, cur_text_section->sh_num, S->tccgen_ind); |
| 434 | } | 432 | } |
| 435 | 433 | ||
| 436 | /* Set the value of LABEL to that of some expression (possibly | 434 | /* Set the value of LABEL to that of some expression (possibly |
| 437 | involving other symbols). LABEL can be overwritten later still. */ | 435 | involving other symbols). LABEL can be overwritten later still. */ |
| 438 | static Sym* set_symbol(TCCState *s1, int label) | 436 | static Sym* set_symbol(TCCState *S, int label) |
| 439 | { | 437 | { |
| 440 | long n; | 438 | long n; |
| 441 | ExprValue e; | 439 | ExprValue e; |
| 442 | Sym *sym; | 440 | Sym *sym; |
| 443 | ElfSym *esym; | 441 | ElfSym *esym; |
| 444 | next(); | 442 | next(S); |
| 445 | asm_expr(s1, &e); | 443 | asm_expr(S, &e); |
| 446 | n = e.v; | 444 | n = e.v; |
| 447 | esym = elfsym(e.sym); | 445 | esym = elfsym(S, e.sym); |
| 448 | if (esym) | 446 | if (esym) |
| 449 | n += esym->st_value; | 447 | n += esym->st_value; |
| 450 | sym = asm_new_label1(s1, label, 2, esym ? esym->st_shndx : SHN_ABS, n); | 448 | sym = asm_new_label1(S, label, 2, esym ? esym->st_shndx : SHN_ABS, n); |
| 451 | elfsym(sym)->st_other |= ST_ASM_SET; | 449 | elfsym(S, sym)->st_other |= ST_ASM_SET; |
| 452 | return sym; | 450 | return sym; |
| 453 | } | 451 | } |
| 454 | 452 | ||
| 455 | static void use_section1(TCCState *s1, Section *sec) | 453 | static void use_section1(TCCState *S, Section *sec) |
| 456 | { | 454 | { |
| 457 | cur_text_section->data_offset = ind; | 455 | cur_text_section->data_offset = S->tccgen_ind; |
| 458 | cur_text_section = sec; | 456 | cur_text_section = sec; |
| 459 | ind = cur_text_section->data_offset; | 457 | S->tccgen_ind = cur_text_section->data_offset; |
| 460 | } | 458 | } |
| 461 | 459 | ||
| 462 | static void use_section(TCCState *s1, const char *name) | 460 | static void use_section(TCCState *S, const char *name) |
| 463 | { | 461 | { |
| 464 | Section *sec; | 462 | Section *sec; |
| 465 | sec = find_section(s1, name); | 463 | sec = find_section(S, name); |
| 466 | use_section1(s1, sec); | 464 | use_section1(S, sec); |
| 467 | } | 465 | } |
| 468 | 466 | ||
| 469 | static void push_section(TCCState *s1, const char *name) | 467 | static void push_section(TCCState *S, const char *name) |
| 470 | { | 468 | { |
| 471 | Section *sec = find_section(s1, name); | 469 | Section *sec = find_section(S, name); |
| 472 | sec->prev = cur_text_section; | 470 | sec->prev = cur_text_section; |
| 473 | use_section1(s1, sec); | 471 | use_section1(S, sec); |
| 474 | } | 472 | } |
| 475 | 473 | ||
| 476 | static void pop_section(TCCState *s1) | 474 | static void pop_section(TCCState *S) |
| 477 | { | 475 | { |
| 478 | Section *prev = cur_text_section->prev; | 476 | Section *prev = cur_text_section->prev; |
| 479 | if (!prev) | 477 | if (!prev) |
| 480 | tcc_error(".popsection without .pushsection"); | 478 | tcc_error(S, ".popsection without .pushsection"); |
| 481 | cur_text_section->prev = NULL; | 479 | cur_text_section->prev = NULL; |
| 482 | use_section1(s1, prev); | 480 | use_section1(S, prev); |
| 483 | } | 481 | } |
| 484 | 482 | ||
| 485 | static void asm_parse_directive(TCCState *s1, int global) | 483 | static void asm_parse_directive(TCCState *S, int global) |
| 486 | { | 484 | { |
| 487 | int n, offset, v, size, tok1; | 485 | int n, offset, v, size, tok1; |
| 488 | Section *sec; | 486 | Section *sec; |
| @@ -490,27 +488,27 @@ static void asm_parse_directive(TCCState *s1, int global) · 1 unmodified line | |||
| 490 | 488 | ||
| 491 | /* assembler directive */ | 489 | /* assembler directive */ |
| 492 | sec = cur_text_section; | 490 | sec = cur_text_section; |
| 493 | switch(tok) { | 491 | switch(S->tccpp_tok) { |
| 494 | case TOK_ASMDIR_align: | 492 | case TOK_ASMDIR_align: |
| 495 | case TOK_ASMDIR_balign: | 493 | case TOK_ASMDIR_balign: |
| 496 | case TOK_ASMDIR_p2align: | 494 | case TOK_ASMDIR_p2align: |
| 497 | case TOK_ASMDIR_skip: | 495 | case TOK_ASMDIR_skip: |
| 498 | case TOK_ASMDIR_space: | 496 | case TOK_ASMDIR_space: |
| 499 | tok1 = tok; | 497 | tok1 = S->tccpp_tok; |
| 500 | next(); | 498 | next(S); |
| 501 | n = asm_int_expr(s1); | 499 | n = asm_int_expr(S); |
| 502 | if (tok1 == TOK_ASMDIR_p2align) | 500 | if (tok1 == TOK_ASMDIR_p2align) |
| 503 | { | 501 | { |
| 504 | if (n < 0 || n > 30) | 502 | if (n < 0 || n > 30) |
| 505 | tcc_error("invalid p2align, must be between 0 and 30"); | 503 | tcc_error(S, "invalid p2align, must be between 0 and 30"); |
| 506 | n = 1 << n; | 504 | n = 1 << n; |
| 507 | tok1 = TOK_ASMDIR_align; | 505 | tok1 = TOK_ASMDIR_align; |
| 508 | } | 506 | } |
| 509 | if (tok1 == TOK_ASMDIR_align || tok1 == TOK_ASMDIR_balign) { | 507 | if (tok1 == TOK_ASMDIR_align || tok1 == TOK_ASMDIR_balign) { |
| 510 | if (n < 0 || (n & (n-1)) != 0) | 508 | if (n < 0 || (n & (n-1)) != 0) |
| 511 | tcc_error("alignment must be a positive power of two"); | 509 | tcc_error(S, "alignment must be a positive power of two"); |
| 512 | offset = (ind + n - 1) & -n; | 510 | offset = (S->tccgen_ind + n - 1) & -n; |
| 513 | size = offset - ind; | 511 | size = offset - S->tccgen_ind; |
| 514 | /* the section must have a compatible alignment */ | 512 | /* the section must have a compatible alignment */ |
| 515 | if (sec->sh_addralign < n) | 513 | if (sec->sh_addralign < n) |
| 516 | sec->sh_addralign = n; | 514 | sec->sh_addralign = n; |
| @@ -520,47 +518,47 @@ static void asm_parse_directive(TCCState *s1, int global) · 3 unmodified lines | |||
| 520 | size = n; | 518 | size = n; |
| 521 | } | 519 | } |
| 522 | v = 0; | 520 | v = 0; |
| 523 | if (tok == ',') { | 521 | if (S->tccpp_tok == ',') { |
| 524 | next(); | 522 | next(S); |
| 525 | v = asm_int_expr(s1); | 523 | v = asm_int_expr(S); |
| 526 | } | 524 | } |
| 527 | zero_pad: | 525 | zero_pad: |
| 528 | if (sec->sh_type != SHT_NOBITS) { | 526 | if (sec->sh_type != SHT_NOBITS) { |
| 529 | sec->data_offset = ind; | 527 | sec->data_offset = S->tccgen_ind; |
| 530 | ptr = section_ptr_add(sec, size); | 528 | ptr = section_ptr_add(S, sec, size); |
| 531 | memset(ptr, v, size); | 529 | memset(ptr, v, size); |
| 532 | } | 530 | } |
| 533 | ind += size; | 531 | S->tccgen_ind += size; |
| 534 | break; | 532 | break; |
| 535 | case TOK_ASMDIR_quad: | 533 | case TOK_ASMDIR_quad: |
| 536 | #ifdef TCC_TARGET_X86_64 | 534 | #ifdef TCC_TARGET_X86_64 |
| 537 | size = 8; | 535 | size = 8; |
| 538 | goto asm_data; | 536 | goto asm_data; |
| 539 | #else | 537 | #else |
| 540 | next(); | 538 | next(S); |
| 541 | for(;;) { | 539 | for(;;) { |
| 542 | uint64_t vl; | 540 | uint64_t vl; |
| 543 | const char *p; | 541 | const char *p; |
| 544 | 542 | ||
| 545 | p = tokc.str.data; | 543 | p = S->tccpp_tokc.str.data; |
| 546 | if (tok != TOK_PPNUM) { | 544 | if (S->tccpp_tok != TOK_PPNUM) { |
| 547 | error_constant: | 545 | error_constant: |
| 548 | tcc_error("64 bit constant"); | 546 | tcc_error(S, "64 bit constant"); |
| 549 | } | 547 | } |
| 550 | vl = strtoll(p, (char **)&p, 0); | 548 | vl = strtoll(p, (char **)&p, 0); |
| 551 | if (*p != '\0') | 549 | if (*p != '\0') |
| 552 | goto error_constant; | 550 | goto error_constant; |
| 553 | next(); | 551 | next(S); |
| 554 | if (sec->sh_type != SHT_NOBITS) { | 552 | if (sec->sh_type != SHT_NOBITS) { |
| 555 | /* XXX: endianness */ | 553 | /* XXX: endianness */ |
| 556 | gen_le32(vl); | 554 | gen_le32(S, vl); |
| 557 | gen_le32(vl >> 32); | 555 | gen_le32(S, vl >> 32); |
| 558 | } else { | 556 | } else { |
| 559 | ind += 8; | 557 | S->tccgen_ind += 8; |
| 560 | } | 558 | } |
| 561 | if (tok != ',') | 559 | if (S->tccpp_tok != ',') |
| 562 | break; | 560 | break; |
| 563 | next(); | 561 | next(S); |
| 564 | } | 562 | } |
| 565 | break; | 563 | break; |
| 566 | #endif | 564 | #endif |
| @@ -575,57 +573,57 @@ static void asm_parse_directive(TCCState *s1, int global) · 8 unmodified lines | |||
| 575 | case TOK_ASMDIR_int: | 573 | case TOK_ASMDIR_int: |
| 576 | size = 4; | 574 | size = 4; |
| 577 | asm_data: | 575 | asm_data: |
| 578 | next(); | 576 | next(S); |
| 579 | for(;;) { | 577 | for(;;) { |
| 580 | ExprValue e; | 578 | ExprValue e; |
| 581 | asm_expr(s1, &e); | 579 | asm_expr(S, &e); |
| 582 | if (sec->sh_type != SHT_NOBITS) { | 580 | if (sec->sh_type != SHT_NOBITS) { |
| 583 | if (size == 4) { | 581 | if (size == 4) { |
| 584 | gen_expr32(&e); | 582 | gen_expr32(S, &e); |
| 585 | #ifdef TCC_TARGET_X86_64 | 583 | #ifdef TCC_TARGET_X86_64 |
| 586 | } else if (size == 8) { | 584 | } else if (size == 8) { |
| 587 | gen_expr64(&e); | 585 | gen_expr64(S, &e); |
| 588 | #endif | 586 | #endif |
| 589 | } else { | 587 | } else { |
| 590 | if (e.sym) | 588 | if (e.sym) |
| 591 | expect("constant"); | 589 | expect(S, "constant"); |
| 592 | if (size == 1) | 590 | if (size == 1) |
| 593 | g(e.v); | 591 | g(S, e.v); |
| 594 | else | 592 | else |
| 595 | gen_le16(e.v); | 593 | gen_le16(S, e.v); |
| 596 | } | 594 | } |
| 597 | } else { | 595 | } else { |
| 598 | ind += size; | 596 | S->tccgen_ind += size; |
| 599 | } | 597 | } |
| 600 | if (tok != ',') | 598 | if (S->tccpp_tok != ',') |
| 601 | break; | 599 | break; |
| 602 | next(); | 600 | next(S); |
| 603 | } | 601 | } |
| 604 | break; | 602 | break; |
| 605 | case TOK_ASMDIR_fill: | 603 | case TOK_ASMDIR_fill: |
| 606 | { | 604 | { |
| 607 | int repeat, size, val, i, j; | 605 | int repeat, size, val, i, j; |
| 608 | uint8_t repeat_buf[8]; | 606 | uint8_t repeat_buf[8]; |
| 609 | next(); | 607 | next(S); |
| 610 | repeat = asm_int_expr(s1); | 608 | repeat = asm_int_expr(S); |
| 611 | if (repeat < 0) { | 609 | if (repeat < 0) { |
| 612 | tcc_error("repeat < 0; .fill ignored"); | 610 | tcc_error(S, "repeat < 0; .fill ignored"); |
| 613 | break; | 611 | break; |
| 614 | } | 612 | } |
| 615 | size = 1; | 613 | size = 1; |
| 616 | val = 0; | 614 | val = 0; |
| 617 | if (tok == ',') { | 615 | if (S->tccpp_tok == ',') { |
| 618 | next(); | 616 | next(S); |
| 619 | size = asm_int_expr(s1); | 617 | size = asm_int_expr(S); |
| 620 | if (size < 0) { | 618 | if (size < 0) { |
| 621 | tcc_error("size < 0; .fill ignored"); | 619 | tcc_error(S, "size < 0; .fill ignored"); |
| 622 | break; | 620 | break; |
| 623 | } | 621 | } |
| 624 | if (size > 8) | 622 | if (size > 8) |
| 625 | size = 8; | 623 | size = 8; |
| 626 | if (tok == ',') { | 624 | if (S->tccpp_tok == ',') { |
| 627 | next(); | 625 | next(S); |
| 628 | val = asm_int_expr(s1); | 626 | val = asm_int_expr(S); |
| 629 | } | 627 | } |
| 630 | } | 628 | } |
| 631 | /* XXX: endianness */ | 629 | /* XXX: endianness */ |
| @@ -639,7 +637,7 @@ static void asm_parse_directive(TCCState *s1, int global) · 7 unmodified lines | |||
| 639 | repeat_buf[7] = 0; | 637 | repeat_buf[7] = 0; |
| 640 | for(i = 0; i < repeat; i++) { | 638 | for(i = 0; i < repeat; i++) { |
| 641 | for(j = 0; j < size; j++) { | 639 | for(j = 0; j < size; j++) { |
| 642 | g(repeat_buf[j]); | 640 | g(S, repeat_buf[j]); |
| 643 | } | 641 | } |
| 644 | } | 642 | } |
| 645 | } | 643 | } |
| @@ -648,24 +646,24 @@ static void asm_parse_directive(TCCState *s1, int global) · 2 unmodified lines | |||
| 648 | { | 646 | { |
| 649 | int repeat; | 647 | int repeat; |
| 650 | TokenString *init_str; | 648 | TokenString *init_str; |
| 651 | next(); | 649 | next(S); |
| 652 | repeat = asm_int_expr(s1); | 650 | repeat = asm_int_expr(S); |
| 653 | init_str = tok_str_alloc(); | 651 | init_str = tok_str_alloc(S); |
| 654 | while (next(), tok != TOK_ASMDIR_endr) { | 652 | while (next(S), S->tccpp_tok != TOK_ASMDIR_endr) { |
| 655 | if (tok == CH_EOF) | 653 | if (S->tccpp_tok == CH_EOF) |
| 656 | tcc_error("we at end of file, .endr not found"); | 654 | tcc_error(S, "we at end of file, .endr not found"); |
| 657 | tok_str_add_tok(init_str); | 655 | tok_str_add_tok(S, init_str); |
| 658 | } | 656 | } |
| 659 | tok_str_add(init_str, -1); | 657 | tok_str_add(S, init_str, -1); |
| 660 | tok_str_add(init_str, 0); | 658 | tok_str_add(S, init_str, 0); |
| 661 | begin_macro(init_str, 1); | 659 | begin_macro(S, init_str, 1); |
| 662 | while (repeat-- > 0) { | 660 | while (repeat-- > 0) { |
| 663 | tcc_assemble_internal(s1, (parse_flags & PARSE_FLAG_PREPROCESS), | 661 | tcc_assemble_internal(S, (S->tccpp_parse_flags & PARSE_FLAG_PREPROCESS), |
| 664 | global); | 662 | global); |
| 665 | macro_ptr = init_str->str; | 663 | S->tccpp_macro_ptr = init_str->str; |
| 666 | } | 664 | } |
| 667 | end_macro(); | 665 | end_macro(S); |
| 668 | next(); | 666 | next(S); |
| 669 | break; | 667 | break; |
| 670 | } | 668 | } |
| 671 | case TOK_ASMDIR_org: | 669 | case TOK_ASMDIR_org: |
| @@ -673,49 +671,49 @@ static void asm_parse_directive(TCCState *s1, int global) · 1 unmodified line | |||
| 673 | unsigned long n; | 671 | unsigned long n; |
| 674 | ExprValue e; | 672 | ExprValue e; |
| 675 | ElfSym *esym; | 673 | ElfSym *esym; |
| 676 | next(); | 674 | next(S); |
| 677 | asm_expr(s1, &e); | 675 | asm_expr(S, &e); |
| 678 | n = e.v; | 676 | n = e.v; |
| 679 | esym = elfsym(e.sym); | 677 | esym = elfsym(S, e.sym); |
| 680 | if (esym) { | 678 | if (esym) { |
| 681 | if (esym->st_shndx != cur_text_section->sh_num) | 679 | if (esym->st_shndx != cur_text_section->sh_num) |
| 682 | expect("constant or same-section symbol"); | 680 | expect(S, "constant or same-section symbol"); |
| 683 | n += esym->st_value; | 681 | n += esym->st_value; |
| 684 | } | 682 | } |
| 685 | if (n < ind) | 683 | if (n < S->tccgen_ind) |
| 686 | tcc_error("attempt to .org backwards"); | 684 | tcc_error(S, "attempt to .org backwards"); |
| 687 | v = 0; | 685 | v = 0; |
| 688 | size = n - ind; | 686 | size = n - S->tccgen_ind; |
| 689 | goto zero_pad; | 687 | goto zero_pad; |
| 690 | } | 688 | } |
| 691 | break; | 689 | break; |
| 692 | case TOK_ASMDIR_set: | 690 | case TOK_ASMDIR_set: |
| 693 | next(); | 691 | next(S); |
| 694 | tok1 = tok; | 692 | tok1 = S->tccpp_tok; |
| 695 | next(); | 693 | next(S); |
| 696 | /* Also accept '.set stuff', but don't do anything with this. | 694 | /* Also accept '.set stuff', but don't do anything with this. |
| 697 | It's used in GAS to set various features like '.set mips16'. */ | 695 | It's used in GAS to set various features like '.set mips16'. */ |
| 698 | if (tok == ',') | 696 | if (S->tccpp_tok == ',') |
| 699 | set_symbol(s1, tok1); | 697 | set_symbol(S, tok1); |
| 700 | break; | 698 | break; |
| 701 | case TOK_ASMDIR_globl: | 699 | case TOK_ASMDIR_globl: |
| 702 | case TOK_ASMDIR_global: | 700 | case TOK_ASMDIR_global: |
| 703 | case TOK_ASMDIR_weak: | 701 | case TOK_ASMDIR_weak: |
| 704 | case TOK_ASMDIR_hidden: | 702 | case TOK_ASMDIR_hidden: |
| 705 | tok1 = tok; | 703 | tok1 = S->tccpp_tok; |
| 706 | do { | 704 | do { |
| 707 | Sym *sym; | 705 | Sym *sym; |
| 708 | next(); | 706 | next(S); |
| 709 | sym = get_asm_sym(tok, NULL); | 707 | sym = get_asm_sym(S, S->tccpp_tok, NULL); |
| 710 | if (tok1 != TOK_ASMDIR_hidden) | 708 | if (tok1 != TOK_ASMDIR_hidden) |
| 711 | sym->type.t &= ~VT_STATIC; | 709 | sym->type.t &= ~VT_STATIC; |
| 712 | if (tok1 == TOK_ASMDIR_weak) | 710 | if (tok1 == TOK_ASMDIR_weak) |
| 713 | sym->a.weak = 1; | 711 | sym->a.weak = 1; |
| 714 | else if (tok1 == TOK_ASMDIR_hidden) | 712 | else if (tok1 == TOK_ASMDIR_hidden) |
| 715 | sym->a.visibility = STV_HIDDEN; | 713 | sym->a.visibility = STV_HIDDEN; |
| 716 | update_storage(sym); | 714 | update_storage(S, sym); |
| 717 | next(); | 715 | next(S); |
| 718 | } while (tok == ','); | 716 | } while (S->tccpp_tok == ','); |
| 719 | break; | 717 | break; |
| 720 | case TOK_ASMDIR_string: | 718 | case TOK_ASMDIR_string: |
| 721 | case TOK_ASMDIR_ascii: | 719 | case TOK_ASMDIR_ascii: |
| @@ -724,21 +722,21 @@ static void asm_parse_directive(TCCState *s1, int global) · 2 unmodified lines | |||
| 724 | const uint8_t *p; | 722 | const uint8_t *p; |
| 725 | int i, size, t; | 723 | int i, size, t; |
| 726 | 724 | ||
| 727 | t = tok; | 725 | t = S->tccpp_tok; |
| 728 | next(); | 726 | next(S); |
| 729 | for(;;) { | 727 | for(;;) { |
| 730 | if (tok != TOK_STR) | 728 | if (S->tccpp_tok != TOK_STR) |
| 731 | expect("string constant"); | 729 | expect(S, "string constant"); |
| 732 | p = tokc.str.data; | 730 | p = S->tccpp_tokc.str.data; |
| 733 | size = tokc.str.size; | 731 | size = S->tccpp_tokc.str.size; |
| 734 | if (t == TOK_ASMDIR_ascii && size > 0) | 732 | if (t == TOK_ASMDIR_ascii && size > 0) |
| 735 | size--; | 733 | size--; |
| 736 | for(i = 0; i < size; i++) | 734 | for(i = 0; i < size; i++) |
| 737 | g(p[i]); | 735 | g(S, p[i]); |
| 738 | next(); | 736 | next(S); |
| 739 | if (tok == ',') { | 737 | if (S->tccpp_tok == ',') { |
| 740 | next(); | 738 | next(S); |
| 741 | } else if (tok != TOK_STR) { | 739 | } else if (S->tccpp_tok != TOK_STR) { |
| 742 | break; | 740 | break; |
| 743 | } | 741 | } |
| 744 | } | 742 | } |
| @@ -749,18 +747,18 @@ static void asm_parse_directive(TCCState *s1, int global) · 4 unmodified lines | |||
| 749 | case TOK_ASMDIR_bss: | 747 | case TOK_ASMDIR_bss: |
| 750 | { | 748 | { |
| 751 | char sname[64]; | 749 | char sname[64]; |
| 752 | tok1 = tok; | 750 | tok1 = S->tccpp_tok; |
| 753 | n = 0; | 751 | n = 0; |
| 754 | next(); | 752 | next(S); |
| 755 | if (tok != ';' && tok != TOK_LINEFEED) { | 753 | if (S->tccpp_tok != ';' && S->tccpp_tok != TOK_LINEFEED) { |
| 756 | n = asm_int_expr(s1); | 754 | n = asm_int_expr(S); |
| 757 | next(); | 755 | next(S); |
| 758 | } | 756 | } |
| 759 | if (n) | 757 | if (n) |
| 760 | sprintf(sname, "%s%d", get_tok_str(tok1, NULL), n); | 758 | sprintf(sname, "%s%d", get_tok_str(S, tok1, NULL), n); |
| 761 | else | 759 | else |
| 762 | sprintf(sname, "%s", get_tok_str(tok1, NULL)); | 760 | sprintf(sname, "%s", get_tok_str(S, tok1, NULL)); |
| 763 | use_section(s1, sname); | 761 | use_section(S, sname); |
| 764 | } | 762 | } |
| 765 | break; | 763 | break; |
| 766 | case TOK_ASMDIR_file: | 764 | case TOK_ASMDIR_file: |
| @@ -768,13 +766,13 @@ static void asm_parse_directive(TCCState *s1, int global) · 1 unmodified line | |||
| 768 | char filename[512]; | 766 | char filename[512]; |
| 769 | 767 | ||
| 770 | filename[0] = '\0'; | 768 | filename[0] = '\0'; |
| 771 | next(); | 769 | next(S); |
| 772 | if (tok == TOK_STR) | 770 | if (S->tccpp_tok == TOK_STR) |
| 773 | pstrcat(filename, sizeof(filename), tokc.str.data); | 771 | pstrcat(filename, sizeof(filename), S->tccpp_tokc.str.data); |
| 774 | else | 772 | else |
| 775 | pstrcat(filename, sizeof(filename), get_tok_str(tok, NULL)); | 773 | pstrcat(filename, sizeof(filename), get_tok_str(S, S->tccpp_tok, NULL)); |
| 776 | tcc_warning_c(warn_unsupported)("ignoring .file %s", filename); | 774 | tcc_warning_c(warn_unsupported)(S, "ignoring .file %s", filename); |
| 777 | next(); | 775 | next(S); |
| 778 | } | 776 | } |
| 779 | break; | 777 | break; |
| 780 | case TOK_ASMDIR_ident: | 778 | case TOK_ASMDIR_ident: |
| @@ -782,30 +780,30 @@ static void asm_parse_directive(TCCState *s1, int global) · 1 unmodified line | |||
| 782 | char ident[256]; | 780 | char ident[256]; |
| 783 | 781 | ||
| 784 | ident[0] = '\0'; | 782 | ident[0] = '\0'; |
| 785 | next(); | 783 | next(S); |
| 786 | if (tok == TOK_STR) | 784 | if (S->tccpp_tok == TOK_STR) |
| 787 | pstrcat(ident, sizeof(ident), tokc.str.data); | 785 | pstrcat(ident, sizeof(ident), S->tccpp_tokc.str.data); |
| 788 | else | 786 | else |
| 789 | pstrcat(ident, sizeof(ident), get_tok_str(tok, NULL)); | 787 | pstrcat(ident, sizeof(ident), get_tok_str(S, S->tccpp_tok, NULL)); |
| 790 | tcc_warning_c(warn_unsupported)("ignoring .ident %s", ident); | 788 | tcc_warning_c(warn_unsupported)(S, "ignoring .ident %s", ident); |
| 791 | next(); | 789 | next(S); |
| 792 | } | 790 | } |
| 793 | break; | 791 | break; |
| 794 | case TOK_ASMDIR_size: | 792 | case TOK_ASMDIR_size: |
| 795 | { | 793 | { |
| 796 | Sym *sym; | 794 | Sym *sym; |
| 797 | 795 | ||
| 798 | next(); | 796 | next(S); |
| 799 | sym = asm_label_find(tok); | 797 | sym = asm_label_find(S, S->tccpp_tok); |
| 800 | if (!sym) { | 798 | if (!sym) { |
| 801 | tcc_error("label not found: %s", get_tok_str(tok, NULL)); | 799 | tcc_error(S, "label not found: %s", get_tok_str(S, S->tccpp_tok, NULL)); |
| 802 | } | 800 | } |
| 803 | /* XXX .size name,label2-label1 */ | 801 | /* XXX .size name,label2-label1 */ |
| 804 | tcc_warning_c(warn_unsupported)("ignoring .size %s,*", get_tok_str(tok, NULL)); | 802 | tcc_warning_c(warn_unsupported)(S, "ignoring .size %s,*", get_tok_str(S, S->tccpp_tok, NULL)); |
| 805 | next(); | 803 | next(S); |
| 806 | skip(','); | 804 | skip(S, ','); |
| 807 | while (tok != TOK_LINEFEED && tok != ';' && tok != CH_EOF) { | 805 | while (S->tccpp_tok != TOK_LINEFEED && S->tccpp_tok != ';' && S->tccpp_tok != CH_EOF) { |
| 808 | next(); | 806 | next(S); |
| 809 | } | 807 | } |
| 810 | } | 808 | } |
| 811 | break; | 809 | break; |
| @@ -814,182 +812,182 @@ static void asm_parse_directive(TCCState *s1, int global) · 2 unmodified lines | |||
| 814 | Sym *sym; | 812 | Sym *sym; |
| 815 | const char *newtype; | 813 | const char *newtype; |
| 816 | 814 | ||
| 817 | next(); | 815 | next(S); |
| 818 | sym = get_asm_sym(tok, NULL); | 816 | sym = get_asm_sym(S, S->tccpp_tok, NULL); |
| 819 | next(); | 817 | next(S); |
| 820 | skip(','); | 818 | skip(S, ','); |
| 821 | if (tok == TOK_STR) { | 819 | if (S->tccpp_tok == TOK_STR) { |
| 822 | newtype = tokc.str.data; | 820 | newtype = S->tccpp_tokc.str.data; |
| 823 | } else { | 821 | } else { |
| 824 | if (tok == '@' || tok == '%') | 822 | if (S->tccpp_tok == '@' || S->tccpp_tok == '%') |
| 825 | next(); | 823 | next(S); |
| 826 | newtype = get_tok_str(tok, NULL); | 824 | newtype = get_tok_str(S, S->tccpp_tok, NULL); |
| 827 | } | 825 | } |
| 828 | 826 | ||
| 829 | if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) { | 827 | if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) { |
| 830 | sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC; | 828 | sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC; |
| 831 | } else | 829 | } else |
| 832 | tcc_warning_c(warn_unsupported)("change type of '%s' from 0x%x to '%s' ignored", | 830 | tcc_warning_c(warn_unsupported)(S, "change type of '%s' from 0x%x to '%s' ignored", |
| 833 | get_tok_str(sym->v, NULL), sym->type.t, newtype); | 831 | get_tok_str(S, sym->v, NULL), sym->type.t, newtype); |
| 834 | 832 | ||
| 835 | next(); | 833 | next(S); |
| 836 | } | 834 | } |
| 837 | break; | 835 | break; |
| 838 | case TOK_ASMDIR_pushsection: | 836 | case TOK_ASMDIR_pushsection: |
| 839 | case TOK_ASMDIR_section: | 837 | case TOK_ASMDIR_section: |
| 840 | { | 838 | { |
| 841 | char sname[256]; | 839 | char sname[256]; |
| 842 | int old_nb_section = s1->nb_sections; | 840 | int old_nb_section = S->nb_sections; |
| 843 | 841 | ||
| 844 | tok1 = tok; | 842 | tok1 = S->tccpp_tok; |
| 845 | /* XXX: support more options */ | 843 | /* XXX: support more options */ |
| 846 | next(); | 844 | next(S); |
| 847 | sname[0] = '\0'; | 845 | sname[0] = '\0'; |
| 848 | while (tok != ';' && tok != TOK_LINEFEED && tok != ',') { | 846 | while (S->tccpp_tok != ';' && S->tccpp_tok != TOK_LINEFEED && S->tccpp_tok != ',') { |
| 849 | if (tok == TOK_STR) | 847 | if (S->tccpp_tok == TOK_STR) |
| 850 | pstrcat(sname, sizeof(sname), tokc.str.data); | 848 | pstrcat(sname, sizeof(sname), S->tccpp_tokc.str.data); |
| 851 | else | 849 | else |
| 852 | pstrcat(sname, sizeof(sname), get_tok_str(tok, NULL)); | 850 | pstrcat(sname, sizeof(sname), get_tok_str(S, S->tccpp_tok, NULL)); |
| 853 | next(); | 851 | next(S); |
| 854 | } | 852 | } |
| 855 | if (tok == ',') { | 853 | if (S->tccpp_tok == ',') { |
| 856 | /* skip section options */ | 854 | /* skip section options */ |
| 857 | next(); | 855 | next(S); |
| 858 | if (tok != TOK_STR) | 856 | if (S->tccpp_tok != TOK_STR) |
| 859 | expect("string constant"); | 857 | expect(S, "string constant"); |
| 860 | next(); | 858 | next(S); |
| 861 | if (tok == ',') { | 859 | if (S->tccpp_tok == ',') { |
| 862 | next(); | 860 | next(S); |
| 863 | if (tok == '@' || tok == '%') | 861 | if (S->tccpp_tok == '@' || S->tccpp_tok == '%') |
| 864 | next(); | 862 | next(S); |
| 865 | next(); | 863 | next(S); |
| 866 | } | 864 | } |
| 867 | } | 865 | } |
| 868 | last_text_section = cur_text_section; | 866 | S->tccasm_last_text_section = cur_text_section; |
| 869 | if (tok1 == TOK_ASMDIR_section) | 867 | if (tok1 == TOK_ASMDIR_section) |
| 870 | use_section(s1, sname); | 868 | use_section(S, sname); |
| 871 | else | 869 | else |
| 872 | push_section(s1, sname); | 870 | push_section(S, sname); |
| 873 | /* If we just allocated a new section reset its alignment to | 871 | /* If we just allocated a new section reset its alignment to |
| 874 | 1. new_section normally acts for GCC compatibility and | 872 | 1. new_section normally acts for GCC compatibility and |
| 875 | sets alignment to PTR_SIZE. The assembler behaves different. */ | 873 | sets alignment to PTR_SIZE. The assembler behaves different. */ |
| 876 | if (old_nb_section != s1->nb_sections) | 874 | if (old_nb_section != S->nb_sections) |
| 877 | cur_text_section->sh_addralign = 1; | 875 | cur_text_section->sh_addralign = 1; |
| 878 | } | 876 | } |
| 879 | break; | 877 | break; |
| 880 | case TOK_ASMDIR_previous: | 878 | case TOK_ASMDIR_previous: |
| 881 | { | 879 | { |
| 882 | Section *sec; | 880 | Section *sec; |
| 883 | next(); | 881 | next(S); |
| 884 | if (!last_text_section) | 882 | if (!S->tccasm_last_text_section) |
| 885 | tcc_error("no previous section referenced"); | 883 | tcc_error(S, "no previous section referenced"); |
| 886 | sec = cur_text_section; | 884 | sec = cur_text_section; |
| 887 | use_section1(s1, last_text_section); | 885 | use_section1(S, S->tccasm_last_text_section); |
| 888 | last_text_section = sec; | 886 | S->tccasm_last_text_section = sec; |
| 889 | } | 887 | } |
| 890 | break; | 888 | break; |
| 891 | case TOK_ASMDIR_popsection: | 889 | case TOK_ASMDIR_popsection: |
| 892 | next(); | 890 | next(S); |
| 893 | pop_section(s1); | 891 | pop_section(S); |
| 894 | break; | 892 | break; |
| 895 | #ifdef TCC_TARGET_I386 | 893 | #ifdef TCC_TARGET_I386 |
| 896 | case TOK_ASMDIR_code16: | 894 | case TOK_ASMDIR_code16: |
| 897 | { | 895 | { |
| 898 | next(); | 896 | next(S); |
| 899 | s1->seg_size = 16; | 897 | S->seg_size = 16; |
| 900 | } | 898 | } |
| 901 | break; | 899 | break; |
| 902 | case TOK_ASMDIR_code32: | 900 | case TOK_ASMDIR_code32: |
| 903 | { | 901 | { |
| 904 | next(); | 902 | next(S); |
| 905 | s1->seg_size = 32; | 903 | S->seg_size = 32; |
| 906 | } | 904 | } |
| 907 | break; | 905 | break; |
| 908 | #endif | 906 | #endif |
| 909 | #ifdef TCC_TARGET_X86_64 | 907 | #ifdef TCC_TARGET_X86_64 |
| 910 | /* added for compatibility with GAS */ | 908 | /* added for compatibility with GAS */ |
| 911 | case TOK_ASMDIR_code64: | 909 | case TOK_ASMDIR_code64: |
| 912 | next(); | 910 | next(S); |
| 913 | break; | 911 | break; |
| 914 | #endif | 912 | #endif |
| 915 | default: | 913 | default: |
| 916 | tcc_error("unknown assembler directive '.%s'", get_tok_str(tok, NULL)); | 914 | tcc_error(S, "unknown assembler directive '.%s'", get_tok_str(S, S->tccpp_tok, NULL)); |
| 917 | break; | 915 | break; |
| 918 | } | 916 | } |
| 919 | } | 917 | } |
| 920 | 918 | ||
| 921 | 919 | ||
| 922 | /* assemble a file */ | 920 | /* assemble a file */ |
| 923 | static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global) | 921 | static int tcc_assemble_internal(TCCState *S, int do_preprocess, int global) |
| 924 | { | 922 | { |
| 925 | int opcode; | 923 | int opcode; |
| 926 | int saved_parse_flags = parse_flags; | 924 | int saved_parse_flags = S->tccpp_parse_flags; |
| 927 | 925 | ||
| 928 | parse_flags = PARSE_FLAG_ASM_FILE | PARSE_FLAG_TOK_STR; | 926 | S->tccpp_parse_flags = PARSE_FLAG_ASM_FILE | PARSE_FLAG_TOK_STR; |
| 929 | if (do_preprocess) | 927 | if (do_preprocess) |
| 930 | parse_flags |= PARSE_FLAG_PREPROCESS; | 928 | S->tccpp_parse_flags |= PARSE_FLAG_PREPROCESS; |
| 931 | for(;;) { | 929 | for(;;) { |
| 932 | next(); | 930 | next(S); |
| 933 | if (tok == TOK_EOF) | 931 | if (S->tccpp_tok == TOK_EOF) |
| 934 | break; | 932 | break; |
| 935 | parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */ | 933 | S->tccpp_parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */ |
| 936 | redo: | 934 | redo: |
| 937 | if (tok == '#') { | 935 | if (S->tccpp_tok == '#') { |
| 938 | /* horrible gas comment */ | 936 | /* horrible gas comment */ |
| 939 | while (tok != TOK_LINEFEED) | 937 | while (S->tccpp_tok != TOK_LINEFEED) |
| 940 | next(); | 938 | next(S); |
| 941 | } else if (tok >= TOK_ASMDIR_FIRST && tok <= TOK_ASMDIR_LAST) { | 939 | } else if (S->tccpp_tok >= TOK_ASMDIR_FIRST && S->tccpp_tok <= TOK_ASMDIR_LAST) { |
| 942 | asm_parse_directive(s1, global); | 940 | asm_parse_directive(S, global); |
| 943 | } else if (tok == TOK_PPNUM) { | 941 | } else if (S->tccpp_tok == TOK_PPNUM) { |
| 944 | const char *p; | 942 | const char *p; |
| 945 | int n; | 943 | int n; |
| 946 | p = tokc.str.data; | 944 | p = S->tccpp_tokc.str.data; |
| 947 | n = strtoul(p, (char **)&p, 10); | 945 | n = strtoul(p, (char **)&p, 10); |
| 948 | if (*p != '\0') | 946 | if (*p != '\0') |
| 949 | expect("':'"); | 947 | expect(S, "':'"); |
| 950 | /* new local label */ | 948 | /* new local label */ |
| 951 | asm_new_label(s1, asm_get_local_label_name(s1, n), 1); | 949 | asm_new_label(S, asm_get_local_label_name(S, n), 1); |
| 952 | next(); | 950 | next(S); |
| 953 | skip(':'); | 951 | skip(S, ':'); |
| 954 | goto redo; | 952 | goto redo; |
| 955 | } else if (tok >= TOK_IDENT) { | 953 | } else if (S->tccpp_tok >= TOK_IDENT) { |
| 956 | /* instruction or label */ | 954 | /* instruction or label */ |
| 957 | opcode = tok; | 955 | opcode = S->tccpp_tok; |
| 958 | next(); | 956 | next(S); |
| 959 | if (tok == ':') { | 957 | if (S->tccpp_tok == ':') { |
| 960 | /* new label */ | 958 | /* new label */ |
| 961 | asm_new_label(s1, opcode, 0); | 959 | asm_new_label(S, opcode, 0); |
| 962 | next(); | 960 | next(S); |
| 963 | goto redo; | 961 | goto redo; |
| 964 | } else if (tok == '=') { | 962 | } else if (S->tccpp_tok == '=') { |
| 965 | set_symbol(s1, opcode); | 963 | set_symbol(S, opcode); |
| 966 | goto redo; | 964 | goto redo; |
| 967 | } else { | 965 | } else { |
| 968 | asm_opcode(s1, opcode); | 966 | asm_opcode(S, opcode); |
| 969 | } | 967 | } |
| 970 | } | 968 | } |
| 971 | /* end of line */ | 969 | /* end of line */ |
| 972 | if (tok != ';' && tok != TOK_LINEFEED) | 970 | if (S->tccpp_tok != ';' && S->tccpp_tok != TOK_LINEFEED) |
| 973 | expect("end of line"); | 971 | expect(S, "end of line"); |
| 974 | parse_flags &= ~PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */ | 972 | S->tccpp_parse_flags &= ~PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */ |
| 975 | } | 973 | } |
| 976 | 974 | ||
| 977 | parse_flags = saved_parse_flags; | 975 | S->tccpp_parse_flags = saved_parse_flags; |
| 978 | return 0; | 976 | return 0; |
| 979 | } | 977 | } |
| 980 | 978 | ||
| 981 | /* Assemble the current file */ | 979 | /* Assemble the current file */ |
| 982 | ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess) | 980 | ST_FUNC int tcc_assemble(TCCState *S, int do_preprocess) |
| 983 | { | 981 | { |
| 984 | int ret; | 982 | int ret; |
| 985 | tcc_debug_start(s1); | 983 | tcc_debug_start(S); |
| 986 | /* default section is text */ | 984 | /* default section is text */ |
| 987 | cur_text_section = text_section; | 985 | cur_text_section = text_section; |
| 988 | ind = cur_text_section->data_offset; | 986 | S->tccgen_ind = cur_text_section->data_offset; |
| 989 | nocode_wanted = 0; | 987 | S->tccgen_nocode_wanted = 0; |
| 990 | ret = tcc_assemble_internal(s1, do_preprocess, 1); | 988 | ret = tcc_assemble_internal(S, do_preprocess, 1); |
| 991 | cur_text_section->data_offset = ind; | 989 | cur_text_section->data_offset = S->tccgen_ind; |
| 992 | tcc_debug_end(s1); | 990 | tcc_debug_end(S); |
| 993 | return ret; | 991 | return ret; |
| 994 | } | 992 | } |
| 995 | 993 | ||
| @@ -999,27 +997,27 @@ ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess) · 3 unmodified lines | |||
| 999 | /* assemble the string 'str' in the current C compilation unit without | 997 | /* assemble the string 'str' in the current C compilation unit without |
| 1000 | C preprocessing. NOTE: str is modified by modifying the '\0' at the | 998 | C preprocessing. NOTE: str is modified by modifying the '\0' at the |
| 1001 | end */ | 999 | end */ |
| 1002 | static void tcc_assemble_inline(TCCState *s1, char *str, int len, int global) | 1000 | static void tcc_assemble_inline(TCCState *S, char *str, int len, int global) |
| 1003 | { | 1001 | { |
| 1004 | const int *saved_macro_ptr = macro_ptr; | 1002 | const int *saved_macro_ptr = S->tccpp_macro_ptr; |
| 1005 | int dotid = set_idnum('.', IS_ID); | 1003 | int dotid = set_idnum(S, '.', IS_ID); |
| 1006 | int dolid = set_idnum('$', 0); | 1004 | int dolid = set_idnum(S, '$', 0); |
| 1007 | 1005 | ||
| 1008 | tcc_open_bf(s1, ":asm:", len); | 1006 | tcc_open_bf(S, ":asm:", len); |
| 1009 | memcpy(file->buffer, str, len); | 1007 | memcpy(S->tccpp_file->buffer, str, len); |
| 1010 | macro_ptr = NULL; | 1008 | S->tccpp_macro_ptr = NULL; |
| 1011 | tcc_assemble_internal(s1, 0, global); | 1009 | tcc_assemble_internal(S, 0, global); |
| 1012 | tcc_close(); | 1010 | tcc_close(S); |
| 1013 | 1011 | ||
| 1014 | set_idnum('$', dolid); | 1012 | set_idnum(S, '$', dolid); |
| 1015 | set_idnum('.', dotid); | 1013 | set_idnum(S, '.', dotid); |
| 1016 | macro_ptr = saved_macro_ptr; | 1014 | S->tccpp_macro_ptr = saved_macro_ptr; |
| 1017 | } | 1015 | } |
| 1018 | 1016 | ||
| 1019 | /* find a constraint by its number or id (gcc 3 extended | 1017 | /* find a constraint by its number or id (gcc 3 extended |
| 1020 | syntax). return -1 if not found. Return in *pp in char after the | 1018 | syntax). return -1 if not found. Return in *pp in char after the |
| 1021 | constraint */ | 1019 | constraint */ |
| 1022 | ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands, | 1020 | ST_FUNC int find_constraint(TCCState* S, ASMOperand *operands, int nb_operands, |
| 1023 | const char *name, const char **pp) | 1021 | const char *name, const char **pp) |
| 1024 | { | 1022 | { |
| 1025 | int index; | 1023 | int index; |
| @@ -1038,7 +1036,7 @@ ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands, · 12 unmodified lines | |||
| 1038 | name++; | 1036 | name++; |
| 1039 | p = strchr(name, ']'); | 1037 | p = strchr(name, ']'); |
339 more lines aren’t shown here.
This diff is large: its 368 lines aren’t shown here.
This diff is large: its 3251 lines aren’t shown here.
This diff is large: its 9788 lines aren’t shown here.
This diff is large: its 616 lines aren’t shown here.
This diff is large: its 960 lines aren’t shown here.
This diff is large: its 4250 lines aren’t shown here.
This diff is large: its 262 lines aren’t shown here.
This diff is large: its 311 lines aren’t shown here.
This diff is large: its 188 lines aren’t shown here.
This diff is large: its 2366 lines aren’t shown here.
This diff is large: its 222 lines aren’t shown here.