arm-asm: Add vpush, vpop, vldm, vldmia, vldmdb, vstm, vstmia, vstmdb

This commit is contained in:
Danny Milosavljevic 2021-01-21 21:59:47 +01:00
parent e350058532
commit 66de1550ab
No known key found for this signature in database
GPG Key ID: E71A35542C30BAA5
3 changed files with 145 additions and 0 deletions

124
arm-asm.c
View File

@ -1534,6 +1534,119 @@ static void asm_floating_point_single_data_transfer_opcode(TCCState *s1, int tok
expect("floating point data transfer instruction");
}
}
static void asm_floating_point_block_data_transfer_opcode(TCCState *s1, int token)
{
uint8_t coprocessor = 0;
int first_regset_register;
int last_regset_register;
uint8_t regset_item_count;
uint8_t extra_register_bit = 0;
int op0_exclam = 0;
int load = 0;
int preincrement = 0;
Operand ops[1];
Operand offset;
switch (ARM_INSTRUCTION_GROUP(token)) {
case TOK_ASM_vpusheq:
case TOK_ASM_vpopeq:
ops[0].type = OP_REG32;
ops[0].reg = 13; // sp
op0_exclam = 1;
break;
default:
parse_operand(s1, &ops[0]);
if (tok == '!') {
op0_exclam = 1;
next(); // skip '!'
}
if (tok == ',')
next(); // skip comma
else {
expect("','");
return;
}
}
if (tok != '{') {
expect("'{'");
return;
}
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();
} else if ((first_regset_register = asm_parse_vfp_regvar(tok, 0)) != -1) {
coprocessor = CP_SINGLE_PRECISION_FLOAT;
next();
} else {
expect("floating-point register");
return;
}
if (tok == '-') {
next();
if ((last_regset_register = asm_parse_vfp_regvar(tok, coprocessor == CP_DOUBLE_PRECISION_FLOAT)) != -1)
next();
else {
expect("floating-point register");
return;
}
} else
last_regset_register = first_regset_register;
if (last_regset_register < first_regset_register) {
tcc_error("registers will be processed in ascending order by hardware--but are not specified in ascending order here");
return;
}
if (tok != '}') {
expect("'}'");
return;
}
next(); // skip '}'
// Note: 0 (one down) is not implemented by us regardless.
regset_item_count = last_regset_register - first_regset_register + 1;
if (coprocessor == CP_DOUBLE_PRECISION_FLOAT)
regset_item_count <<= 1;
else {
extra_register_bit = first_regset_register & 1;
first_regset_register >>= 1;
}
offset.type = OP_IM8;
offset.e.v = regset_item_count << 2;
switch (ARM_INSTRUCTION_GROUP(token)) {
case TOK_ASM_vstmeq: // post-increment store
case TOK_ASM_vstmiaeq: // post-increment store
break;
case TOK_ASM_vpopeq:
case TOK_ASM_vldmeq: // post-increment load
case TOK_ASM_vldmiaeq: // post-increment load
load = 1;
break;
case TOK_ASM_vldmdbeq: // pre-decrement load
load = 1;
/* fallthrough */
case TOK_ASM_vpusheq:
case TOK_ASM_vstmdbeq: // pre-decrement store
offset.type = OP_IM8N;
offset.e.v = -offset.e.v;
preincrement = 1;
break;
default:
expect("floating point block data transfer instruction");
return;
}
if (ops[0].type != OP_REG32)
expect("(first operand) register");
else if (ops[0].reg == 15)
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("first operand of '%s' should have an exclamation mark", get_tok_str(token, NULL));
else
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);
}
#endif
static void asm_misc_single_data_transfer_opcode(TCCState *s1, int token)
@ -1898,6 +2011,17 @@ ST_FUNC void asm_opcode(TCCState *s1, int token)
case TOK_ASM_vstreq:
asm_floating_point_single_data_transfer_opcode(s1, token);
return;
case TOK_ASM_vpusheq:
case TOK_ASM_vpopeq:
case TOK_ASM_vldmeq:
case TOK_ASM_vldmiaeq:
case TOK_ASM_vldmdbeq:
case TOK_ASM_vstmeq:
case TOK_ASM_vstmiaeq:
case TOK_ASM_vstmdbeq:
asm_floating_point_block_data_transfer_opcode(s1, token);
return;
#endif
default:

View File

@ -285,3 +285,12 @@
DEF_ASM_CONDED(vldr)
DEF_ASM_CONDED(vstr)
DEF_ASM_CONDED(vpush)
DEF_ASM_CONDED(vpop)
DEF_ASM_CONDED(vldm)
DEF_ASM_CONDED(vldmia)
DEF_ASM_CONDED(vldmdb)
DEF_ASM_CONDED(vstm)
DEF_ASM_CONDED(vstmia)
DEF_ASM_CONDED(vstmdb)

View File

@ -120,6 +120,18 @@ do
"s2, [r3, #-4]" \
"s2, [r3, #0x45]" \
"s2, [r3, #-0x45]" \
"r1, {d3-d4}" \
"r1!, {d3-d4}" \
"r2, {d4-d15}" \
"r3!, {d4-d15}" \
"r3!, {d4}" \
"r2, {s4-s31}" \
"r3!, {s4}" \
"{d3-d4}" \
"{d4-d15}" \
"{d4}" \
"{s4-s31}" \
"{s4}" \
""
do
#echo ".syntax unified" > a.s