summaryrefslogtreecommitdiff
path: root/arm-asm.c
diff options
context:
space:
mode:
Diffstat (limited to 'arm-asm.c')
-rw-r--r--arm-asm.c1112
1 files changed, 556 insertions, 556 deletions
diff --git a/arm-asm.c b/arm-asm.c
index 88a6d05..45ccab5 100644
--- a/arm-asm.c
+++ b/arm-asm.c
@@ -24,9 +24,9 @@
#define CONFIG_TCC_ASM
#define NB_ASM_REGS 16
-ST_FUNC void g(TCCState* S, int c);
-ST_FUNC void gen_le16(TCCState* S, int c);
-ST_FUNC void gen_le32(TCCState* S, int c);
+ST_FUNC void g(int c);
+ST_FUNC void gen_le16(int c);
+ST_FUNC void gen_le32(int c);
/*************************************************************/
#else
@@ -92,7 +92,7 @@ static int asm_parse_vfp_status_regvar(int t)
}
/* Parse a text containing operand and store the result in OP */
-static void parse_operand(TCCState *S, Operand *op)
+static void parse_operand(TCCState *s1, Operand *op)
{
ExprValue e;
int8_t reg;
@@ -100,54 +100,54 @@ static void parse_operand(TCCState *S, Operand *op)
op->type = 0;
- if (S->tccpp_tok == '{') { // regset literal
- next(S); // skip '{'
- while (S->tccpp_tok != '}' && S->tccpp_tok != TOK_EOF) {
- reg = asm_parse_regvar(S, S->tccpp_tok);
+ if (tok == '{') { // regset literal
+ next(); // skip '{'
+ while (tok != '}' && tok != TOK_EOF) {
+ reg = asm_parse_regvar(tok);
if (reg == -1) {
- expect(S, "register");
+ expect("register");
return;
} else
- next(S); // skip register name
+ next(); // skip register name
if ((1 << reg) < regset)
- tcc_warning(S, "registers will be processed in ascending order by hardware--but are not specified in ascending order here");
+ tcc_warning("registers will be processed in ascending order by hardware--but are not specified in ascending order here");
regset |= 1 << reg;
- if (S->tccpp_tok != ',')
+ if (tok != ',')
break;
- next(S); // skip ','
+ next(); // skip ','
}
- if (S->tccpp_tok != '}')
- expect(S, "'}'");
- next(S); // skip '}'
+ if (tok != '}')
+ expect("'}'");
+ next(); // skip '}'
if (regset == 0) {
// ARM instructions don't support empty regset.
- tcc_error(S, "empty register list is not supported");
+ tcc_error("empty register list is not supported");
} else {
op->type = OP_REGSET32;
op->regset = regset;
}
return;
- } else if ((reg = asm_parse_regvar(S, S->tccpp_tok)) != -1) {
- next(S); // skip register name
+ } else if ((reg = asm_parse_regvar(tok)) != -1) {
+ next(); // skip register name
op->type = OP_REG32;
op->reg = (uint8_t) reg;
return;
- } else if ((reg = asm_parse_vfp_regvar(S->tccpp_tok, 0)) != -1) {
- next(S); // skip register name
+ } else if ((reg = asm_parse_vfp_regvar(tok, 0)) != -1) {
+ next(); // skip register name
op->type = OP_VREG32;
op->reg = (uint8_t) reg;
return;
- } else if ((reg = asm_parse_vfp_regvar(S->tccpp_tok, 1)) != -1) {
- next(S); // skip register name
+ } else if ((reg = asm_parse_vfp_regvar(tok, 1)) != -1) {
+ next(); // skip register name
op->type = OP_VREG64;
op->reg = (uint8_t) reg;
return;
- } else if (S->tccpp_tok == '#' || S->tccpp_tok == '$') {
+ } else if (tok == '#' || tok == '$') {
/* constant value */
- next(S); // skip '#' or '$'
+ next(); // skip '#' or '$'
}
- asm_expr(S, &e);
+ asm_expr(s1, &e);
op->type = OP_IM32;
op->e = e;
if (!op->e.sym) {
@@ -156,64 +156,64 @@ static void parse_operand(TCCState *S, Operand *op)
else if (op->e.v == (uint8_t)op->e.v)
op->type = OP_IM8;
} else
- expect(S, "operand");
+ expect("operand");
}
/* XXX: make it faster ? */
-ST_FUNC void g(TCCState* S, int c)
+ST_FUNC void g(int c)
{
int ind1;
- if (S->tccgen_nocode_wanted)
+ if (nocode_wanted)
return;
- ind1 = S->tccgen_ind + 1;
+ ind1 = ind + 1;
if (ind1 > cur_text_section->data_allocated)
- section_realloc(S, cur_text_section, ind1);
- cur_text_section->data[S->tccgen_ind] = c;
- S->tccgen_ind = ind1;
+ section_realloc(cur_text_section, ind1);
+ cur_text_section->data[ind] = c;
+ ind = ind1;
}
-ST_FUNC void gen_le16 (TCCState* S, int i)
+ST_FUNC void gen_le16 (int i)
{
- g(S, i);
- g(S, i>>8);
+ g(i);
+ g(i>>8);
}
-ST_FUNC void gen_le32 (TCCState* S, int i)
+ST_FUNC void gen_le32 (int i)
{
int ind1;
- if (S->tccgen_nocode_wanted)
+ if (nocode_wanted)
return;
- ind1 = S->tccgen_ind + 4;
+ ind1 = ind + 4;
if (ind1 > cur_text_section->data_allocated)
- section_realloc(S, cur_text_section, ind1);
- cur_text_section->data[S->tccgen_ind++] = i & 0xFF;
- cur_text_section->data[S->tccgen_ind++] = (i >> 8) & 0xFF;
- cur_text_section->data[S->tccgen_ind++] = (i >> 16) & 0xFF;
- cur_text_section->data[S->tccgen_ind++] = (i >> 24) & 0xFF;
+ section_realloc(cur_text_section, ind1);
+ cur_text_section->data[ind++] = i & 0xFF;
+ cur_text_section->data[ind++] = (i >> 8) & 0xFF;
+ cur_text_section->data[ind++] = (i >> 16) & 0xFF;
+ cur_text_section->data[ind++] = (i >> 24) & 0xFF;
}
-ST_FUNC void gen_expr32(TCCState* S, ExprValue *pe)
+ST_FUNC void gen_expr32(ExprValue *pe)
{
- gen_le32(S, pe->v);
+ gen_le32(pe->v);
}
-static uint32_t condition_code_of_token(TCCState* S, int token) {
+static uint32_t condition_code_of_token(int token) {
if (token < TOK_ASM_nopeq) {
- expect(S, "condition-enabled instruction");
+ expect("condition-enabled instruction");
return 0;
} else
return (token - TOK_ASM_nopeq) & 15;
}
-static void asm_emit_opcode(TCCState* S, int token, uint32_t opcode) {
- gen_le32(S, (condition_code_of_token(S, token) << 28) | opcode);
+static void asm_emit_opcode(int token, uint32_t opcode) {
+ gen_le32((condition_code_of_token(token) << 28) | opcode);
}
-static void asm_emit_unconditional_opcode(TCCState* S, uint32_t opcode) {
- gen_le32(S, opcode);
+static void asm_emit_unconditional_opcode(uint32_t opcode) {
+ gen_le32(opcode);
}
-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)
+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)
{
uint32_t opcode = 0xe000000;
if (inter_processor_transfer)
@@ -230,69 +230,69 @@ static void asm_emit_coprocessor_opcode(TCCState* S, uint32_t high_nibble, uint8
opcode |= cp_opcode2 << 5;
//assert(cp_m_operand_register < 16);
opcode |= cp_m_operand_register;
- asm_emit_unconditional_opcode(S, (high_nibble << 28) | opcode);
+ asm_emit_unconditional_opcode((high_nibble << 28) | opcode);
}
-static void asm_nullary_opcode(TCCState* S, int token)
+static void asm_nullary_opcode(int token)
{
switch (ARM_INSTRUCTION_GROUP(token)) {
case TOK_ASM_nopeq:
- asm_emit_opcode(S, token, 0xd << 21); // mov r0, r0
+ asm_emit_opcode(token, 0xd << 21); // mov r0, r0
break;
case TOK_ASM_wfeeq:
- asm_emit_opcode(S, token, 0x320f002);
+ asm_emit_opcode(token, 0x320f002);
case TOK_ASM_wfieq:
- asm_emit_opcode(S, token, 0x320f003);
+ asm_emit_opcode(token, 0x320f003);
break;
default:
- expect(S, "nullary instruction");
+ expect("nullary instruction");
}
}
-static void asm_unary_opcode(TCCState *S, int token)
+static void asm_unary_opcode(TCCState *s1, int token)
{
Operand op;
- parse_operand(S, &op);
+ parse_operand(s1, &op);
switch (ARM_INSTRUCTION_GROUP(token)) {
case TOK_ASM_swieq:
case TOK_ASM_svceq:
if (op.type != OP_IM8)
- expect(S, "immediate 8-bit unsigned integer");
+ expect("immediate 8-bit unsigned integer");
else {
/* Note: Dummy operand (ignored by processor): ARM ref documented 0...255, ARM instruction set documented 24 bit */
- asm_emit_opcode(S, token, (0xf << 24) | op.e.v);
+ asm_emit_opcode(token, (0xf << 24) | op.e.v);
}
break;
default:
- expect(S, "unary instruction");
+ expect("unary instruction");
}
}
-static void asm_binary_opcode(TCCState *S, int token)
+static void asm_binary_opcode(TCCState *s1, int token)
{
Operand ops[2];
Operand rotation;
uint32_t encoded_rotation = 0;
uint64_t amount;
- parse_operand(S, &ops[0]);
- if (S->tccpp_tok == ',')
- next(S);
+ parse_operand(s1, &ops[0]);
+ if (tok == ',')
+ next();
else
- expect(S, "','");
- parse_operand(S, &ops[1]);
+ expect("','");
+ parse_operand(s1, &ops[1]);
if (ops[0].type != OP_REG32) {
- expect(S, "(destination operand) register");
+ expect("(destination operand) register");
return;
}
if (ops[0].reg == 15) {
- tcc_error(S, "'%s' does not support 'pc' as operand", get_tok_str(S, token, NULL));
+ tcc_error("'%s' does not support 'pc' as operand", get_tok_str(token, NULL));
return;
}
if (ops[0].reg == 13)
- tcc_warning(S, "Using 'sp' as operand with '%s' is deprecated by ARM", get_tok_str(S, token, NULL));
+ tcc_warning("Using 'sp' as operand with '%s' is deprecated by ARM", get_tok_str(token, NULL));
if (ops[1].type != OP_REG32) {
switch (ARM_INSTRUCTION_GROUP(token)) {
@@ -303,38 +303,38 @@ static void asm_binary_opcode(TCCState *S, int token)
uint16_t immediate_value = ops[1].e.v;
switch (ARM_INSTRUCTION_GROUP(token)) {
case TOK_ASM_movteq:
- asm_emit_opcode(S, token, 0x3400000 | (ops[0].reg << 12) | (immediate_value & 0xF000) << 4 | (immediate_value & 0xFFF));
+ asm_emit_opcode(token, 0x3400000 | (ops[0].reg << 12) | (immediate_value & 0xF000) << 4 | (immediate_value & 0xFFF));
break;
case TOK_ASM_movweq:
- asm_emit_opcode(S, token, 0x3000000 | (ops[0].reg << 12) | (immediate_value & 0xF000) << 4 | (immediate_value & 0xFFF));
+ asm_emit_opcode(token, 0x3000000 | (ops[0].reg << 12) | (immediate_value & 0xF000) << 4 | (immediate_value & 0xFFF));
break;
}
} else
- expect(S, "(source operand) immediate 16 bit value");
+ expect("(source operand) immediate 16 bit value");
} else
- expect(S, "(source operand) immediate");
+ expect("(source operand) immediate");
break;
default:
- expect(S, "(source operand) register");
+ expect("(source operand) register");
}
return;
}
if (ops[1].reg == 15) {
- tcc_error(S, "'%s' does not support 'pc' as operand", get_tok_str(S, token, NULL));
+ tcc_error("'%s' does not support 'pc' as operand", get_tok_str(token, NULL));
return;
}
if (ops[1].reg == 13)
- tcc_warning(S, "Using 'sp' as operand with '%s' is deprecated by ARM", get_tok_str(S, token, NULL));
+ tcc_warning("Using 'sp' as operand with '%s' is deprecated by ARM", get_tok_str(token, NULL));
- if (S->tccpp_tok == ',') {
- next(S); // skip ','
- if (S->tccpp_tok == TOK_ASM_ror) {
- next(S); // skip 'ror'
- parse_operand(S, &rotation);
+ if (tok == ',') {
+ next(); // skip ','
+ if (tok == TOK_ASM_ror) {
+ next(); // skip 'ror'
+ parse_operand(s1, &rotation);
if (rotation.type != OP_IM8) {
- expect(S, "immediate value for rotation");
+ expect("immediate value for rotation");
return;
} else {
amount = rotation.e.v;
@@ -349,7 +349,7 @@ static void asm_binary_opcode(TCCState *S, int token)
encoded_rotation = 3 << 10;
break;
default:
- expect(S, "'8' or '16' or '24'");
+ expect("'8' or '16' or '24'");
return;
}
}
@@ -358,27 +358,27 @@ static void asm_binary_opcode(TCCState *S, int token)
switch (ARM_INSTRUCTION_GROUP(token)) {
case TOK_ASM_clzeq:
if (encoded_rotation)
- tcc_error(S, "clz does not support rotation");
- asm_emit_opcode(S, token, 0x16f0f10 | (ops[0].reg << 12) | ops[1].reg);
+ tcc_error("clz does not support rotation");
+ asm_emit_opcode(token, 0x16f0f10 | (ops[0].reg << 12) | ops[1].reg);
break;
case TOK_ASM_sxtbeq:
- asm_emit_opcode(S, token, 0x6af0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation);
+ asm_emit_opcode(token, 0x6af0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation);
break;
case TOK_ASM_sxtheq:
- asm_emit_opcode(S, token, 0x6bf0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation);
+ asm_emit_opcode(token, 0x6bf0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation);
break;
case TOK_ASM_uxtbeq:
- asm_emit_opcode(S, token, 0x6ef0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation);
+ asm_emit_opcode(token, 0x6ef0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation);
break;
case TOK_ASM_uxtheq:
- asm_emit_opcode(S, token, 0x6ff0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation);
+ asm_emit_opcode(token, 0x6ff0070 | (ops[0].reg << 12) | ops[1].reg | encoded_rotation);
break;
default:
- expect(S, "binary instruction");
+ expect("binary instruction");
}
}
-static void asm_coprocessor_opcode(TCCState *S, int token) {
+static void asm_coprocessor_opcode(TCCState *s1, int token) {
uint8_t coprocessor;
Operand opcode1;
Operand opcode2;
@@ -387,70 +387,70 @@ static void asm_coprocessor_opcode(TCCState *S, int token) {
uint8_t high_nibble;
uint8_t mrc = 0;
- if (S->tccpp_tok >= TOK_ASM_p0 && S->tccpp_tok <= TOK_ASM_p15) {
- coprocessor = S->tccpp_tok - TOK_ASM_p0;
- next(S);
+ if (tok >= TOK_ASM_p0 && tok <= TOK_ASM_p15) {
+ coprocessor = tok - TOK_ASM_p0;
+ next();
} else {
- expect(S, "'p<number>'");
+ expect("'p<number>'");
return;
}
- if (S->tccpp_tok == ',')
- next(S);
+ if (tok == ',')
+ next();
else
- expect(S, "','");
+ expect("','");
- parse_operand(S, &opcode1);
+ parse_operand(s1, &opcode1);
if (opcode1.type != OP_IM8 || opcode1.e.v > 15) {
- tcc_error(S, "opcode1 of instruction '%s' must be an immediate value between 0 and 15", get_tok_str(S, token, NULL));
+ tcc_error("opcode1 of instruction '%s' must be an immediate value between 0 and 15", get_tok_str(token, NULL));
return;
}
for (i = 0; i < 3; ++i) {
- if (S->tccpp_tok == ',')
- next(S);
+ if (tok == ',')
+ next();
else
- expect(S, "','");
+ expect("','");
if (i == 0 && token != TOK_ASM_cdp2 && (ARM_INSTRUCTION_GROUP(token) == TOK_ASM_mrceq || ARM_INSTRUCTION_GROUP(token) == TOK_ASM_mcreq)) {
- if (S->tccpp_tok >= TOK_ASM_r0 && S->tccpp_tok <= TOK_ASM_r15) {
- registers[i] = S->tccpp_tok - TOK_ASM_r0;
- next(S);
+ if (tok >= TOK_ASM_r0 && tok <= TOK_ASM_r15) {
+ registers[i] = tok - TOK_ASM_r0;
+ next();
} else {
- expect(S, "'r<number>'");
+ expect("'r<number>'");
return;
}
} else {
- if (S->tccpp_tok >= TOK_ASM_c0 && S->tccpp_tok <= TOK_ASM_c15) {
- registers[i] = S->tccpp_tok - TOK_ASM_c0;
- next(S);
+ if (tok >= TOK_ASM_c0 && tok <= TOK_ASM_c15) {
+ registers[i] = tok - TOK_ASM_c0;
+ next();
} else {
- expect(S, "'c<number>'");
+ expect("'c<number>'");
return;
}
}
}
- if (S->tccpp_tok == ',') {
- next(S);
- parse_operand(S, &opcode2);
+ if (tok == ',') {
+ next();
+ parse_operand(s1, &opcode2);
} else {
opcode2.type = OP_IM8;
opcode2.e.v = 0;
}
if (opcode2.type != OP_IM8 || opcode2.e.v > 15) {
- tcc_error(S, "opcode2 of instruction '%s' must be an immediate value between 0 and 15", get_tok_str(S, token, NULL));
+ tcc_error("opcode2 of instruction '%s' must be an immediate value between 0 and 15", get_tok_str(token, NULL));
return;
}
if (token == TOK_ASM_cdp2) {
high_nibble = 0xF;
- asm_emit_coprocessor_opcode(S, high_nibble, coprocessor, opcode1.e.v, registers[0], registers[1], registers[2], opcode2.e.v, 0);
+ asm_emit_coprocessor_opcode(high_nibble, coprocessor, opcode1.e.v, registers[0], registers[1], registers[2], opcode2.e.v, 0);
return;
} else
- high_nibble = condition_code_of_token(S, token);
+ high_nibble = condition_code_of_token(token);
switch (ARM_INSTRUCTION_GROUP(token)) {
case TOK_ASM_cdpeq:
- asm_emit_coprocessor_opcode(S, high_nibble, coprocessor, opcode1.e.v, registers[0], registers[1], registers[2], opcode2.e.v, 0);
+ asm_emit_coprocessor_opcode(high_nibble, coprocessor, opcode1.e.v, registers[0], registers[1], registers[2], opcode2.e.v, 0);
break;
case TOK_ASM_mrceq:
// opcode1 encoding changes! highest and lowest bit gone.
@@ -459,13 +459,13 @@ static void asm_coprocessor_opcode(TCCState *S, int token) {
case TOK_ASM_mcreq:
// opcode1 encoding changes! highest and lowest bit gone.
if (opcode1.e.v > 7) {
- tcc_error(S, "opcode1 of instruction '%s' must be an immediate value between 0 and 7", get_tok_str(S, token, NULL));
+ tcc_error("opcode1 of instruction '%s' must be an immediate value between 0 and 7", get_tok_str(token, NULL));
return;
}
- asm_emit_coprocessor_opcode(S, high_nibble, coprocessor, (opcode1.e.v << 1) | mrc, registers[0], registers[1], registers[2], opcode2.e.v, 1);
+ asm_emit_coprocessor_opcode(high_nibble, coprocessor, (opcode1.e.v << 1) | mrc, registers[0], registers[1], registers[2], opcode2.e.v, 1);
break;
default:
- expect(S, "known instruction");
+ expect("known instruction");
}
}
@@ -486,27 +486,27 @@ static void asm_coprocessor_opcode(TCCState *S, int token) {
#define ENCODE_BARREL_SHIFTER_REGISTER(register_index) ((register_index) << 8)
#define ENCODE_BARREL_SHIFTER_IMMEDIATE(value) ((value) << 7)
-static void asm_block_data_transfer_opcode(TCCState *S, int token)
+static void asm_block_data_transfer_opcode(TCCState *s1, int token)
{
uint32_t opcode;
int op0_exclam = 0;
Operand ops[2];
int nb_ops = 1;
- parse_operand(S, &ops[0]);
- if (S->tccpp_tok == '!') {
+ parse_operand(s1, &ops[0]);
+ if (tok == '!') {
op0_exclam = 1;
- next(S); // skip '!'
+ next(); // skip '!'
}
- if (S->tccpp_tok == ',') {
- next(S); // skip comma
- parse_operand(S, &ops[1]);
+ if (tok == ',') {
+ next(); // skip comma
+ parse_operand(s1, &ops[1]);
++nb_ops;
}
if (nb_ops < 1) {
- expect(S, "at least one operand");
+ expect("at least one operand");
return;
} else if (ops[nb_ops - 1].type != OP_REGSET32) {
- expect(S, "(last operand) register list");
+ expect("(last operand) register list");
return;
}
@@ -522,9 +522,9 @@ static void asm_block_data_transfer_opcode(TCCState *S, int token)
// Rn: base register
// Register List: bits 15...0
if (nb_ops != 1)
- expect(S, "exactly one operand");
+ expect("exactly one operand");
else
- asm_emit_opcode(S, token, (0x92d << 16) | ops[0].regset); // TODO: base register ?
+ asm_emit_opcode(token, (0x92d << 16) | ops[0].regset); // TODO: base register ?
break;
case TOK_ASM_popeq: // TODO: Optimize 1-register case to: ldr ?, [sp], #4
// Instruction: 1 I=0 P=0 U=1 S=0 W=0 L=1 << 20, op 1101
@@ -532,9 +532,9 @@ static void asm_block_data_transfer_opcode(TCCState *S, int token)
// Rn: base register
// Register List: bits 15...0
if (nb_ops != 1)
- expect(S, "exactly one operand");
+ expect("exactly one operand");
else
- asm_emit_opcode(S, token, (0x8bd << 16) | ops[0].regset); // TODO: base register ?
+ asm_emit_opcode(token, (0x8bd << 16) | ops[0].regset); // TODO: base register ?
break;
case TOK_ASM_stmdaeq:
case TOK_ASM_ldmdaeq:
@@ -574,23 +574,23 @@ static void asm_block_data_transfer_opcode(TCCState *S, int token)
opcode = 0x99 << 20;
break;
default:
- tcc_error(S, "internal error: This place should not be reached (fallback in asm_block_data_transfer_opcode)");
+ tcc_error("internal error: This place should not be reached (fallback in asm_block_data_transfer_opcode)");
}
// operands:
// Rn: first operand
// Register List: lower bits
if (nb_ops != 2)
- expect(S, "exactly two operands");
+ expect("exactly two operands");
else if (ops[0].type != OP_REG32)
- expect(S, "(first operand) register");
+ expect("(first operand) register");
else {
if (op0_exclam)
opcode |= 1 << 21; // writeback
- asm_emit_opcode(S, token, opcode | ENCODE_RN(ops[0].reg) | ops[1].regset);
+ asm_emit_opcode(token, opcode | ENCODE_RN(ops[0].reg) | ops[1].regset);
}
break;
default:
- expect(S, "block data transfer instruction");
+ expect("block data transfer instruction");
}
}
@@ -600,17 +600,17 @@ static void asm_block_data_transfer_opcode(TCCState *S, int token)
NB_SHIFT: will be set to 1 iff SHIFT is filled. Note that for rrx, there's no need to fill SHIFT.
SHIFT: will be filled in with the shift operand to use, if any. */
-static uint32_t asm_parse_optional_shift(TCCState* S, int* nb_shift, Operand* shift)
+static uint32_t asm_parse_optional_shift(TCCState* s1, int* nb_shift, Operand* shift)
{
uint32_t opcode = 0;
*nb_shift = 0;
- switch (S->tccpp_tok) {
+ switch (tok) {
case TOK_ASM_asl:
case TOK_ASM_lsl:
case TOK_ASM_asr:
case TOK_ASM_lsr:
case TOK_ASM_ror:
- switch (S->tccpp_tok) {
+ switch (tok) {
case TOK_ASM_asl:
/* fallthrough */
case TOK_ASM_lsl:
@@ -626,26 +626,26 @@ static uint32_t asm_parse_optional_shift(TCCState* S, int* nb_shift, Operand* sh
opcode = ENCODE_BARREL_SHIFTER_MODE_ROR;
break;
}
- next(S);
- parse_operand(S, shift);
+ next();
+ parse_operand(s1, shift);
*nb_shift = 1;
break;
case TOK_ASM_rrx:
- next(S);
+ next();
opcode = ENCODE_BARREL_SHIFTER_MODE_ROR;
break;
}
return opcode;
}
-static uint32_t asm_encode_shift(TCCState *S, Operand* shift)
+static uint32_t asm_encode_shift(Operand* shift)
{
uint64_t amount;
uint32_t operands = 0;
switch (shift->type) {
case OP_REG32:
if (shift->reg == 15)
- tcc_error(S, "r15 cannot be used as a shift count");
+ tcc_error("r15 cannot be used as a shift count");
else {
operands = ENCODE_BARREL_SHIFTER_SHIFT_BY_REGISTER;
operands |= ENCODE_BARREL_SHIFTER_REGISTER(shift->reg);
@@ -656,15 +656,15 @@ static uint32_t asm_encode_shift(TCCState *S, Operand* shift)
if (amount > 0 && amount < 32)
operands = ENCODE_BARREL_SHIFTER_IMMEDIATE(amount);
else
- tcc_error(S, "shift count out of range");
+ tcc_error("shift count out of range");
break;
default:
- tcc_error(S, "unknown shift amount");
+ tcc_error("unknown shift amount");
}
return operands;
}
-static void asm_data_processing_opcode(TCCState *S, int token)
+static void asm_data_processing_opcode(TCCState *s1, int token)
{
Operand ops[3];
int nb_ops;
@@ -677,31 +677,31 @@ static void asm_data_processing_opcode(TCCState *S, int token)
uint32_t opcode_nos = opcode_idx >> 1; // without "s"; "OpCode" in ARM docs
for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ) {
- 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)
+ 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)
break;
- parse_operand(S, &ops[nb_ops]);
+ parse_operand(s1, &ops[nb_ops]);
++nb_ops;
- if (S->tccpp_tok != ',')
+ if (tok != ',')
break;
- next(S); // skip ','
+ next(); // skip ','
}
- if (S->tccpp_tok == ',')
- next(S);
- operands |= asm_parse_optional_shift(S, &nb_shift, &shift);
+ if (tok == ',')
+ next();
+ operands |= asm_parse_optional_shift(s1, &nb_shift, &shift);
if (nb_ops < 2)
- expect(S, "at least two operands");
+ expect("at least two operands");
else if (nb_ops == 2) {
memcpy(&ops[2], &ops[1], sizeof(ops[1])); // move ops[2]
memcpy(&ops[1], &ops[0], sizeof(ops[0])); // ops[1] was implicit
nb_ops = 3;
} else if (nb_ops == 3) {
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
- tcc_error(S, "'%s' cannot be used with three operands", get_tok_str(S, token, NULL));
+ tcc_error("'%s' cannot be used with three operands", get_tok_str(token, NULL));
return;
}
}
if (nb_ops != 3) {
- expect(S, "two or three operands");
+ expect("two or three operands");
return;
} else {
uint32_t opcode = 0;
@@ -710,7 +710,7 @@ static void asm_data_processing_opcode(TCCState *S, int token)
if (nb_shift && shift.type == OP_REG32) {
if ((ops[0].type == OP_REG32 && ops[0].reg == 15) ||
(ops[1].type == OP_REG32 && ops[1].reg == 15)) {
- tcc_error(S, "Using the 'pc' register in data processing instructions that have a register-controlled shift is not implemented by ARM");
+ tcc_error("Using the 'pc' register in data processing instructions that have a register-controlled shift is not implemented by ARM");
return;
}
}
@@ -726,13 +726,13 @@ static void asm_data_processing_opcode(TCCState *S, int token)
/* operations in the token list are ordered by opcode */
opcode = opcode_nos << 21; // drop "s"
if (ops[0].type != OP_REG32)
- expect(S, "(destination operand) register");
+ expect("(destination operand) register");
else if (opcode_nos == 0xa || opcode_nos == 0xb || opcode_nos == 0x8 || opcode_nos == 0x9) // cmp, cmn, tst, teq
operands |= ENCODE_SET_CONDITION_CODES; // force S set, otherwise it's a completely different instruction.
else
operands |= ENCODE_RD(ops[0].reg);
if (ops[1].type != OP_REG32)
- expect(S, "(first source operand) register");
+ expect("(first source operand) register");
else if (!(opcode_nos == 0xd || opcode_nos == 0xf)) // not: mov, mvn (those have only one source operand)
operands |= ENCODE_RN(ops[1].reg);
switch (ops[2].type) {
@@ -809,7 +809,7 @@ static void asm_data_processing_opcode(TCCState *S, int token)
immediate_value = ~immediate_value;
break;
default:
- tcc_error(S, "cannot use '%s' with a negative immediate value", get_tok_str(S, token, NULL));
+ tcc_error("cannot use '%s' with a negative immediate value", get_tok_str(token, NULL));
}
for (half_immediate_rotation = 0; half_immediate_rotation < 16; ++half_immediate_rotation) {
if (immediate_value >= 0x00 && immediate_value < 0x100)
@@ -819,30 +819,30 @@ static void asm_data_processing_opcode(TCCState *S, int token)
}
if (half_immediate_rotation >= 16) {
immediate_value = ops[2].e.v;
- tcc_error(S, "immediate value 0x%X cannot be encoded into ARM immediate", (unsigned) immediate_value);
+ tcc_error("immediate value 0x%X cannot be encoded into ARM immediate", (unsigned) immediate_value);
return;
}
operands |= immediate_value;
operands |= half_immediate_rotation << 8;
break;
default:
- expect(S, "(second source operand) register or immediate value");
+ expect("(second source operand) register or immediate value");
}
if (nb_shift) {
if (operands & ENCODE_IMMEDIATE_FLAG)
- tcc_error(S, "immediate rotation not implemented");
+ tcc_error("immediate rotation not implemented");
else
- operands |= asm_encode_shift(S, &shift);
+ operands |= asm_encode_shift(&shift);
}
/* S=0 and S=1 entries alternate one after another, in that order */
opcode |= (opcode_idx & 1) ? ENCODE_SET_CONDITION_CODES : 0;
- asm_emit_opcode(S, token, opcode | operands);
+ asm_emit_opcode(token, opcode | operands);
}
}
-static void asm_shift_opcode(TCCState *S, int token)
+static void asm_shift_opcode(TCCState *s1, int token)
{
Operand ops[3];
int nb_ops;
@@ -851,20 +851,20 @@ static void asm_shift_opcode(TCCState *S, int token)
uint32_t operands = 0;
for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) {
- parse_operand(S, &ops[nb_ops]);
- if (S->tccpp_tok != ',') {
+ parse_operand(s1, &ops[nb_ops]);
+ if (tok != ',') {
++nb_ops;
break;
}
- next(S); // skip ','
+ next(); // skip ','
}
if (nb_ops < 2) {
- expect(S, "at least two operands");
+ expect("at least two operands");
return;
}
if (ops[0].type != OP_REG32) {
- expect(S, "(destination operand) register");
+ expect("(destination operand) register");
return;
} else
operands |= ENCODE_RD(ops[0].reg);
@@ -878,9 +878,9 @@ static void asm_shift_opcode(TCCState *S, int token)
if (ops[1].type == OP_REG32) {
operands |= ops[1].reg;
operands |= ENCODE_BARREL_SHIFTER_MODE_ROR;
- asm_emit_opcode(S, token, opcode | operands);
+ asm_emit_opcode(token, opcode | operands);
} else
- tcc_error(S, "(first source operand) register");
+ tcc_error("(first source operand) register");
return;
default:
memcpy(&ops[2], &ops[1], sizeof(ops[1])); // move ops[2]
@@ -889,7 +889,7 @@ static void asm_shift_opcode(TCCState *S, int token)
}
}
if (nb_ops != 3) {
- expect(S, "two or three operands");
+ expect("two or three operands");
return;
}
@@ -909,7 +909,7 @@ static void asm_shift_opcode(TCCState *S, int token)
case OP_IM8:
operands |= ENCODE_IMMEDIATE_FLAG;
operands |= ops[1].e.v;
- 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));
+ tcc_error("Using an immediate value as the source operand is not possible with '%s' instruction on ARM", get_tok_str(token, NULL));
return;
}
@@ -917,13 +917,13 @@ static void asm_shift_opcode(TCCState *S, int token)
case OP_REG32:
if ((ops[0].type == OP_REG32 && ops[0].reg == 15) ||
(ops[1].type == OP_REG32 && ops[1].reg == 15)) {
- tcc_error(S, "Using the 'pc' register in data processing instructions that have a register-controlled shift is not implemented by ARM");
+ tcc_error("Using the 'pc' register in data processing instructions that have a register-controlled shift is not implemented by ARM");
}
- operands |= asm_encode_shift(S, &ops[2]);
+ operands |= asm_encode_shift(&ops[2]);
break;
case OP_IM8:
if (ops[2].e.v)
- operands |= asm_encode_shift(S, &ops[2]);
+ operands |= asm_encode_shift(&ops[2]);
else
definitely_neutral = 1;
break;
@@ -947,28 +947,28 @@ static void asm_shift_opcode(TCCState *S, int token)
operands |= ENCODE_BARREL_SHIFTER_MODE_ROR;
break;
default:
- expect(S, "shift instruction");
+ expect("shift instruction");
return;
}
- asm_emit_opcode(S, token, opcode | operands);
+ asm_emit_opcode(token, opcode | operands);
}
-static void asm_multiplication_opcode(TCCState *S, int token)
+static void asm_multiplication_opcode(TCCState *s1, int token)
{
Operand ops[4];
int nb_ops = 0;
uint32_t opcode = 0x90;
for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) {
- parse_operand(S, &ops[nb_ops]);
- if (S->tccpp_tok != ',') {
+ parse_operand(s1, &ops[nb_ops]);
+ if (tok != ',') {
++nb_ops;
break;
}
- next(S); // skip ','
+ next(); // skip ','
}
if (nb_ops < 2)
- expect(S, "at least two operands");
+ expect("at least two operands");
else if (nb_ops == 2) {
switch (ARM_INSTRUCTION_GROUP(token)) {
case TOK_ASM_mulseq:
@@ -976,7 +976,7 @@ static void asm_multiplication_opcode(TCCState *S, int token)
memcpy(&ops[2], &ops[0], sizeof(ops[1])); // ARM is actually like this!
break;
default:
- expect(S, "at least three operands");
+ expect("at least three operands");
return;
}
nb_ops = 3;
@@ -992,20 +992,20 @@ static void asm_multiplication_opcode(TCCState *S, int token)
if (ops[0].type == OP_REG32)
opcode |= ops[0].reg << 16;
else
- expect(S, "(destination operand) register");
+ expect("(destination operand) register");
if (ops[1].type == OP_REG32)
opcode |= ops[1].reg;
else
- expect(S, "(first source operand) register");
+ expect("(first source operand) register");
if (ops[2].type == OP_REG32)
opcode |= ops[2].reg << 8;
else
- expect(S, "(second source operand) register");
+ expect("(second source operand) register");
if (nb_ops > 3) {
if (ops[3].type == OP_REG32)
opcode |= ops[3].reg << 12;
else
- expect(S, "(third source operand) register");
+ expect("(third source operand) register");
}
switch (ARM_INSTRUCTION_GROUP(token)) {
@@ -1014,9 +1014,9 @@ static void asm_multiplication_opcode(TCCState *S, int token)
/* fallthrough */
case TOK_ASM_muleq:
if (nb_ops != 3)
- expect(S, "three operands");
+ expect("three operands");
else {
- asm_emit_opcode(S, token, opcode);
+ asm_emit_opcode(token, opcode);
}
break;
case TOK_ASM_mlaseq:
@@ -1024,33 +1024,33 @@ static void asm_multiplication_opcode(TCCState *S, int token)
/* fallthrough */
case TOK_ASM_mlaeq:
if (nb_ops != 4)
- expect(S, "four operands");
+ expect("four operands");
else {
opcode |= 1 << 21; // Accumulate
- asm_emit_opcode(S, token, opcode);
+ asm_emit_opcode(token, opcode);
}
break;
default:
- expect(S, "known multiplication instruction");
+ expect("known multiplication instruction");
}
}
-static void asm_long_multiplication_opcode(TCCState *S, int token)
+static void asm_long_multiplication_opcode(TCCState *s1, int token)
{
Operand ops[4];
int nb_ops = 0;
uint32_t opcode = 0x90 | (1 << 23);
for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) {
- parse_operand(S, &ops[nb_ops]);
- if (S->tccpp_tok != ',') {
+ parse_operand(s1, &ops[nb_ops]);
+ if (tok != ',') {
++nb_ops;
break;
}
- next(S); // skip ','
+ next(); // skip ','
}
if (nb_ops != 4) {
- expect(S, "four operands");
+ expect("four operands");
return;
}
@@ -1064,19 +1064,19 @@ static void asm_long_multiplication_opcode(TCCState *S, int token)
if (ops[0].type == OP_REG32)
opcode |= ops[0].reg << 12;
else
- expect(S, "(destination lo accumulator) register");
+ expect("(destination lo accumulator) register");
if (ops[1].type == OP_REG32)
opcode |= ops[1].reg << 16;
else
- expect(S, "(destination hi accumulator) register");
+ expect("(destination hi accumulator) register");
if (ops[2].type == OP_REG32)
opcode |= ops[2].reg;
else
- expect(S, "(first source operand) register");
+ expect("(first source operand) register");
if (ops[3].type == OP_REG32)
opcode |= ops[3].reg << 8;
else
- expect(S, "(second source operand) register");
+ expect("(second source operand) register");
switch (ARM_INSTRUCTION_GROUP(token)) {
case TOK_ASM_smullseq:
@@ -1084,13 +1084,13 @@ static void asm_long_multiplication_opcode(TCCState *S, int token)
/* fallthrough */
case TOK_ASM_smulleq:
opcode |= 1 << 22; // signed
- asm_emit_opcode(S, token, opcode);
+ asm_emit_opcode(token, opcode);
break;
case TOK_ASM_umullseq:
opcode |= 1 << 20; // Status
/* fallthrough */
case TOK_ASM_umulleq:
- asm_emit_opcode(S, token, opcode);
+ asm_emit_opcode(token, opcode);
break;
case TOK_ASM_smlalseq:
opcode |= 1 << 20; // Status
@@ -1098,21 +1098,21 @@ static void asm_long_multiplication_opcode(TCCState *S, int token)
case TOK_ASM_smlaleq:
opcode |= 1 << 22; // signed
opcode |= 1 << 21; // Accumulate
- asm_emit_opcode(S, token, opcode);
+ asm_emit_opcode(token, opcode);
break;
case TOK_ASM_umlalseq:
opcode |= 1 << 20; // Status
/* fallthrough */
case TOK_ASM_umlaleq:
opcode |= 1 << 21; // Accumulate
- asm_emit_opcode(S, token, opcode);
+ asm_emit_opcode(token, opcode);
break;
default:
- expect(S, "known long multiplication instruction");
+ expect("known long multiplication instruction");
}
}
-static void asm_single_data_transfer_opcode(TCCState *S, int token)
+static void asm_single_data_transfer_opcode(TCCState *s1, int token)
{
Operand ops[3];
Operand strex_operand;
@@ -1126,67 +1126,67 @@ static void asm_single_data_transfer_opcode(TCCState *S, int token)
// Note: ldr r0, [r4, #4]! ; pre-indexed: r0 = *(int*)(r4+4); r4 = r4+4
// Note: ldr r0, [r4], #4 ; post-indexed: r0 = *(int*)(r4+0); r4 = r4+4
- parse_operand(S, &ops[0]);
+ parse_operand(s1, &ops[0]);
if (ops[0].type == OP_REG32)
opcode |= ENCODE_RD(ops[0].reg);
else {
- expect(S, "(destination operand) register");
+ expect("(destination operand) register");
return;
}
- if (S->tccpp_tok != ',')
- expect(S, "at least two arguments");
+ if (tok != ',')
+ expect("at least two arguments");
else
- next(S); // skip ','
+ next(); // skip ','
switch (ARM_INSTRUCTION_GROUP(token)) {
case TOK_ASM_strexbeq:
case TOK_ASM_strexeq:
- parse_operand(S, &strex_operand);
+ parse_operand(s1, &strex_operand);
if (strex_operand.type != OP_REG32) {
- expect(S, "register");
+ expect("register");
return;
}
- if (S->tccpp_tok != ',')
- expect(S, "at least three arguments");
+ if (tok != ',')
+ expect("at least three arguments");
else
- next(S); // skip ','
+ next(); // skip ','
break;
}
- if (S->tccpp_tok != '[')
- expect(S, "'['");
+ if (tok != '[')
+ expect("'['");
else
- next(S); // skip '['
+ next(); // skip '['
- parse_operand(S, &ops[1]);
+ parse_operand(s1, &ops[1]);
if (ops[1].type == OP_REG32)
opcode |= ENCODE_RN(ops[1].reg);
else {
- expect(S, "(first source operand) register");
+ expect("(first source operand) register");
return;
}
- if (S->tccpp_tok == ']') {
- next(S);
+ if (tok == ']') {
+ next();
closed_bracket = 1;
// exclam = 1; // implicit in hardware; don't do it in software
}
- if (S->tccpp_tok == ',') {
- next(S); // skip ','
- if (S->tccpp_tok == '-') {
+ if (tok == ',') {
+ next(); // skip ','
+ if (tok == '-') {
op2_minus = 1;
- next(S);
+ next();
}
- parse_operand(S, &ops[2]);
+ parse_operand(s1, &ops[2]);
if (ops[2].type == OP_REG32) {
if (ops[2].reg == 15) {
- tcc_error(S, "Using 'pc' for register offset in '%s' is not implemented by ARM", get_tok_str(S, token, NULL));
+ tcc_error("Using 'pc' for register offset in '%s' is not implemented by ARM", get_tok_str(token, NULL));
return;
}
- if (S->tccpp_tok == ',') {
- next(S);
- opcode |= asm_parse_optional_shift(S, &nb_shift, &shift);
+ if (tok == ',') {
+ next();
+ opcode |= asm_parse_optional_shift(s1, &nb_shift, &shift);
if (opcode == 0)
- expect(S, "shift directive, or no comma");
+ expect("shift directive, or no comma");
}
}
} else {
@@ -1196,14 +1196,14 @@ static void asm_single_data_transfer_opcode(TCCState *S, int token)
opcode |= 1 << 24; // add offset before transfer
}
if (!closed_bracket) {
- if (S->tccpp_tok != ']')
- expect(S, "']'");
+ if (tok != ']')
+ expect("']'");
else
- next(S); // skip ']'
+ next(); // skip ']'
opcode |= 1 << 24; // add offset before transfer
- if (S->tccpp_tok == '!') {
+ if (tok == '!') {
exclam = 1;
- next(S); // skip '!'
+ next(); // skip '!'
}
}
@@ -1224,16 +1224,16 @@ static void asm_single_data_transfer_opcode(TCCState *S, int token)
if (ops[2].type == OP_IM32 || ops[2].type == OP_IM8 || ops[2].type == OP_IM8N) {
int v = ops[2].e.v;
if (op2_minus)
- tcc_error(S, "minus before '#' not supported for immediate values");
+ tcc_error("minus before '#' not supported for immediate values");
if (v >= 0) {
opcode |= 1 << 23; // up
if (v >= 0x1000)
- tcc_error(S, "offset out of range for '%s'", get_tok_str(S, token, NULL));
+ tcc_error("offset out of range for '%s'", get_tok_str(token, NULL));
else
opcode |= v;
} else { // down
if (v <= -0x1000)
- tcc_error(S, "offset out of range for '%s'", get_tok_str(S, token, NULL));
+ tcc_error("offset out of range for '%s'", get_tok_str(token, NULL));
else
opcode |= -v;
}
@@ -1243,7 +1243,7 @@ static void asm_single_data_transfer_opcode(TCCState *S, int token)
opcode |= ENCODE_IMMEDIATE_FLAG; /* if set, it means it's NOT immediate */
opcode |= ops[2].reg;
} else
- expect(S, "register");
+ expect("register");
switch (ARM_INSTRUCTION_GROUP(token)) {
case TOK_ASM_strbeq:
@@ -1252,8 +1252,8 @@ static void asm_single_data_transfer_opcode(TCCState *S, int token)
case TOK_ASM_streq:
opcode |= 1 << 26; // Load/Store
if (nb_shift)
- opcode |= asm_encode_shift(S, &shift);
- asm_emit_opcode(S, token, opcode);
+ opcode |= asm_encode_shift(&shift);
+ asm_emit_opcode(token, opcode);
break;
case TOK_ASM_ldrbeq:
opcode |= 1 << 22; // B
@@ -1262,56 +1262,56 @@ static void asm_single_data_transfer_opcode(TCCState *S, int token)
opcode |= 1 << 20; // L
opcode |= 1 << 26; // Load/Store
if (nb_shift)
- opcode |= asm_encode_shift(S, &shift);
- asm_emit_opcode(S, token, opcode);
+ opcode |= asm_encode_shift(&shift);
+ asm_emit_opcode(token, opcode);
break;
case TOK_ASM_strexbeq:
opcode |= 1 << 22; // B
/* fallthrough */
case TOK_ASM_strexeq:
if ((opcode & 0xFFF) || nb_shift) {
- tcc_error(S, "neither offset nor shift allowed with 'strex'");
+ tcc_error("neither offset nor shift allowed with 'strex'");
return;
} else if (opcode & ENCODE_IMMEDIATE_FLAG) { // if set, it means it's NOT immediate
- tcc_error(S, "offset not allowed with 'strex'");
+ tcc_error("offset not allowed with 'strex'");
return;
}
if ((opcode & (1 << 24)) == 0) { // add offset after transfer
- tcc_error(S, "adding offset after transfer not allowed with 'strex'");
+ tcc_error("adding offset after transfer not allowed with 'strex'");
return;
}
opcode |= 0xf90; // Used to mean: barrel shifter is enabled, barrel shift register is r15, mode is LSL
opcode |= strex_operand.reg;
- asm_emit_opcode(S, token, opcode);
+ asm_emit_opcode(token, opcode);
break;
case TOK_ASM_ldrexbeq:
opcode |= 1 << 22; // B
/* fallthrough */
case TOK_ASM_ldrexeq:
if ((opcode & 0xFFF) || nb_shift) {
- tcc_error(S, "neither offset nor shift allowed with 'ldrex'");
+ tcc_error("neither offset nor shift allowed with 'ldrex'");
return;
} else if (opcode & ENCODE_IMMEDIATE_FLAG) { // if set, it means it's NOT immediate
- tcc_error(S, "offset not allowed with 'ldrex'");
+ tcc_error("offset not allowed with 'ldrex'");
return;
}
if ((opcode & (1 << 24)) == 0) { // add offset after transfer
- tcc_error(S, "adding offset after transfer not allowed with 'ldrex'");
+ tcc_error("adding offset after transfer not allowed with 'ldrex'");
return;
}
opcode |= 1 << 20; // L
opcode |= 0x00f;
opcode |= 0xf90; // Used to mean: barrel shifter is enabled, barrel shift register is r15, mode is LSL
- asm_emit_opcode(S, token, opcode);
+ asm_emit_opcode(token, opcode);
break;
default:
- expect(S, "data transfer instruction");
+ expect("data transfer instruction");
}
}
// 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)
-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) {
+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) {
uint32_t opcode = 0x0;
opcode |= 1 << 26; // Load/Store
opcode |= 1 << 27; // coprocessor
@@ -1328,7 +1328,7 @@ static void asm_emit_coprocessor_data_transfer(TCCState *S, uint32_t high_nibble
opcode |= ENCODE_RD(CRd);
if (Rn->type != OP_REG32) {
- expect(S, "register");
+ expect("register");
return;
}
//assert(Rn->reg < 16);
@@ -1342,18 +1342,18 @@ static void asm_emit_coprocessor_data_transfer(TCCState *S, uint32_t high_nibble
if (offset->type == OP_IM8 || offset->type == OP_IM8N || offset->type == OP_IM32) {
int v = offset->e.v;
if (offset_minus)
- tcc_error(S, "minus before '#' not supported for immediate values");
+ tcc_error("minus before '#' not supported for immediate values");
if (offset->type == OP_IM8N || v < 0)
v = -v;
else
opcode |= 1 << 23; // up
if (v & 3) {
- tcc_error(S, "immediate offset must be a multiple of 4");
+ tcc_error("immediate offset must be a multiple of 4");
return;
}
v >>= 2;
if (v > 255) {
- tcc_error(S, "immediate offset must be between -1020 and 1020");
+ tcc_error("immediate offset must be between -1020 and 1020");
return;
}
opcode |= v;
@@ -1362,20 +1362,20 @@ static void asm_emit_coprocessor_data_transfer(TCCState *S, uint32_t high_nibble
opcode |= 1 << 23; // up
opcode |= ENCODE_IMMEDIATE_FLAG; /* if set, it means it's NOT immediate */
opcode |= offset->reg;
- tcc_error(S, "Using register offset to register address is not possible here");
+ tcc_error("Using register offset to register address is not possible here");
return;
} else if (offset->type == OP_VREG64) {
opcode |= 16;
opcode |= offset->reg;
} else
- expect(S, "immediate or register");
+ expect("immediate or register");
- asm_emit_unconditional_opcode(S, (high_nibble << 28) | opcode);
+ asm_emit_unconditional_opcode((high_nibble << 28) | opcode);
}
// Almost exactly the same as asm_single_data_transfer_opcode.
// Difference: Offsets are smaller and multiples of 4; no shifts, no STREX, ENCODE_IMMEDIATE_FLAG is inverted again.
-static void asm_coprocessor_data_transfer_opcode(TCCState *S, int token)
+static void asm_coprocessor_data_transfer_opcode(TCCState *s1, int token)
{
Operand ops[3];
uint8_t coprocessor;
@@ -1389,61 +1389,61 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *S, int token)
// Note: ldc p2, c0, [r4, #4]! ; pre-indexed: r0 = *(int*)(r4+4); r4 = r4+4
// Note: ldc p3, c0, [r4], #4 ; post-indexed: r0 = *(int*)(r4+0); r4 = r4+4
- if (S->tccpp_tok >= TOK_ASM_p0 && S->tccpp_tok <= TOK_ASM_p15) {
- coprocessor = S->tccpp_tok - TOK_ASM_p0;
- next(S);
+ if (tok >= TOK_ASM_p0 && tok <= TOK_ASM_p15) {
+ coprocessor = tok - TOK_ASM_p0;
+ next();
} else {
- expect(S, "'c<number>'");
+ expect("'c<number>'");
return;
}
- if (S->tccpp_tok == ',')
- next(S);
+ if (tok == ',')
+ next();
else
- expect(S, "','");
+ expect("','");
- if (S->tccpp_tok >= TOK_ASM_c0 && S->tccpp_tok <= TOK_ASM_c15) {
- coprocessor_destination_register = S->tccpp_tok - TOK_ASM_c0;
- next(S);
+ if (tok >= TOK_ASM_c0 && tok <= TOK_ASM_c15) {
+ coprocessor_destination_register = tok - TOK_ASM_c0;
+ next();
} else {
- expect(S, "'c<number>'");
+ expect("'c<number>'");
return;
}
- if (S->tccpp_tok == ',')
- next(S);
+ if (tok == ',')
+ next();
else
- expect(S, "','");
+ expect("','");
- if (S->tccpp_tok != '[')
- expect(S, "'['");
+ if (tok != '[')
+ expect("'['");
else
- next(S); // skip '['
+ next(); // skip '['
- parse_operand(S, &ops[1]);
+ parse_operand(s1, &ops[1]);
if (ops[1].type != OP_REG32) {
- expect(S, "(first source operand) register");
+ expect("(first source operand) register");
return;
}
- if (S->tccpp_tok == ']') {
- next(S);
+ if (tok == ']') {
+ next();
closed_bracket = 1;
// exclam = 1; // implicit in hardware; don't do it in software
}
- if (S->tccpp_tok == ',') {
- next(S); // skip ','
- if (S->tccpp_tok == '-') {
+ if (tok == ',') {
+ next(); // skip ','
+ if (tok == '-') {
op2_minus = 1;
- next(S);
+ next();
}
- parse_operand(S, &ops[2]);
+ parse_operand(s1, &ops[2]);
if (ops[2].type == OP_REG32) {
if (ops[2].reg == 15) {
- tcc_error(S, "Using 'pc' for register offset in '%s' is not implemented by ARM", get_tok_str(S, token, NULL));
+ tcc_error("Using 'pc' for register offset in '%s' is not implemented by ARM", get_tok_str(token, NULL));
return;
}
} else if (ops[2].type == OP_VREG64) {
- tcc_error(S, "'%s' does not support VFP register operand", get_tok_str(S, token, NULL));
+ tcc_error("'%s' does not support VFP register operand", get_tok_str(token, NULL));
return;
}
} else {
@@ -1453,14 +1453,14 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *S, int token)
preincrement = 1; // add offset before transfer
}
if (!closed_bracket) {
- if (S->tccpp_tok != ']')
- expect(S, "']'");
+ if (tok != ']')
+ expect("']'");
else
- next(S); // skip ']'
+ next(); // skip ']'
preincrement = 1; // add offset before transfer
- if (S->tccpp_tok == '!') {
+ if (tok == '!') {
exclam = 1;
- next(S); // skip '!'
+ next(); // skip '!'
}
}
@@ -1472,13 +1472,13 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *S, int token)
long_transfer = 1; // long transfer
/* fallthrough */
case TOK_ASM_ldc2:
- asm_emit_coprocessor_data_transfer(S, 0xF, coprocessor, coprocessor_destination_register, &ops[1], &ops[2], op2_minus, preincrement, exclam, long_transfer, 1);
+ asm_emit_coprocessor_data_transfer(0xF, coprocessor, coprocessor_destination_register, &ops[1], &ops[2], op2_minus, preincrement, exclam, long_transfer, 1);
break;
case TOK_ASM_stc2l:
long_transfer = 1; // long transfer
/* fallthrough */
case TOK_ASM_stc2:
- asm_emit_coprocessor_data_transfer(S, 0xF, coprocessor, coprocessor_destination_register, &ops[1], &ops[2], op2_minus, preincrement, exclam, long_transfer, 0);
+ asm_emit_coprocessor_data_transfer(0xF, coprocessor, coprocessor_destination_register, &ops[1], &ops[2], op2_minus, preincrement, exclam, long_transfer, 0);
break;
}
} else switch (ARM_INSTRUCTION_GROUP(token)) {
@@ -1486,16 +1486,16 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *S, int token)
long_transfer = 1;
/* fallthrough */
case TOK_ASM_stceq:
- 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);
+ 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);
break;
case TOK_ASM_ldcleq:
long_transfer = 1;
/* fallthrough */
case TOK_ASM_ldceq:
- 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);
+ 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);
break;
default:
- expect(S, "coprocessor data transfer instruction");
+ expect("coprocessor data transfer instruction");
}
}
@@ -1503,7 +1503,7 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *S, int token)
#define CP_SINGLE_PRECISION_FLOAT 10
#define CP_DOUBLE_PRECISION_FLOAT 11
-static void asm_floating_point_single_data_transfer_opcode(TCCState *S, int token)
+static void asm_floating_point_single_data_transfer_opcode(TCCState *s1, int token)
{
Operand ops[3];
uint8_t coprocessor = 0;
@@ -1513,7 +1513,7 @@ static void asm_floating_point_single_data_transfer_opcode(TCCState *S, int toke
// Note: Not allowed: vldr p2, c0, [r4, #4]! ; pre-indexed: r0 = *(int*)(r4+4); r4 = r4+4
// Note: Not allowed: vldr p3, c0, [r4], #4 ; post-indexed: r0 = *(int*)(r4+0); r4 = r4+4
- parse_operand(S, &ops[0]);
+ parse_operand(s1, &ops[0]);
if (ops[0].type == OP_VREG32) {
coprocessor = CP_SINGLE_PRECISION_FLOAT;
coprocessor_destination_register = ops[0].reg;
@@ -1522,32 +1522,32 @@ static void asm_floating_point_single_data_transfer_opcode(TCCState *S, int toke
} else if (ops[0].type == OP_VREG64) {
coprocessor = CP_DOUBLE_PRECISION_FLOAT;
coprocessor_destination_register = ops[0].reg;
- next(S);
+ next();
} else {
- expect(S, "floating point register");
+ expect("floating point register");
return;
}
- if (S->tccpp_tok == ',')
- next(S);
+ if (tok == ',')
+ next();
else
- expect(S, "','");
+ expect("','");
- if (S->tccpp_tok != '[')
- expect(S, "'['");
+ if (tok != '[')
+ expect("'['");
else
- next(S); // skip '['
+ next(); // skip '['
- parse_operand(S, &ops[1]);
+ parse_operand(s1, &ops[1]);
if (ops[1].type != OP_REG32) {
- expect(S, "(first source operand) register");
+ expect("(first source operand) register");
return;
}
- if (S->tccpp_tok == ',') {
- next(S); // skip ','
- parse_operand(S, &ops[2]);
+ if (tok == ',') {
+ next(); // skip ','
+ parse_operand(s1, &ops[2]);
if (ops[2].type != OP_IM8 && ops[2].type != OP_IM8N) {
- expect(S, "immediate offset");
+ expect("immediate offset");
return;
}
} else {
@@ -1555,24 +1555,24 @@ static void asm_floating_point_single_data_transfer_opcode(TCCState *S, int toke
ops[2].type = OP_IM8;
ops[2].e.v = 0;
}
- if (S->tccpp_tok != ']')
- expect(S, "']'");
+ if (tok != ']')
+ expect("']'");
else
- next(S); // skip ']'
+ next(); // skip ']'
switch (ARM_INSTRUCTION_GROUP(token)) {
case TOK_ASM_vldreq:
- 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);
+ asm_emit_coprocessor_data_transfer(condition_code_of_token(token), coprocessor, coprocessor_destination_register, &ops[1], &ops[2], 0, 1, 0, long_transfer, 1);
break;
case TOK_ASM_vstreq:
- 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);
+ asm_emit_coprocessor_data_transfer(condition_code_of_token(token), coprocessor, coprocessor_destination_register, &ops[1], &ops[2], 0, 1, 0, long_transfer, 0);
break;
default:
- expect(S, "floating point data transfer instruction");
+ expect("floating point data transfer instruction");
}
}
-static void asm_floating_point_block_data_transfer_opcode(TCCState *S, int token)
+static void asm_floating_point_block_data_transfer_opcode(TCCState *s1, int token)
{
uint8_t coprocessor = 0;
int first_regset_register;
@@ -1592,56 +1592,56 @@ static void asm_floating_point_block_data_transfer_opcode(TCCState *S, int token
op0_exclam = 1;
break;
default:
- parse_operand(S, &ops[0]);
- if (S->tccpp_tok == '!') {
+ parse_operand(s1, &ops[0]);
+ if (tok == '!') {
op0_exclam = 1;
- next(S); // skip '!'
+ next(); // skip '!'
}
- if (S->tccpp_tok == ',')
- next(S); // skip comma
+ if (tok == ',')
+ next(); // skip comma
else {
- expect(S, "','");
+ expect("','");
return;
}
}
- if (S->tccpp_tok != '{') {
- expect(S, "'{'");
+ if (tok != '{') {
+ expect("'{'");
return;
}
- next(S); // skip '{'
- first_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, 1);
- if ((first_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, 1)) != -1) {
+ next(); // skip '{'
+ first_regset_register = asm_parse_vfp_regvar(tok, 1);
+ if ((first_regset_register = asm_parse_vfp_regvar(tok, 1)) != -1) {
coprocessor = CP_DOUBLE_PRECISION_FLOAT;
- next(S);
- } else if ((first_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, 0)) != -1) {
+ next();
+ } else if ((first_regset_register = asm_parse_vfp_regvar(tok, 0)) != -1) {
coprocessor = CP_SINGLE_PRECISION_FLOAT;
- next(S);
+ next();
} else {
- expect(S, "floating-point register");
+ expect("floating-point register");
return;
}
- if (S->tccpp_tok == '-') {
- next(S);
- if ((last_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, coprocessor == CP_DOUBLE_PRECISION_FLOAT)) != -1)
- next(S);
+ if (tok == '-') {
+ next();
+ if ((last_regset_register = asm_parse_vfp_regvar(tok, coprocessor == CP_DOUBLE_PRECISION_FLOAT)) != -1)
+ next();
else {
- expect(S, "floating-point register");
+ expect("floating-point register");
return;
}
} else
last_regset_register = first_regset_register;
if (last_regset_register < first_regset_register) {
- tcc_error(S, "registers will be processed in ascending order by hardware--but are not specified in ascending order here");
+ tcc_error("registers will be processed in ascending order by hardware--but are not specified in ascending order here");
return;
}
- if (S->tccpp_tok != '}') {
- expect(S, "'}'");
+ if (tok != '}') {
+ expect("'}'");
return;
}
- next(S); // skip '}'
+ next(); // skip '}'
// Note: 0 (one down) is not implemented by us regardless.
regset_item_count = last_regset_register - first_regset_register + 1;
@@ -1672,23 +1672,23 @@ static void asm_floating_point_block_data_transfer_opcode(TCCState *S, int token
preincrement = 1;
break;
default:
- expect(S, "floating point block data transfer instruction");
+ expect("floating point block data transfer instruction");
return;
}
if (ops[0].type != OP_REG32)
- expect(S, "(first operand) register");
+ expect("(first operand) register");
else if (ops[0].reg == 15)
- tcc_error(S, "'%s' does not support 'pc' as operand", get_tok_str(S, token, NULL));
+ tcc_error("'%s' does not support 'pc' as operand", get_tok_str(token, NULL));
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)
- tcc_error(S, "first operand of '%s' should have an exclamation mark", get_tok_str(S, token, NULL));
+ tcc_error("first operand of '%s' should have an exclamation mark", get_tok_str(token, NULL));
else
- 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);
+ 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);
}
#define VMOV_FRACTIONAL_DIGITS 7
#define VMOV_ONE 10000000 /* pow(10, VMOV_FRACTIONAL_DIGITS) */
-static uint32_t vmov_parse_fractional_part(TCCState* S, const char* s)
+static uint32_t vmov_parse_fractional_part(const char* s)
{
uint32_t result = 0;
int i;
@@ -1701,7 +1701,7 @@ static uint32_t vmov_parse_fractional_part(TCCState* S, const char* s)
}
}
if (*s)
- expect(S, "decimal numeral");
+ expect("decimal numeral");
return result;
}
@@ -1720,34 +1720,34 @@ static int vmov_linear_approx_index(uint32_t beginning, uint32_t end, uint32_t v
return -1;
}
-static uint32_t vmov_parse_immediate_value(TCCState* S) {
+static uint32_t vmov_parse_immediate_value() {
uint32_t value;
unsigned long integral_value;
const char *p;
- if (S->tccpp_tok != TOK_PPNUM) {
- expect(S, "immediate value");
+ if (tok != TOK_PPNUM) {
+ expect("immediate value");
return 0;
}
- p = S->tccpp_tokc.str.data;
+ p = tokc.str.data;
errno = 0;
integral_value = strtoul(p, (char **)&p, 0);
if (errno || integral_value >= 32) {
- tcc_error(S, "invalid floating-point immediate value");
+ tcc_error("invalid floating-point immediate value");
return 0;
}
value = (uint32_t) integral_value * VMOV_ONE;
if (*p == '.') {
++p;
- value += vmov_parse_fractional_part(S, p);
+ value += vmov_parse_fractional_part(p);
}
- next(S);
+ next();
return value;
}
-static uint8_t vmov_encode_immediate_value(TCCState* S, uint32_t value)
+static uint8_t vmov_encode_immediate_value(uint32_t value)
{
uint32_t limit;
uint32_t end = 0;
@@ -1767,7 +1767,7 @@ static uint8_t vmov_encode_immediate_value(TCCState* S, uint32_t value)
limit >>= 1;
}
if (r == -1 || value < beginning || value > end) {
- tcc_error(S, "invalid decimal number for vmov: %d", value);
+ tcc_error("invalid decimal number for vmov: %d", value);
return 0;
}
n = vmov_linear_approx_index(beginning, end, value);
@@ -1775,7 +1775,7 @@ static uint8_t vmov_encode_immediate_value(TCCState* S, uint32_t value)
}
// Not standalone.
-static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *S, int token, uint8_t coprocessor, uint8_t CRd) {
+static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *s1, int token, uint8_t coprocessor, uint8_t CRd) {
uint8_t opcode1 = 0;
uint8_t opcode2 = 0;
uint8_t operands[3] = {0, 0, 0};
@@ -1785,14 +1785,14 @@ static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *S
operands[0] = CRd;
- if (S->tccpp_tok == '#' || S->tccpp_tok == '$') {
- next(S);
+ if (tok == '#' || tok == '$') {
+ next();
}
- if (S->tccpp_tok == '-') {
+ if (tok == '-') {
op_minus = 1;
- next(S);
+ next();
}
- immediate_value = vmov_parse_immediate_value(S);
+ immediate_value = vmov_parse_immediate_value();
opcode1 = 11; // "Other" instruction
switch (ARM_INSTRUCTION_GROUP(token)) {
@@ -1801,7 +1801,7 @@ static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *S
opcode2 = 2;
operands[1] = 5;
if (immediate_value) {
- expect(S, "Immediate value 0");
+ expect("Immediate value 0");
return;
}
break;
@@ -1810,7 +1810,7 @@ static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *S
opcode2 = 6;
operands[1] = 5;
if (immediate_value) {
- expect(S, "Immediate value 0");
+ expect("Immediate value 0");
return;
}
break;
@@ -1821,12 +1821,12 @@ static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *S
operands[1] = 0x8;
else
operands[1] = 0x0;
- code = vmov_encode_immediate_value(S, immediate_value);
+ code = vmov_encode_immediate_value(immediate_value);
operands[1] |= code >> 4;
operands[2] = code & 0xF;
break;
default:
- expect(S, "known floating point with immediate instruction");
+ expect("known floating point with immediate instruction");
return;
}
@@ -1836,17 +1836,17 @@ static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *S
operands[0] >>= 1;
}
- asm_emit_coprocessor_opcode(S, condition_code_of_token(S, token), coprocessor, opcode1, operands[0], operands[1], operands[2], opcode2, 0);
+ asm_emit_coprocessor_opcode(condition_code_of_token(token), coprocessor, opcode1, operands[0], operands[1], operands[2], opcode2, 0);
}
-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]) {
+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]) {
uint8_t opcode1 = 0;
uint8_t opcode2 = 0;
switch (coprocessor) {
case CP_SINGLE_PRECISION_FLOAT:
// "vmov.f32 r2, s3" or "vmov.f32 s3, r2"
if (nb_ops != 2 || nb_arm_regs != 1) {
- tcc_error(S, "vmov.f32 only implemented for one VFP register operand and one ARM register operands");
+ tcc_error("vmov.f32 only implemented for one VFP register operand and one ARM register operands");
return;
}
if (ops[0].type != OP_REG32) { // determine mode: load or store
@@ -1869,11 +1869,11 @@ static void asm_floating_point_reg_arm_reg_transfer_opcode_tail(TCCState *S, int
ops[0].reg >>= 1;
}
- 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);
+ 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);
break;
case CP_DOUBLE_PRECISION_FLOAT:
if (nb_ops != 3 || nb_arm_regs != 2) {
- tcc_error(S, "vmov.f32 only implemented for one VFP register operand and two ARM register operands");
+ tcc_error("vmov.f32 only implemented for one VFP register operand and two ARM register operands");
return;
}
// Determine whether it's a store into a VFP register (vmov "d1, r2, r3") rather than "vmov r2, r3, d1"
@@ -1886,23 +1886,23 @@ static void asm_floating_point_reg_arm_reg_transfer_opcode_tail(TCCState *S, int
memcpy(&ops[1], &ops[2], sizeof(ops[1]));
memcpy(&ops[2], &temp, sizeof(ops[2]));
} else {
- tcc_error(S, "vmov.f64 only implemented for one VFP register operand and two ARM register operands");
+ tcc_error("vmov.f64 only implemented for one VFP register operand and two ARM register operands");
return;
}
} else if (ops[0].type != OP_REG32 || ops[1].type != OP_REG32 || ops[2].type != OP_VREG64) {
- tcc_error(S, "vmov.f64 only implemented for one VFP register operand and two ARM register operands");
+ tcc_error("vmov.f64 only implemented for one VFP register operand and two ARM register operands");
return;
} else {
opcode1 |= 1;
}
- 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);
+ asm_emit_coprocessor_data_transfer(condition_code_of_token(token), coprocessor, ops[0].reg, &ops[1], &ops[2], 0, 0, 0, 1, opcode1);
break;
default:
- tcc_internal_error(S, "unknown coprocessor");
+ tcc_internal_error("unknown coprocessor");
}
}
-static void asm_floating_point_vcvt_data_processing_opcode(TCCState *S, int token) {
+static void asm_floating_point_vcvt_data_processing_opcode(TCCState *s1, int token) {
uint8_t coprocessor = 0;
Operand ops[3];
uint8_t opcode1 = 11;
@@ -1928,11 +1928,11 @@ static void asm_floating_point_vcvt_data_processing_opcode(TCCState *S, int toke
coprocessor = CP_SINGLE_PRECISION_FLOAT;
break;
default:
- tcc_error(S, "Unknown coprocessor for instruction '%s'", get_tok_str(S, token, NULL));
+ tcc_error("Unknown coprocessor for instruction '%s'", get_tok_str(token, NULL));
return;
}
- parse_operand(S, &ops[0]);
+ parse_operand(s1, &ops[0]);
ops[1].type = OP_IM8;
ops[1].e.v = 8;
/* floating-point -> integer */
@@ -1956,11 +1956,11 @@ static void asm_floating_point_vcvt_data_processing_opcode(TCCState *S, int toke
break;
}
- if (S->tccpp_tok == ',')
- next(S);
+ if (tok == ',')
+ next();
else
- expect(S, "','");
- parse_operand(S, &ops[2]);
+ expect("','");
+ parse_operand(s1, &ops[2]);
switch (ARM_INSTRUCTION_GROUP(token)) {
/* floating-point -> integer */
@@ -1990,7 +1990,7 @@ static void asm_floating_point_vcvt_data_processing_opcode(TCCState *S, int toke
case TOK_ASM_vcvteq_f64_f32:
if (ops[0].type == OP_VREG64 && ops[2].type == OP_VREG32) {
} else {
- expect(S, "d<number>, s<number>");
+ expect("d<number>, s<number>");
return;
}
break;
@@ -1998,13 +1998,13 @@ static void asm_floating_point_vcvt_data_processing_opcode(TCCState *S, int toke
if (coprocessor == CP_SINGLE_PRECISION_FLOAT) {
if (ops[0].type == OP_VREG32 && ops[2].type == OP_VREG32) {
} else {
- expect(S, "s<number>, s<number>");
+ expect("s<number>, s<number>");
return;
}
} else if (coprocessor == CP_DOUBLE_PRECISION_FLOAT) {
if (ops[0].type == OP_VREG32 && ops[2].type == OP_VREG64) {
} else {
- expect(S, "s<number>, d<number>");
+ expect("s<number>, d<number>");
return;
}
}
@@ -2020,10 +2020,10 @@ static void asm_floating_point_vcvt_data_processing_opcode(TCCState *S, int toke
opcode1 |= 4;
ops[0].reg >>= 1;
}
- 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);
+ 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);
}
-static void asm_floating_point_data_processing_opcode(TCCState *S, int token) {
+static void asm_floating_point_data_processing_opcode(TCCState *s1, int token) {
uint8_t coprocessor = CP_SINGLE_PRECISION_FLOAT;
uint8_t opcode1 = 0;
uint8_t opcode2 = 0; // (0 || 2) | register selection
@@ -2078,30 +2078,30 @@ static void asm_floating_point_data_processing_opcode(TCCState *S, int token) {
for (nb_ops = 0; nb_ops < 3; ) {
// Note: Necessary because parse_operand can't parse decimal numerals.
- if (nb_ops == 1 && (S->tccpp_tok == '#' || S->tccpp_tok == '$' || S->tccpp_tok == TOK_PPNUM || S->tccpp_tok == '-')) {
- asm_floating_point_immediate_data_processing_opcode_tail(S, token, coprocessor, ops[0].reg);
+ if (nb_ops == 1 && (tok == '#' || tok == '$' || tok == TOK_PPNUM || tok == '-')) {
+ asm_floating_point_immediate_data_processing_opcode_tail(s1, token, coprocessor, ops[0].reg);
return;
}
- parse_operand(S, &ops[nb_ops]);
+ parse_operand(s1, &ops[nb_ops]);
if (vmov && ops[nb_ops].type == OP_REG32) {
++nb_arm_regs;
} else if (ops[nb_ops].type == OP_VREG32) {
if (coprocessor != CP_SINGLE_PRECISION_FLOAT) {
- expect(S, "'s<number>'");
+ expect("'s<number>'");
return;
}
} else if (ops[nb_ops].type == OP_VREG64) {
if (coprocessor != CP_DOUBLE_PRECISION_FLOAT) {
- expect(S, "'d<number>'");
+ expect("'d<number>'");
return;
}
} else {
- expect(S, "floating point register");
+ expect("floating point register");
return;
}
++nb_ops;
- if (S->tccpp_tok == ',')
- next(S);
+ if (tok == ',')
+ next();
else
break;
}
@@ -2113,7 +2113,7 @@ static void asm_floating_point_data_processing_opcode(TCCState *S, int token) {
nb_ops = 3;
}
if (nb_ops < 3) {
- tcc_error(S, "Not enough operands for '%s' (%u)", get_tok_str(S, token, NULL), nb_ops);
+ tcc_error("Not enough operands for '%s' (%u)", get_tok_str(token, NULL), nb_ops);
return;
}
}
@@ -2202,7 +2202,7 @@ static void asm_floating_point_data_processing_opcode(TCCState *S, int token) {
case TOK_ASM_vmoveq_f32:
case TOK_ASM_vmoveq_f64:
if (nb_arm_regs > 0) { // vmov.f32 r2, s3 or similar
- asm_floating_point_reg_arm_reg_transfer_opcode_tail(S, token, coprocessor, nb_arm_regs, nb_ops, ops);
+ asm_floating_point_reg_arm_reg_transfer_opcode_tail(s1, token, coprocessor, nb_arm_regs, nb_ops, ops);
return;
} else {
opcode1 = 11; // "Other" instruction
@@ -2212,7 +2212,7 @@ static void asm_floating_point_data_processing_opcode(TCCState *S, int token) {
}
break;
default:
- expect(S, "known floating point instruction");
+ expect("known floating point instruction");
return;
}
@@ -2236,10 +2236,10 @@ static void asm_floating_point_data_processing_opcode(TCCState *S, int token) {
}
}
- 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);
+ 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);
}
-static void asm_floating_point_status_register_opcode(TCCState* S, int token)
+static void asm_floating_point_status_register_opcode(TCCState* s1, int token)
{
uint8_t coprocessor = CP_SINGLE_PRECISION_FLOAT;
uint8_t opcode;
@@ -2248,61 +2248,61 @@ static void asm_floating_point_status_register_opcode(TCCState* S, int token)
switch (ARM_INSTRUCTION_GROUP(token)) {
case TOK_ASM_vmrseq:
opcode = 0xf;
- if (S->tccpp_tok == TOK_ASM_apsr_nzcv) {
+ if (tok == TOK_ASM_apsr_nzcv) {
arm_operand.type = OP_REG32;
arm_operand.reg = 15; // not PC
- next(S); // skip apsr_nzcv
+ next(); // skip apsr_nzcv
} else {
- parse_operand(S, &arm_operand);
+ parse_operand(s1, &arm_operand);
if (arm_operand.type == OP_REG32 && arm_operand.reg == 15) {
- tcc_error(S, "'%s' does not support 'pc' as operand", get_tok_str(S, token, NULL));
+ tcc_error("'%s' does not support 'pc' as operand", get_tok_str(token, NULL));
return;
}
}
- if (S->tccpp_tok != ',')
- expect(S, "','");
+ if (tok != ',')
+ expect("','");
else
- next(S); // skip ','
- vfp_sys_reg = asm_parse_vfp_status_regvar(S->tccpp_tok);
- next(S); // skip vfp sys reg
+ next(); // skip ','
+ vfp_sys_reg = asm_parse_vfp_status_regvar(tok);
+ next(); // skip vfp sys reg
if (arm_operand.type == OP_REG32 && arm_operand.reg == 15 && vfp_sys_reg != 1) {
- tcc_error(S, "'%s' only supports the variant 'vmrs apsr_nzcv, fpscr' here", get_tok_str(S, token, NULL));
+ tcc_error("'%s' only supports the variant 'vmrs apsr_nzcv, fpscr' here", get_tok_str(token, NULL));
return;
}
break;
case TOK_ASM_vmsreq:
opcode = 0xe;
- vfp_sys_reg = asm_parse_vfp_status_regvar(S->tccpp_tok);
- next(S); // skip vfp sys reg
- if (S->tccpp_tok != ',')
- expect(S, "','");
+ vfp_sys_reg = asm_parse_vfp_status_regvar(tok);
+ next(); // skip vfp sys reg
+ if (tok != ',')
+ expect("','");
else
- next(S); // skip ','
- parse_operand(S, &arm_operand);
+ next(); // skip ','
+ parse_operand(s1, &arm_operand);
if (arm_operand.type == OP_REG32 && arm_operand.reg == 15) {
- tcc_error(S, "'%s' does not support 'pc' as operand", get_tok_str(S, token, NULL));
+ tcc_error("'%s' does not support 'pc' as operand", get_tok_str(token, NULL));
return;
}
break;
default:
- expect(S, "floating point status register instruction");
+ expect("floating point status register instruction");
return;
}
if (vfp_sys_reg == -1) {
- expect(S, "VFP system register");
+ expect("VFP system register");
return;
}
if (arm_operand.type != OP_REG32) {
- expect(S, "ARM register");
+ expect("ARM register");
return;
}
- asm_emit_coprocessor_opcode(S, condition_code_of_token(S, token), coprocessor, opcode, arm_operand.reg, vfp_sys_reg, 0x10, 0, 0);
+ asm_emit_coprocessor_opcode(condition_code_of_token(token), coprocessor, opcode, arm_operand.reg, vfp_sys_reg, 0x10, 0, 0);
}
#endif
-static void asm_misc_single_data_transfer_opcode(TCCState *S, int token)
+static void asm_misc_single_data_transfer_opcode(TCCState *s1, int token)
{
Operand ops[3];
int exclam = 0;
@@ -2322,42 +2322,42 @@ static void asm_misc_single_data_transfer_opcode(TCCState *S, int token)
// Here: 0 0 0 P U I W L << 20
// [compare single data transfer: 0 1 I P U B W L << 20]
- parse_operand(S, &ops[0]);
+ parse_operand(s1, &ops[0]);
if (ops[0].type == OP_REG32)
opcode |= ENCODE_RD(ops[0].reg);
else {
- expect(S, "(destination operand) register");
+ expect("(destination operand) register");
return;
}
- if (S->tccpp_tok != ',')
- expect(S, "at least two arguments");
+ if (tok != ',')
+ expect("at least two arguments");
else
- next(S); // skip ','
+ next(); // skip ','
- if (S->tccpp_tok != '[')
- expect(S, "'['");
+ if (tok != '[')
+ expect("'['");
else
- next(S); // skip '['
+ next(); // skip '['
- parse_operand(S, &ops[1]);
+ parse_operand(s1, &ops[1]);
if (ops[1].type == OP_REG32)
opcode |= ENCODE_RN(ops[1].reg);
else {
- expect(S, "(first source operand) register");
+ expect("(first source operand) register");
return;
}
- if (S->tccpp_tok == ']') {
- next(S);
+ if (tok == ']') {
+ next();
closed_bracket = 1;
// exclam = 1; // implicit in hardware; don't do it in software
}
- if (S->tccpp_tok == ',') {
- next(S); // skip ','
- if (S->tccpp_tok == '-') {
+ if (tok == ',') {
+ next(); // skip ','
+ if (tok == '-') {
op2_minus = 1;
- next(S);
+ next();
}
- parse_operand(S, &ops[2]);
+ parse_operand(s1, &ops[2]);
} else {
// end of input expression in brackets--assume 0 offset
ops[2].type = OP_IM8;
@@ -2365,20 +2365,20 @@ static void asm_misc_single_data_transfer_opcode(TCCState *S, int token)
opcode |= 1 << 24; // add offset before transfer
}
if (!closed_bracket) {
- if (S->tccpp_tok != ']')
- expect(S, "']'");
+ if (tok != ']')
+ expect("']'");
else
- next(S); // skip ']'
+ next(); // skip ']'
opcode |= 1 << 24; // add offset before transfer
- if (S->tccpp_tok == '!') {
+ if (tok == '!') {
exclam = 1;
- next(S); // skip '!'
+ next(); // skip '!'
}
}
if (exclam) {
if ((opcode & (1 << 24)) == 0) {
- tcc_error(S, "result of '%s' would be unpredictable here", get_tok_str(S, token, NULL));
+ tcc_error("result of '%s' would be unpredictable here", get_tok_str(token, NULL));
return;
}
opcode |= 1 << 21; // write offset back into register
@@ -2387,11 +2387,11 @@ static void asm_misc_single_data_transfer_opcode(TCCState *S, int token)
if (ops[2].type == OP_IM32 || ops[2].type == OP_IM8 || ops[2].type == OP_IM8N) {
int v = ops[2].e.v;
if (op2_minus)
- tcc_error(S, "minus before '#' not supported for immediate values");
+ tcc_error("minus before '#' not supported for immediate values");
if (v >= 0) {
opcode |= 1 << 23; // up
if (v >= 0x100)
- tcc_error(S, "offset out of range for '%s'", get_tok_str(S, token, NULL));
+ tcc_error("offset out of range for '%s'", get_tok_str(token, NULL));
else {
// bits 11...8: immediate hi nibble
// bits 3...0: immediate lo nibble
@@ -2400,7 +2400,7 @@ static void asm_misc_single_data_transfer_opcode(TCCState *S, int token)
}
} else { // down
if (v <= -0x100)
- tcc_error(S, "offset out of range for '%s'", get_tok_str(S, token, NULL));
+ tcc_error("offset out of range for '%s'", get_tok_str(token, NULL));
else {
v = -v;
// bits 11...8: immediate hi nibble
@@ -2415,7 +2415,7 @@ static void asm_misc_single_data_transfer_opcode(TCCState *S, int token)
opcode |= 1 << 23; // up
opcode |= ops[2].reg;
} else
- expect(S, "register");
+ expect("register");
switch (ARM_INSTRUCTION_GROUP(token)) {
case TOK_ASM_ldrsheq:
@@ -2424,34 +2424,34 @@ static void asm_misc_single_data_transfer_opcode(TCCState *S, int token)
case TOK_ASM_ldrsbeq:
opcode |= 1 << 6; // sign extend
opcode |= 1 << 20; // L
- asm_emit_opcode(S, token, opcode);
+ asm_emit_opcode(token, opcode);
break;
case TOK_ASM_ldrheq:
opcode |= 1 << 5; // halfword, not byte
opcode |= 1 << 20; // L
- asm_emit_opcode(S, token, opcode);
+ asm_emit_opcode(token, opcode);
break;
case TOK_ASM_strheq:
opcode |= 1 << 5; // halfword, not byte
- asm_emit_opcode(S, token, opcode);
+ asm_emit_opcode(token, opcode);
break;
}
}
/* Note: almost dupe of encbranch in arm-gen.c */
-static uint32_t encbranchoffset(TCCState* S, int pos, int addr, int fail)
+static uint32_t encbranchoffset(int pos, int addr, int fail)
{
addr-=pos+8;
addr/=4;
if(addr>=0x7fffff || addr<-0x800000) {
if(fail)
- tcc_error(S, "branch offset is too far");
+ tcc_error("branch offset is too far");
return 0;
}
return /*not 0x0A000000|*/(addr&0xffffff);
}
-static void asm_branch_opcode(TCCState *S, int token)
+static void asm_branch_opcode(TCCState *s1, int token)
{
int jmp_disp = 0;
Operand op;
@@ -2461,63 +2461,63 @@ static void asm_branch_opcode(TCCState *S, int token)
switch (ARM_INSTRUCTION_GROUP(token)) {
case TOK_ASM_beq:
case TOK_ASM_bleq:
- asm_expr(S, &e);
- esym = elfsym(S, e.sym);
+ asm_expr(s1, &e);
+ esym = elfsym(e.sym);
if (!esym || esym->st_shndx != cur_text_section->sh_num) {
- tcc_error(S, "invalid branch target");
+ tcc_error("invalid branch target");
return;
}
- jmp_disp = encbranchoffset(S, S->tccgen_ind, e.v + esym->st_value, 1);
+ jmp_disp = encbranchoffset(ind, e.v + esym->st_value, 1);
break;
default:
- parse_operand(S, &op);
+ parse_operand(s1, &op);
break;
}
switch (ARM_INSTRUCTION_GROUP(token)) {
case TOK_ASM_beq:
- asm_emit_opcode(S, token, (0xa << 24) | (jmp_disp & 0xffffff));
+ asm_emit_opcode(token, (0xa << 24) | (jmp_disp & 0xffffff));
break;
case TOK_ASM_bleq:
- asm_emit_opcode(S, token, (0xb << 24) | (jmp_disp & 0xffffff));
+ asm_emit_opcode(token, (0xb << 24) | (jmp_disp & 0xffffff));
break;
case TOK_ASM_bxeq:
if (op.type != OP_REG32)
- expect(S, "register");
+ expect("register");
else
- asm_emit_opcode(S, token, (0x12fff1 << 4) | op.reg);
+ asm_emit_opcode(token, (0x12fff1 << 4) | op.reg);
break;
case TOK_ASM_blxeq:
if (op.type != OP_REG32)
- expect(S, "register");
+ expect("register");
else
- asm_emit_opcode(S, token, (0x12fff3 << 4) | op.reg);
+ asm_emit_opcode(token, (0x12fff3 << 4) | op.reg);
break;
default:
- expect(S, "branch instruction");
+ expect("branch instruction");
}
}
-ST_FUNC void asm_opcode(TCCState *S, int token)
+ST_FUNC void asm_opcode(TCCState *s1, int token)
{
while (token == TOK_LINEFEED) {
- next(S);
- token = S->tccpp_tok;
+ next();
+ token = tok;
}
if (token == TOK_EOF)
return;
if (token < TOK_ASM_nopeq) { // no condition code
switch (token) {
case TOK_ASM_cdp2:
- asm_coprocessor_opcode(S, token);
+ asm_coprocessor_opcode(s1, token);
return;
case TOK_ASM_ldc2:
case TOK_ASM_ldc2l:
case TOK_ASM_stc2:
case TOK_ASM_stc2l:
- asm_coprocessor_data_transfer_opcode(S, token);
+ asm_coprocessor_data_transfer_opcode(s1, token);
return;
default:
- expect(S, "instruction");
+ expect("instruction");
return;
}
}
@@ -2535,22 +2535,22 @@ ST_FUNC void asm_opcode(TCCState *S, int token)
case TOK_ASM_ldmdbeq:
case TOK_ASM_stmibeq:
case TOK_ASM_ldmibeq:
- asm_block_data_transfer_opcode(S, token);
+ asm_block_data_transfer_opcode(s1, token);
return;
case TOK_ASM_nopeq:
case TOK_ASM_wfeeq:
case TOK_ASM_wfieq:
- asm_nullary_opcode(S, token);
+ asm_nullary_opcode(token);
return;
case TOK_ASM_swieq:
case TOK_ASM_svceq:
- asm_unary_opcode(S, token);
+ asm_unary_opcode(s1, token);
return;
case TOK_ASM_beq:
case TOK_ASM_bleq:
case TOK_ASM_bxeq:
case TOK_ASM_blxeq:
- asm_branch_opcode(S, token);
+ asm_branch_opcode(s1, token);
return;
case TOK_ASM_clzeq:
case TOK_ASM_sxtbeq:
@@ -2559,7 +2559,7 @@ ST_FUNC void asm_opcode(TCCState *S, int token)
case TOK_ASM_uxtheq:
case TOK_ASM_movteq:
case TOK_ASM_movweq:
- asm_binary_opcode(S, token);
+ asm_binary_opcode(s1, token);
return;
case TOK_ASM_ldreq:
@@ -2570,14 +2570,14 @@ ST_FUNC void asm_opcode(TCCState *S, int token)
case TOK_ASM_ldrexbeq:
case TOK_ASM_strexeq:
case TOK_ASM_strexbeq:
- asm_single_data_transfer_opcode(S, token);
+ asm_single_data_transfer_opcode(s1, token);
return;
case TOK_ASM_ldrheq:
case TOK_ASM_ldrsheq:
case TOK_ASM_ldrsbeq:
case TOK_ASM_strheq:
- asm_misc_single_data_transfer_opcode(S, token);
+ asm_misc_single_data_transfer_opcode(s1, token);
return;
case TOK_ASM_andeq:
@@ -2612,7 +2612,7 @@ ST_FUNC void asm_opcode(TCCState *S, int token)
case TOK_ASM_movseq:
case TOK_ASM_bicseq:
case TOK_ASM_mvnseq:
- asm_data_processing_opcode(S, token);
+ asm_data_processing_opcode(s1, token);
return;
case TOK_ASM_lsleq:
@@ -2625,14 +2625,14 @@ ST_FUNC void asm_opcode(TCCState *S, int token)
case TOK_ASM_rorseq:
case TOK_ASM_rrxseq:
case TOK_ASM_rrxeq:
- asm_shift_opcode(S, token);
+ asm_shift_opcode(s1, token);
return;
case TOK_ASM_muleq:
case TOK_ASM_mulseq:
case TOK_ASM_mlaeq:
case TOK_ASM_mlaseq:
- asm_multiplication_opcode(S, token);
+ asm_multiplication_opcode(s1, token);
return;
case TOK_ASM_smulleq:
@@ -2643,26 +2643,26 @@ ST_FUNC void asm_opcode(TCCState *S, int token)
case TOK_ASM_smlalseq:
case TOK_ASM_umlaleq:
case TOK_ASM_umlalseq:
- asm_long_multiplication_opcode(S, token);
+ asm_long_multiplication_opcode(s1, token);
return;
case TOK_ASM_cdpeq:
case TOK_ASM_mcreq:
case TOK_ASM_mrceq:
- asm_coprocessor_opcode(S, token);
+ asm_coprocessor_opcode(s1, token);
return;
case TOK_ASM_ldceq:
case TOK_ASM_ldcleq:
case TOK_ASM_stceq:
case TOK_ASM_stcleq:
- asm_coprocessor_data_transfer_opcode(S, token);
+ asm_coprocessor_data_transfer_opcode(s1, token);
return;
#if defined(TCC_ARM_VFP)
case TOK_ASM_vldreq:
case TOK_ASM_vstreq:
- asm_floating_point_single_data_transfer_opcode(S, token);
+ asm_floating_point_single_data_transfer_opcode(s1, token);
return;
case TOK_ASM_vmlaeq_f32:
@@ -2695,7 +2695,7 @@ ST_FUNC void asm_opcode(TCCState *S, int token)
case TOK_ASM_vcmpeq_f64:
case TOK_ASM_vcmpeeq_f64:
case TOK_ASM_vmoveq_f64:
- asm_floating_point_data_processing_opcode(S, token);
+ asm_floating_point_data_processing_opcode(s1, token);
return;
case TOK_ASM_vcvtreq_s32_f32:
@@ -2712,7 +2712,7 @@ ST_FUNC void asm_opcode(TCCState *S, int token)
case TOK_ASM_vcvteq_f32_u32:
case TOK_ASM_vcvteq_f64_f32:
case TOK_ASM_vcvteq_f32_f64:
- asm_floating_point_vcvt_data_processing_opcode(S, token);
+ asm_floating_point_vcvt_data_processing_opcode(s1, token);
return;
case TOK_ASM_vpusheq:
@@ -2723,21 +2723,21 @@ ST_FUNC void asm_opcode(TCCState *S, int token)
case TOK_ASM_vstmeq:
case TOK_ASM_vstmiaeq:
case TOK_ASM_vstmdbeq:
- asm_floating_point_block_data_transfer_opcode(S, token);
+ asm_floating_point_block_data_transfer_opcode(s1, token);
return;
case TOK_ASM_vmsreq:
case TOK_ASM_vmrseq:
- asm_floating_point_status_register_opcode(S, token);
+ asm_floating_point_status_register_opcode(s1, token);
return;
#endif
default:
- expect(S, "known instruction");
+ expect("known instruction");
}
}
-ST_FUNC void subst_asm_operand(TCCState* S, CString *add_str, SValue *sv, int modifier)
+ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier)
{
int r, reg, size, val;
char buf[64];
@@ -2746,45 +2746,45 @@ ST_FUNC void subst_asm_operand(TCCState* S, CString *add_str, SValue *sv, int mo
if ((r & VT_VALMASK) == VT_CONST) {
if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n' &&
modifier != 'P')
- cstr_ccat(S, add_str, '#');
+ cstr_ccat(add_str, '#');
if (r & VT_SYM) {
- const char *name = get_tok_str(S, sv->sym->v, NULL);
+ const char *name = get_tok_str(sv->sym->v, NULL);
if (sv->sym->v >= SYM_FIRST_ANOM) {
/* In case of anonymous symbols ("L.42", used
for static data labels) we can't find them
in the C symbol table when later looking up
this name. So enter them now into the asm label
list when we still know the symbol. */
- get_asm_sym(S, tok_alloc(S, name, strlen(name))->tok, sv->sym);
+ get_asm_sym(tok_alloc(name, strlen(name))->tok, sv->sym);
}
- if (S->leading_underscore)
- cstr_ccat(S, add_str, '_');
- cstr_cat(S, add_str, name, -1);
+ if (tcc_state->leading_underscore)
+ cstr_ccat(add_str, '_');
+ cstr_cat(add_str, name, -1);
if ((uint32_t) sv->c.i == 0)
goto no_offset;
- cstr_ccat(S, add_str, '+');
+ cstr_ccat(add_str, '+');
}
val = sv->c.i;
if (modifier == 'n')
val = -val;
snprintf(buf, sizeof(buf), "%d", (int) sv->c.i);
- cstr_cat(S, add_str, buf, -1);
+ cstr_cat(add_str, buf, -1);
no_offset:;
} else if ((r & VT_VALMASK) == VT_LOCAL) {
snprintf(buf, sizeof(buf), "[fp,#%d]", (int) sv->c.i);
- cstr_cat(S, add_str, buf, -1);
+ cstr_cat(add_str, buf, -1);
} else if (r & VT_LVAL) {
reg = r & VT_VALMASK;
if (reg >= VT_CONST)
- tcc_internal_error(S, "");
+ tcc_internal_error("");
snprintf(buf, sizeof(buf), "[%s]",
- get_tok_str(S, TOK_ASM_r0 + reg, NULL));
- cstr_cat(S, add_str, buf, -1);
+ get_tok_str(TOK_ASM_r0 + reg, NULL));
+ cstr_cat(add_str, buf, -1);
} else {
/* register case */
reg = r & VT_VALMASK;
if (reg >= VT_CONST)
- tcc_internal_error(S, "");
+ tcc_internal_error("");
/* choose register operand size */
if ((sv->type.t & VT_BTYPE) == VT_BYTE ||
@@ -2808,13 +2808,13 @@ ST_FUNC void subst_asm_operand(TCCState* S, CString *add_str, SValue *sv, int mo
reg = TOK_ASM_r0 + reg;
break;
}
- snprintf(buf, sizeof(buf), "%s", get_tok_str(S, reg, NULL));
- cstr_cat(S, add_str, buf, -1);
+ snprintf(buf, sizeof(buf), "%s", get_tok_str(reg, NULL));
+ cstr_cat(add_str, buf, -1);
}
}
/* generate prolog and epilog code for asm statement */
-ST_FUNC void asm_gen_code(TCCState* S, ASMOperand *operands, int nb_operands,
+ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,
int nb_outputs, int is_output,
uint8_t *clobber_regs,
int out_reg)
@@ -2844,7 +2844,7 @@ ST_FUNC void asm_gen_code(TCCState* S, ASMOperand *operands, int nb_operands,
if (!is_output) { // prolog
/* generate reg save code */
if (saved_regset)
- gen_le32(S, 0xe92d0000 | saved_regset); // push {...}
+ gen_le32(0xe92d0000 | saved_regset); // push {...}
/* generate load code */
for(i = 0; i < nb_operands; i++) {
@@ -2858,12 +2858,12 @@ ST_FUNC void asm_gen_code(TCCState* S, ASMOperand *operands, int nb_operands,
sv = *op->vt;
sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL | VT_LVAL;
sv.type.t = VT_PTR;
- load(S, op->reg, &sv);
+ load(op->reg, &sv);
} else if (i >= nb_outputs || op->is_rw) { // not write-only
/* load value in register */
- load(S, op->reg, op->vt);
+ load(op->reg, op->vt);
if (op->is_llong)
- tcc_error(S, "long long not implemented");
+ tcc_error("long long not implemented");
}
}
}
@@ -2878,29 +2878,29 @@ ST_FUNC void asm_gen_code(TCCState* S, ASMOperand *operands, int nb_operands,
sv = *op->vt;
sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL;
sv.type.t = VT_PTR;
- load(S, out_reg, &sv);
+ load(out_reg, &sv);
sv = *op->vt;
sv.r = (sv.r & ~VT_VALMASK) | out_reg;
- store(S, op->reg, &sv);
+ store(op->reg, &sv);
}
} else {
- store(S, op->reg, op->vt);
+ store(op->reg, op->vt);
if (op->is_llong)
- tcc_error(S, "long long not implemented");
+ tcc_error("long long not implemented");
}
}
}
/* generate reg restore code */
if (saved_regset)
- gen_le32(S, 0xe8bd0000 | saved_regset); // pop {...}
+ gen_le32(0xe8bd0000 | saved_regset); // pop {...}
}
}
/* return the constraint priority (we allocate first the lowest
numbered constraints) */
-static inline int constraint_priority(TCCState* S, const char *str)
+static inline int constraint_priority(const char *str)
{
int priority, c, pr;
@@ -2927,7 +2927,7 @@ static inline int constraint_priority(TCCState* S, const char *str)
pr = 4;
break;
default:
- tcc_error(S, "unknown constraint '%c'", c);
+ tcc_error("unknown constraint '%c'", c);
pr = 0;
}
if (pr > priority)
@@ -2956,7 +2956,7 @@ static const char *skip_constraint_modifiers(const char *p)
#define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask)
-ST_FUNC void asm_compute_constraints(TCCState* S, ASMOperand *operands,
+ST_FUNC void asm_compute_constraints(ASMOperand *operands,
int nb_operands, int nb_outputs,
const uint8_t *clobber_regs,
int *pout_reg)
@@ -3009,13 +3009,13 @@ ST_FUNC void asm_compute_constraints(TCCState* S, ASMOperand *operands,
str = skip_constraint_modifiers(str);
if (isnum(*str) || *str == '[') {
/* this is a reference to another constraint */
- k = find_constraint(S, operands, nb_operands, str, NULL);
+ k = find_constraint(operands, nb_operands, str, NULL);
if ((unsigned) k >= i || i < nb_outputs)
- tcc_error(S, "invalid reference in constraint %d ('%s')",
+ tcc_error("invalid reference in constraint %d ('%s')",
i, str);
op->ref_index = k;
if (operands[k].input_index >= 0)
- tcc_error(S, "cannot reference twice the same operand");
+ tcc_error("cannot reference twice the same operand");
operands[k].input_index = i;
op->priority = 5;
} else if ((op->vt->r & VT_VALMASK) == VT_LOCAL
@@ -3024,7 +3024,7 @@ ST_FUNC void asm_compute_constraints(TCCState* S, ASMOperand *operands,
op->priority = 1;
op->reg = reg;
} else {
- op->priority = constraint_priority(S, str);
+ op->priority = constraint_priority(str);
}
}
@@ -3073,7 +3073,7 @@ ST_FUNC void asm_compute_constraints(TCCState* S, ASMOperand *operands,
if (op->reg >= 0) {
if (is_reg_allocated(op->reg))
tcc_error
- (S, "asm regvar requests register that's taken already");
+ ("asm regvar requests register that's taken already");
reg = op->reg;
goto reg_found;
}
@@ -3087,7 +3087,7 @@ ST_FUNC void asm_compute_constraints(TCCState* S, ASMOperand *operands,
/* FALL THRU */
case '&': // Operand is clobbered before the instruction is done using the input operands
if (j >= nb_outputs)
- tcc_error(S, "'%c' modifier can only be applied to outputs",
+ tcc_error("'%c' modifier can only be applied to outputs",
c);
reg_mask = REG_IN_MASK | REG_OUT_MASK;
goto try_next;
@@ -3147,7 +3147,7 @@ ST_FUNC void asm_compute_constraints(TCCState* S, ASMOperand *operands,
}
break;
default:
- tcc_error(S, "asm constraint %d ('%s') could not be satisfied",
+ tcc_error("asm constraint %d ('%s') could not be satisfied",
j, op->constraint);
break;
}
@@ -3169,7 +3169,7 @@ ST_FUNC void asm_compute_constraints(TCCState* S, ASMOperand *operands,
if (!(regs_allocated[reg] & REG_OUT_MASK))
goto reg_found2;
}
- tcc_error(S, "could not find free output register for reloading");
+ tcc_error("could not find free output register for reloading");
reg_found2:
*pout_reg = reg;
break;
@@ -3183,7 +3183,7 @@ ST_FUNC void asm_compute_constraints(TCCState* S, ASMOperand *operands,
op = &operands[j];
printf("%%%d [%s]: \"%s\" r=0x%04x reg=%d\n",
j,
- op->id ? get_tok_str(S, op->id, NULL) : "",
+ op->id ? get_tok_str(op->id, NULL) : "",
op->constraint, op->vt->r, op->reg);
}
if (*pout_reg >= 0)
@@ -3191,7 +3191,7 @@ ST_FUNC void asm_compute_constraints(TCCState* S, ASMOperand *operands,
#endif
}
-ST_FUNC void asm_clobber(TCCState* S, uint8_t *clobber_regs, const char *str)
+ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str)
{
int reg;
TokenSym *ts;
@@ -3200,17 +3200,17 @@ ST_FUNC void asm_clobber(TCCState* S, uint8_t *clobber_regs, const char *str)
!strcmp(str, "cc") ||
!strcmp(str, "flags"))
return;
- ts = tok_alloc(S, str, strlen(str));
- reg = asm_parse_regvar(S, ts->tok);
+ ts = tok_alloc(str, strlen(str));
+ reg = asm_parse_regvar(ts->tok);
if (reg == -1) {
- tcc_error(S, "invalid clobber register '%s'", str);
+ tcc_error("invalid clobber register '%s'", str);
}
clobber_regs[reg] = 1;
}
/* If T refers to a register then return the register number and type.
Otherwise return -1. */
-ST_FUNC int asm_parse_regvar (TCCState *S, int t)
+ST_FUNC int asm_parse_regvar (int t)
{
if (t >= TOK_ASM_r0 && t <= TOK_ASM_pc) { /* register name */
switch (t) {