tinycc-devel
[Top][All Lists]
Advanced

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

[Tinycc-devel] [PATCH 2/3] stdatomic: emit function calls


From: Dmitry Selyutin
Subject: [Tinycc-devel] [PATCH 2/3] stdatomic: emit function calls
Date: Tue, 26 Jan 2021 23:46:18 +0300

---
 tccgen.c | 82 +++++++++++++++++++++++++++++++++++---------------------
 tcctok.h | 31 +++++++++++++--------
 2 files changed, 71 insertions(+), 42 deletions(-)

diff --git a/tccgen.c b/tccgen.c
index 86b0e86..e625729 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -5745,35 +5745,46 @@ static void parse_memory_model(int mtok)

 static void parse_atomic(int atok)
 {
+    size_t op;
     size_t arg;
     size_t argc;
-    int param;
-    char const *params;
     CType *atom = NULL;
+    char const *params = NULL;
+    static struct {
+        int const tok;
+        char const *const params;
+    } const ops[] = {
+        /*
+         * a -- atomic
+         * A -- read-only atomic
+         * p -- pointer to memory
+         * P -- pointer to read-only memory
+         * v -- value
+         * m -- memory model
+         */
+        {TOK___atomic_init, "-a"},
+        {TOK___atomic_store, "-avm"},
+        {TOK___atomic_load, "am"},
+        {TOK___atomic_exchange, "avm"},
+        {TOK___atomic_compare_exchange_strong, "apvmm"},
+        {TOK___atomic_compare_exchange_weak, "apvmm"},
+        {TOK___atomic_fetch_add, "avm"},
+        {TOK___atomic_fetch_sub, "avm"},
+        {TOK___atomic_fetch_or, "avm"},
+        {TOK___atomic_fetch_xor, "avm"},
+        {TOK___atomic_fetch_and, "avm"},
+    };

     next();

-    /*
-     * a -- atomic
-     * A -- read-only atomic
-     * p -- pointer to memory
-     * P -- pointer to read-only memory
-     * v -- value
-     * m -- memory model
-     */
-    switch (atok) {
-    case TOK___atomic_init: params = "-a"; break;
-    case TOK___atomic_store: params = "-avm"; break;
-    case TOK___atomic_load: params = "am"; break;
-    case TOK___atomic_exchange: params = "avm"; break;
-    case TOK___atomic_compare_exchange_strong: params = "apvmm"; break;
-    case TOK___atomic_compare_exchange_weak: params = "apvmm"; break;
-    case TOK___atomic_fetch_add: params = "avm"; break;
-    case TOK___atomic_fetch_sub: params = "avm"; break;
-    case TOK___atomic_fetch_or: params = "avm"; break;
-    case TOK___atomic_fetch_xor: params = "avm"; break;
-    case TOK___atomic_fetch_and: params = "avm"; break;
+    for (op = 0; op < (sizeof(ops) / sizeof(*ops)); ++op) {
+        if (ops[op].tok == atok) {
+            params = ops[op].params;
+            break;
+        }
     }
+    if (!params)
+        tcc_error("unknown atomic operation");

     argc = strlen(params);
     if (params[0] == '-') {
@@ -5781,12 +5792,14 @@ static void parse_atomic(int atok)
         --argc;
     }

+    vpushi(0);
+    vpushi(0); /* function address */
+
     skip('(');
     for (arg = 0; arg < argc; ++arg) {
         expr_eq();

-        param = params[arg];
-        switch (param) {
+        switch (params[arg]) {
         case 'a':
         case 'A':
             if (atom)
@@ -5796,11 +5809,20 @@ static void parse_atomic(int atok)
             atom = pointed_type(&vtop->type);
             if (!(atom->t & VT_ATOMIC))
                 expect_arg("qualified pointer to atomic", arg);
-            if ((param == 'a') && (atom->t & VT_CONSTANT))
+            if ((params[arg] == 'a') && (atom->t & VT_CONSTANT))
                 expect_arg("pointer to writable atomic", arg);
-            if (!is_integer_btype(atom->t & VT_BTYPE))
-                expect_arg("only atomic integers are supported", arg);
             atom->t &= ~VT_ATOMIC;
+            switch (btype_size(atom->t & VT_BTYPE)) {
+            case 1: atok += 1; break;
+            case 2: atok += 2; break;
+            case 4: atok += 3; break;
+            case 8: atok += 4; break;
+            default: tcc_error("only integer-sized types are supported");
+            }
+            vswap();
+            vpop();
+            vpush_helper_func(atok);
+            vswap();
             break;

         case 'p':
@@ -5811,7 +5833,7 @@ static void parse_atomic(int atok)

         case 'v':
             if (!is_integer_btype(vtop->type.t & VT_BTYPE))
-                expect_arg("only atomic integers are supported", arg);
+                expect_arg("integer type", arg);
             break;

         case 'm':
@@ -5833,9 +5855,7 @@ static void parse_atomic(int atok)
         expect("less parameters");
     skip(')');

-    for (arg = 0; arg < (argc - 1); ++arg)
-        vpop();
-    tcc_error("atomics are not supported yet");
+    gfunc_call(argc);
 }

 ST_FUNC void unary(void)
diff --git a/tcctok.h b/tcctok.h
index 3ac525e..248ddb4 100644
--- a/tcctok.h
+++ b/tcctok.h
@@ -182,18 +182,27 @@
      DEF(TOK___ATOMIC_ACQ_REL, "__ATOMIC_ACQ_REL")
      DEF(TOK___ATOMIC_SEQ_CST, "__ATOMIC_SEQ_CST")

+#define DEF_ATOMIC(id, str) \
+     DEF(id, str) \
+     DEF(id##_8, str "_8") \
+     DEF(id##_16, str "_16") \
+     DEF(id##_32, str "_32") \
+     DEF(id##_64, str "_64")
+
 /* atomic operations */
-     DEF(TOK___atomic_init, "__atomic_init")
-     DEF(TOK___atomic_store, "__atomic_store")
-     DEF(TOK___atomic_load, "__atomic_load")
-     DEF(TOK___atomic_exchange, "__atomic_exchange")
-     DEF(TOK___atomic_compare_exchange_strong,
"__atomic_compare_exchange_strong")
-     DEF(TOK___atomic_compare_exchange_weak, "__atomic_compare_exchange_weak")
-     DEF(TOK___atomic_fetch_add, "__atomic_fetch_add")
-     DEF(TOK___atomic_fetch_sub, "__atomic_fetch_sub")
-     DEF(TOK___atomic_fetch_or, "__atomic_fetch_or")
-     DEF(TOK___atomic_fetch_xor, "__atomic_fetch_xor")
-     DEF(TOK___atomic_fetch_and, "__atomic_fetch_and")
+     DEF_ATOMIC(TOK___atomic_init, "__atomic_init")
+     DEF_ATOMIC(TOK___atomic_store, "__atomic_store")
+     DEF_ATOMIC(TOK___atomic_load, "__atomic_load")
+     DEF_ATOMIC(TOK___atomic_exchange, "__atomic_exchange")
+     DEF_ATOMIC(TOK___atomic_compare_exchange_strong,
"__atomic_compare_exchange_strong")
+     DEF_ATOMIC(TOK___atomic_compare_exchange_weak,
"__atomic_compare_exchange_weak")
+     DEF_ATOMIC(TOK___atomic_fetch_add, "__atomic_fetch_add")
+     DEF_ATOMIC(TOK___atomic_fetch_sub, "__atomic_fetch_sub")
+     DEF_ATOMIC(TOK___atomic_fetch_or, "__atomic_fetch_or")
+     DEF_ATOMIC(TOK___atomic_fetch_xor, "__atomic_fetch_xor")
+     DEF_ATOMIC(TOK___atomic_fetch_and, "__atomic_fetch_and")
+
+#undef DEF_ATOMIC

 /* pragma */
      DEF(TOK_pack, "pack")
--
2.30.0


-- 
Best regards,
Dmitry Selyutin



reply via email to

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