[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Tinycc-devel] [PATCH 2/3] stdatomic: emit function calls,
Dmitry Selyutin <=