[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Tinycc-devel] [PATCH] arm-asm: Add vmsr, vmrs
From: |
Danny Milosavljevic |
Subject: |
[Tinycc-devel] [PATCH] arm-asm: Add vmsr, vmrs |
Date: |
Tue, 26 Jan 2021 14:26:42 +0100 |
---
arm-asm.c | 85 ++++++++++++++++++++++++++++++++++++--
arm-tok.h | 12 ++++++
tests/arm-asm-testsuite.sh | 9 +++-
3 files changed, 101 insertions(+), 5 deletions(-)
diff --git a/arm-asm.c b/arm-asm.c
index 9c390d2..8cbcd51 100644
--- a/arm-asm.c
+++ b/arm-asm.c
@@ -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:
diff --git a/arm-tok.h b/arm-tok.h
index 79514b0..2ee79ca 100644
--- a/arm-tok.h
+++ b/arm-tok.h
@@ -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)
diff --git a/tests/arm-asm-testsuite.sh b/tests/arm-asm-testsuite.sh
index 19acf90..bfa1e10 100755
--- a/tests/arm-asm-testsuite.sh
+++ b/tests/arm-asm-testsuite.sh
@@ -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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Tinycc-devel] [PATCH] arm-asm: Add vmsr, vmrs,
Danny Milosavljevic <=