arm-asm: Add vmsr, vmrs

This commit is contained in:
Danny Milosavljevic 2021-01-26 10:22:10 +01:00
parent 1c9d999114
commit 25628cffe5
No known key found for this signature in database
GPG Key ID: E71A35542C30BAA5
3 changed files with 101 additions and 5 deletions

View File

@ -77,6 +77,20 @@ static int asm_parse_vfp_regvar(int t, int double_precision)
return -1;
}
static int asm_parse_vfp_status_regvar(int t)
{
switch (t) {
case TOK_ASM_fpsid:
return 0;
case TOK_ASM_fpscr:
return 1;
case TOK_ASM_fpexc:
return 8;
default:
return -1;
}
}
/* Parse a text containing operand and store the result in OP */
static void parse_operand(TCCState *s1, Operand *op)
{
@ -1915,10 +1929,6 @@ static void asm_floating_point_data_processing_opcode(TCCState *s1, int token) {
VMOV Rd, Dn[0]
VMOV Dn[1], Rd
VMOV Rd, Dn[1]
VMSR <sysreg>, Rd
VMRS Rd, <sysreg>
VMRS APSR_nzcv, FPSCR
*/
switch (ARM_INSTRUCTION_GROUP(token)) {
@ -2110,6 +2120,68 @@ static void asm_floating_point_data_processing_opcode(TCCState *s1, int token) {
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* s1, int token)
{
uint8_t coprocessor = CP_SINGLE_PRECISION_FLOAT;
uint8_t opcode;
int vfp_sys_reg = -1;
Operand arm_operand;
switch (ARM_INSTRUCTION_GROUP(token)) {
case TOK_ASM_vmrseq:
opcode = 0xf;
if (tok == TOK_ASM_apsr_nzcv) {
arm_operand.type = OP_REG32;
arm_operand.reg = 15; // not PC
next(); // skip apsr_nzcv
} else {
parse_operand(s1, &arm_operand);
if (arm_operand.type == OP_REG32 && arm_operand.reg == 15) {
tcc_error("'%s' does not support 'pc' as operand", get_tok_str(token, NULL));
return;
}
}
if (tok != ',')
expect("','");
else
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' 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(tok);
next(); // skip vfp sys reg
if (tok != ',')
expect("','");
else
next(); // skip ','
parse_operand(s1, &arm_operand);
if (arm_operand.type == OP_REG32 && arm_operand.reg == 15) {
tcc_error("'%s' does not support 'pc' as operand", get_tok_str(token, NULL));
return;
}
break;
default:
expect("floating point status register instruction");
return;
}
if (vfp_sys_reg == -1) {
expect("VFP system register");
return;
}
if (arm_operand.type != OP_REG32) {
expect("ARM register");
return;
}
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 *s1, int token)
@ -2518,6 +2590,11 @@ ST_FUNC void asm_opcode(TCCState *s1, int token)
case TOK_ASM_vstmdbeq:
asm_floating_point_block_data_transfer_opcode(s1, token);
return;
case TOK_ASM_vmsreq:
case TOK_ASM_vmrseq:
asm_floating_point_status_register_opcode(s1, token);
return;
#endif
default:

View File

@ -120,6 +120,16 @@
DEF_ASM(d14)
DEF_ASM(d15)
/* VFP status registers */
DEF_ASM(fpsid)
DEF_ASM(fpscr)
DEF_ASM(fpexc)
/* VFP magical ARM register */
DEF_ASM(apsr_nzcv)
/* data processing directives */
DEF_ASM(asl)
@ -333,3 +343,5 @@
DEF_ASM_CONDED(vstm)
DEF_ASM_CONDED(vstmia)
DEF_ASM_CONDED(vstmdb)
DEF_ASM_CONDED(vmsr)
DEF_ASM_CONDED(vmrs)

View File

@ -14,7 +14,7 @@ cat ../arm-tok.h | \
sed -e 's;^[ ]*DEF_ASM_CONDED_VFP_F32_F64[^(]*(\(.*\)).*$; DEF_ASM_CONDED(\1.f32)\
DEF_ASM_CONDED(\1.f64);g' | \
sed -e 's;^[ ]*DEF_ASM[^(]*(\(.*\)).*$;\1;g' | \
egrep -v '^((r|c|p|s|d)[0-9]+|fp|ip|sp|lr|pc|asl)$' | while read s
egrep -v '^((r|c|p|s|d)[0-9]+|fp|ip|sp|lr|pc|asl|apsr_nzcv|fpsid|fpscr|fpexc)$' | while read s
do
as_opts=""
if [ "${s#v}" != "${s}" ]
@ -155,6 +155,13 @@ do
"d1, r2, r3" \
"s1, r2" \
"r2, s1" \
"r2, fpexc" \
"r2, fpscr" \
"r2, fpsid" \
"apsr_nzcv, fpscr" \
"fpexc, r2" \
"fpscr, r2" \
"fpsid, r2" \
""
do
#echo ".syntax unified" > a.s