tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Tinycc-devel] [PATCH v2] arm-asm: Add vcvt


From: Danny Milosavljevic
Subject: [Tinycc-devel] [PATCH v2] arm-asm: Add vcvt
Date: Fri, 12 Feb 2021 04:37:15 +0100

---
 arm-asm.c                  | 141 ++++++++++++++++++++++++++++++++++++-
 arm-tok.h                  |  36 ++++++++++
 tests/arm-asm-testsuite.sh |   4 +-
 3 files changed, 177 insertions(+), 4 deletions(-)

diff --git a/arm-asm.c b/arm-asm.c
index 95d02e6..314ce5c 100644
--- a/arm-asm.c
+++ b/arm-asm.c
@@ -1902,6 +1902,127 @@ static void 
asm_floating_point_reg_arm_reg_transfer_opcode_tail(TCCState *s1, in
     }
 }
 
+static void asm_floating_point_vcvt_data_processing_opcode(TCCState *s1, int 
token) {
+    uint8_t coprocessor = 0;
+    Operand ops[3];
+    uint8_t opcode1 = 11;
+    uint8_t opcode2 = 2;
+
+    switch (ARM_INSTRUCTION_GROUP(token)) {
+    case TOK_ASM_vcvtreq_s32_f64:
+    case TOK_ASM_vcvtreq_u32_f64:
+    case TOK_ASM_vcvteq_s32_f64:
+    case TOK_ASM_vcvteq_u32_f64:
+    case TOK_ASM_vcvteq_f64_s32:
+    case TOK_ASM_vcvteq_f64_u32:
+    case TOK_ASM_vcvteq_f32_f64:
+       coprocessor = CP_DOUBLE_PRECISION_FLOAT;
+       break;
+    case TOK_ASM_vcvtreq_s32_f32:
+    case TOK_ASM_vcvtreq_u32_f32:
+    case TOK_ASM_vcvteq_s32_f32:
+    case TOK_ASM_vcvteq_u32_f32:
+    case TOK_ASM_vcvteq_f32_s32:
+    case TOK_ASM_vcvteq_f32_u32:
+    case TOK_ASM_vcvteq_f64_f32:
+       coprocessor = CP_SINGLE_PRECISION_FLOAT;
+       break;
+    default:
+       tcc_error("Unknown coprocessor for instruction '%s'", 
get_tok_str(token, NULL));
+       return;
+    }
+
+    parse_operand(s1, &ops[0]);
+    ops[1].type = OP_IM8;
+    ops[1].e.v = 8;
+    /* floating-point -> integer */
+    switch (ARM_INSTRUCTION_GROUP(token)) {
+    case TOK_ASM_vcvtreq_s32_f32:
+    case TOK_ASM_vcvtreq_s32_f64:
+    case TOK_ASM_vcvteq_s32_f32:
+    case TOK_ASM_vcvteq_s32_f64:
+        ops[1].e.v |= 1; // signed
+        /* fall through */
+    case TOK_ASM_vcvteq_u32_f32:
+    case TOK_ASM_vcvteq_u32_f64:
+    case TOK_ASM_vcvtreq_u32_f32:
+    case TOK_ASM_vcvtreq_u32_f64:
+        ops[1].e.v |= 4; // to_integer (opc2)
+        break;
+    /* floating-point size conversion */
+    case TOK_ASM_vcvteq_f64_f32:
+    case TOK_ASM_vcvteq_f32_f64:
+        ops[1].e.v = 7;
+        break;
+    }
+
+    if (tok == ',')
+        next();
+    else
+        expect("','");
+    parse_operand(s1, &ops[2]);
+
+    switch (ARM_INSTRUCTION_GROUP(token)) {
+    /* floating-point -> integer */
+    case TOK_ASM_vcvteq_s32_f32:
+    case TOK_ASM_vcvteq_s32_f64:
+    case TOK_ASM_vcvteq_u32_f32:
+    case TOK_ASM_vcvteq_u32_f64:
+        opcode2 |= 4; // round_zero
+        break;
+
+    /* integer -> floating-point */
+    case TOK_ASM_vcvteq_f64_s32:
+    case TOK_ASM_vcvteq_f32_s32:
+        opcode2 |= 4; // signed--special
+        break;
+
+    /* floating-point size conversion */
+    case TOK_ASM_vcvteq_f64_f32:
+    case TOK_ASM_vcvteq_f32_f64:
+        opcode2 |= 4; // always set
+        break;
+    }
+
+    switch (ARM_INSTRUCTION_GROUP(token)) {
+    case TOK_ASM_vcvteq_f64_u32:
+    case TOK_ASM_vcvteq_f64_s32:
+    case TOK_ASM_vcvteq_f64_f32:
+        if (ops[0].type == OP_VREG64 && ops[2].type == OP_VREG32) {
+        } else {
+            expect("d<number>, s<number>");
+            return;
+        }
+        break;
+    default:
+        if (coprocessor == CP_SINGLE_PRECISION_FLOAT) {
+            if (ops[0].type == OP_VREG32 && ops[2].type == OP_VREG32) {
+            } else {
+                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<number>, d<number>");
+                return;
+            }
+        }
+    }
+
+    if (ops[2].type == OP_VREG32) {
+        if (ops[2].reg & 1)
+            opcode2 |= 1;
+        ops[2].reg >>= 1;
+    }
+    if (ops[0].type == OP_VREG32) {
+        if (ops[0].reg & 1)
+            opcode1 |= 4;
+        ops[0].reg >>= 1;
+    }
+    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 *s1, int token) 
{
     uint8_t coprocessor = CP_SINGLE_PRECISION_FLOAT;
     uint8_t opcode1 = 0;
@@ -1920,8 +2041,6 @@ static void 
asm_floating_point_data_processing_opcode(TCCState *s1, int token) {
    VFMA           1?10   ?0?      Must be unconditional
    VFMS           1?10   ?1?      Must be unconditional
 
-   VCVT*
-
    VMOV Fd, Fm
    VMOV Sn, Sm, Rd, Rn
    VMOV Rd, Rn, Sn, Sm
@@ -2092,7 +2211,6 @@ static void 
asm_floating_point_data_processing_opcode(TCCState *s1, int token) {
             ops[1].e.v = 0;
         }
         break;
-    // TODO: vcvt; vcvtr
     default:
         expect("known floating point instruction");
         return;
@@ -2580,6 +2698,23 @@ ST_FUNC void asm_opcode(TCCState *s1, int token)
         asm_floating_point_data_processing_opcode(s1, token);
         return;
 
+    case TOK_ASM_vcvtreq_s32_f32:
+    case TOK_ASM_vcvtreq_s32_f64:
+    case TOK_ASM_vcvteq_s32_f32:
+    case TOK_ASM_vcvteq_s32_f64:
+    case TOK_ASM_vcvtreq_u32_f32:
+    case TOK_ASM_vcvtreq_u32_f64:
+    case TOK_ASM_vcvteq_u32_f32:
+    case TOK_ASM_vcvteq_u32_f64:
+    case TOK_ASM_vcvteq_f64_s32:
+    case TOK_ASM_vcvteq_f32_s32:
+    case TOK_ASM_vcvteq_f64_u32:
+    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(s1, token);
+        return;
+
     case TOK_ASM_vpusheq:
     case TOK_ASM_vpopeq:
     case TOK_ASM_vldmeq:
diff --git a/arm-tok.h b/arm-tok.h
index 2ee79ca..297b105 100644
--- a/arm-tok.h
+++ b/arm-tok.h
@@ -186,6 +186,24 @@
   DEF_ASM_CONDED_WITH_SUFFIX(x, f32) \
   DEF_ASM_CONDED_WITH_SUFFIX(x, f64)
 
+#define DEF_ASM_CONDED_WITH_TWO_SUFFIXES(x, y, z) \
+  DEF(TOK_ASM_ ## x ## eq ## _ ## y ## _ ## z, #x "eq." #y "." #z) \
+  DEF(TOK_ASM_ ## x ## ne ## _ ## y ## _ ## z, #x "ne." #y "." #z) \
+  DEF(TOK_ASM_ ## x ## cs ## _ ## y ## _ ## z, #x "cs." #y "." #z) \
+  DEF(TOK_ASM_ ## x ## cc ## _ ## y ## _ ## z, #x "cc." #y "." #z) \
+  DEF(TOK_ASM_ ## x ## mi ## _ ## y ## _ ## z, #x "mi." #y "." #z) \
+  DEF(TOK_ASM_ ## x ## pl ## _ ## y ## _ ## z, #x "pl." #y "." #z) \
+  DEF(TOK_ASM_ ## x ## vs ## _ ## y ## _ ## z, #x "vs." #y "." #z) \
+  DEF(TOK_ASM_ ## x ## vc ## _ ## y ## _ ## z, #x "vc." #y "." #z) \
+  DEF(TOK_ASM_ ## x ## hi ## _ ## y ## _ ## z, #x "hi." #y "." #z) \
+  DEF(TOK_ASM_ ## x ## ls ## _ ## y ## _ ## z, #x "ls." #y "." #z) \
+  DEF(TOK_ASM_ ## x ## ge ## _ ## y ## _ ## z, #x "ge." #y "." #z) \
+  DEF(TOK_ASM_ ## x ## lt ## _ ## y ## _ ## z, #x "lt." #y "." #z) \
+  DEF(TOK_ASM_ ## x ## gt ## _ ## y ## _ ## z, #x "gt." #y "." #z) \
+  DEF(TOK_ASM_ ## x ## le ## _ ## y ## _ ## z, #x "le." #y "." #z) \
+  DEF(TOK_ASM_ ## x ## _ ## y ## _ ## z, #x "." #y "." #z) \
+  DEF(TOK_ASM_ ## x ## rsvd ## _ ## y ## _ ## z, #x "rsvd." #y "." #z)
+
 /* Note: add new tokens after nop (MUST always use DEF_ASM_CONDED) */
 
  DEF_ASM_CONDED(nop)
@@ -335,6 +353,24 @@
  DEF_ASM_CONDED_VFP_F32_F64(vcmpe)
  DEF_ASM_CONDED_VFP_F32_F64(vmov)
 
+ DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvtr, s32, f64)
+ DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvtr, s32, f32)
+ DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvtr, u32, f64)
+ DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvtr, u32, f32)
+
+ DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, s32, f64)
+ DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, s32, f32)
+ DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, u32, f64)
+ DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, u32, f32)
+
+ DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, f64, s32)
+ DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, f32, s32)
+ DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, f64, u32)
+ DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, f32, u32)
+
+ DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, f64, f32)
+ DEF_ASM_CONDED_WITH_TWO_SUFFIXES(vcvt, f32, f64)
+
  DEF_ASM_CONDED(vpush)
  DEF_ASM_CONDED(vpop)
  DEF_ASM_CONDED(vldm)
diff --git a/tests/arm-asm-testsuite.sh b/tests/arm-asm-testsuite.sh
index bfa1e10..61c5dad 100755
--- a/tests/arm-asm-testsuite.sh
+++ b/tests/arm-asm-testsuite.sh
@@ -13,7 +13,7 @@ cat ../arm-tok.h | \
   grep -v 'DEF_ASM_CONDED_WITH_SUFFIX(x' | \
   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' | \
+  sed -e 's;^[ ]*DEF_ASM[^(]*(\(.*\)).*$;\1;g' -e 's;, ;.;g' | \
   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=""
@@ -162,6 +162,8 @@ do
                     "fpexc, r2" \
                     "fpscr, r2" \
                     "fpsid, r2" \
+                    "s3, d4" \
+                    "d4, s3" \
                    ""
        do
                #echo ".syntax unified" > a.s



reply via email to

[Prev in Thread] Current Thread [Next in Thread]