History

stdatomic: refactor parser and generator

Dmitry Selyutin committed 5 years ago

Commit 1ff86791 parent d0d0c8b3 files · +116 −116Browse files

Unified · Split

3 files
  1. include/stdatomic.h +27 −25
  2. tccgen.c +73 −73
  3. tcctok.h +16 −18
include/stdatomic.h+27−25
@@ -72,57 +72,59 @@ typedef struct { · 71 unmodified lines
7272 #define ATOMIC_FLAG_INIT {0}
7373
7474 #define atomic_flag_test_and_set(object) \
75− __c11_atomic_exchange(&(object)->value, 1, __ATOMIC_SEQ_CST)
75+ __atomic_exchange(&(object)->value, 1, __ATOMIC_SEQ_CST)
7676 #define atomic_flag_test_and_set_explicit(object, order) \
77− __c11_atomic_exchange(&(object)->value, 1, order)
77+ __atomic_exchange(&(object)->value, 1, order)
7878
7979 #define atomic_flag_clear(object) \
80− __c11_atomic_store(&(object)->value, 0, __ATOMIC_SEQ_CST)
80+ __atomic_store(&(object)->value, 0, __ATOMIC_SEQ_CST)
8181 #define atomic_flag_clear_explicit(object, order) \
82− __c11_atomic_store(&(object)->value, 0, order)
82+ __atomic_store(&(object)->value, 0, order)
8383
8484 /* Generic routines */
8585 #define atomic_init(object, desired) \
86− __c11_atomic_init(object, desired)
86+ __atomic_store(object, desired, __ATOMIC_RELAXED)
8787
8888 #define atomic_store(object, desired) \
89− __c11_atomic_store(object, desired, __ATOMIC_SEQ_CST)
90−#define atomic_store_explicit __c11_atomic_store
89+ __atomic_store(object, desired, __ATOMIC_SEQ_CST)
90+#define atomic_store_explicit __atomic_store
9191
9292 #define atomic_load(object) \
93− __c11_atomic_load(object, __ATOMIC_SEQ_CST)
94−#define atomic_load_explicit __c11_atomic_load
93+ __atomic_load(object, __ATOMIC_SEQ_CST)
94+#define atomic_load_explicit __atomic_load
9595
9696 #define atomic_exchange(object, desired) \
97− __c11_atomic_exchange(object, desired, __ATOMIC_SEQ_CST)
98−#define atomic_exchange_explicit __c11_atomic_exchange
97+ __atomic_exchange(object, desired, __ATOMIC_SEQ_CST)
98+#define atomic_exchange_explicit __atomic_exchange
9999
100100 #define atomic_compare_exchange_strong(object, expected, desired) \
101− __c11_atomic_compare_exchange_strong(object, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
102−#define atomic_compare_exchange_strong_explicit __c11_atomic_compare_exchange_strong
101+ __atomic_compare_exchange(object, expected, desired, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
102+#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
103+ __atomic_compare_exchange(object, expected, desired, 0, success, failure)
103104
104105 #define atomic_compare_exchange_weak(object, expected, desired) \
105− __c11_atomic_compare_exchange_weak(object, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
106−#define atomic_compare_exchange_weak_explicit __c11_atomic_compare_exchange_weak
106+ __atomic_compare_exchange(object, expected, desired, 1, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
107+#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
108+ __atomic_compare_exchange(object, expected, desired, 1, success, failure)
107109
108110 #define atomic_fetch_add(object, operand) \
109− __c11_atomic_fetch_add(object, operand, __ATOMIC_SEQ_CST)
110−#define atomic_fetch_add_explicit __c11_atomic_fetch_add
111+ __atomic_fetch_add(object, operand, __ATOMIC_SEQ_CST)
112+#define atomic_fetch_add_explicit __atomic_fetch_add
111113
112114 #define atomic_fetch_sub(object, operand) \
113− __c11_atomic_fetch_sub(object, operand, __ATOMIC_SEQ_CST)
114−#define atomic_fetch_sub_explicit __c11_atomic_fetch_sub
115+ __atomic_fetch_sub(object, operand, __ATOMIC_SEQ_CST)
116+#define atomic_fetch_sub_explicit __atomic_fetch_sub
115117
116118 #define atomic_fetch_or(object, operand) \
117− __c11_atomic_fetch_or(object, operand, __ATOMIC_SEQ_CST)
118−#define atomic_fetch_or_explicit __c11_atomic_fetch_or
119+ __atomic_fetch_or(object, operand, __ATOMIC_SEQ_CST)
120+#define atomic_fetch_or_explicit __atomic_fetch_or
119121
120122 #define atomic_fetch_xor(object, operand) \
121− __c11_atomic_fetch_xor(object, operand, __ATOMIC_SEQ_CST)
122−#define atomic_fetch_xor_explicit __c11_atomic_fetch_xor
123+ __atomic_fetch_xor(object, operand, __ATOMIC_SEQ_CST)
124+#define atomic_fetch_xor_explicit __atomic_fetch_xor
123125
124126 #define atomic_fetch_and(object, operand) \
125− __c11_atomic_fetch_and(object, operand, __ATOMIC_SEQ_CST)
126−#define atomic_fetch_and_explicit __c11_atomic_fetch_and
127+ __atomic_fetch_and(object, operand, __ATOMIC_SEQ_CST)
128+#define atomic_fetch_and_explicit __atomic_fetch_and
127129
128130 #endif /* _STDATOMIC_H */
tccgen.c+73−73
@@ -5755,94 +5755,86 @@ static inline int is_memory_model(const SValue *sv) · 5754 unmodified lines
57555755 * Ideally we should check whether the model matches 1:1.
57565756 * If it is possible, we should check by the name of the value.
57575757 */
5758− return (((sv->type.t & VT_BTYPE) == VT_INT) && (sv->c.i < 6));
5758+ return 1;
57595759 }
57605760
5761+#define ATOMIC_ID(ATOK) \
5762+ (ATOK - TOK___atomic_store)
5763+
57615764 static void parse_atomic(int atok)
57625765 {
5763− size_t op;
5766+ int mode;
57645767 size_t arg;
5765− size_t argc;
5766− CType *atom = NULL;
5767− char const *params = NULL;
5768− static struct {
5769− int const tok;
5770− char const *const params;
5771− } const ops[] = {
5768+ SValue *call;
5769+ CType atom = {};
5770+ static const char const *templates[] = {
57725771 /*
5773− * a -- atomic
5774− * A -- read-only atomic
5775− * p -- pointer to memory
5776− * P -- pointer to read-only memory
5777− * v -- value
5778− * m -- memory model
5772+ * Each entry consists of callback and function template.
5773+ * The template represents argument types and return type.
5774+ *
5775+ * ? void (return-only)
5776+ * b bool
5777+ * a atomic
5778+ * A read-only atomic
5779+ * p pointer to memory
5780+ * v value
5781+ * m memory model
57795782 */
5780− {TOK___c11_atomic_init, "-av"},
5781− {TOK___c11_atomic_store, "-avm"},
5782− {TOK___c11_atomic_load, "am"},
5783− {TOK___c11_atomic_exchange, "avm"},
5784− {TOK___c11_atomic_compare_exchange_strong, "apvmm"},
5785− {TOK___c11_atomic_compare_exchange_weak, "apvmm"},
5786− {TOK___c11_atomic_fetch_add, "avm"},
5787− {TOK___c11_atomic_fetch_sub, "avm"},
5788− {TOK___c11_atomic_fetch_or, "avm"},
5789− {TOK___c11_atomic_fetch_xor, "avm"},
5790− {TOK___c11_atomic_fetch_and, "avm"},
5783+ [ATOMIC_ID(TOK___atomic_store)] = "avm?",
5784+ [ATOMIC_ID(TOK___atomic_load)] = "Amv",
5785+ [ATOMIC_ID(TOK___atomic_exchange)] = "avmv",
5786+ [ATOMIC_ID(TOK___atomic_compare_exchange)] = "apvbmmb",
5787+ [ATOMIC_ID(TOK___atomic_fetch_add)] = "avmv",
5788+ [ATOMIC_ID(TOK___atomic_fetch_sub)] = "avmv",
5789+ [ATOMIC_ID(TOK___atomic_fetch_or)] = "avmv",
5790+ [ATOMIC_ID(TOK___atomic_fetch_xor)] = "avmv",
5791+ [ATOMIC_ID(TOK___atomic_fetch_and)] = "avmv",
57915792 };
5793+ const char *template = templates[ATOMIC_ID(atok)];
5794+ const size_t argc = (strlen(template) - 1);
57925795
57935796 next();
57945797
5795− for (op = 0; op < (sizeof(ops) / sizeof(*ops)); ++op) {
5796− if (ops[op].tok == atok) {
5797− params = ops[op].params;
5798− break;
5799− }
5800− }
5801− if (!params)
5802− tcc_error("unknown atomic operation");
5803−
5804− argc = strlen(params);
5805− if (params[0] == '-') {
5806− ++params;
5807− --argc;
5808− }
5809−
5810− vpushi(0);
5811− vpushi(0); /* function address */
5798+ vpush_helper_func(atok);
5799+ call = vtop;
58125800
58135801 skip('(');
5802+ if ((*template != 'a') && (*template != 'A'))
5803+ expect_arg("pointer to atomic", 0);
58145804 for (arg = 0; arg < argc; ++arg) {
58155805 expr_eq();
58165806
5817− switch (params[arg]) {
5807+ switch (template[arg]) {
5808+ case '?':
5809+ /* void makes sense only for return value. */
5810+ if (arg != (argc - 1))
5811+ tcc_error("illegal atomic built-in template");
5812+ break;
5813+
5814+ case 'b':
5815+ break;
5816+
58185817 case 'a':
58195818 case 'A':
5820− if (atom)
5821− expect_arg("exactly one pointer to atomic", arg);
58225819 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
5823− expect_arg("pointer to atomic expected", arg);
5824− atom = pointed_type(&vtop->type);
5825− if (!(atom->t & VT_ATOMIC))
5826− expect_arg("qualified pointer to atomic", arg);
5827− if ((params[arg] == 'a') && (atom->t & VT_CONSTANT))
5820+ expect_arg("pointer to atomic value", arg);
5821+ memcpy(&atom, pointed_type(&vtop->type), sizeof(CType));
5822+ if (!(atom.t & VT_ATOMIC))
5823+ expect_arg("qualified pointer to atomic value", arg);
5824+ if ((template[arg] == 'a') && (atom.t & VT_CONSTANT))
58285825 expect_arg("pointer to writable atomic", arg);
5829− atom->t &= ~VT_ATOMIC;
5830− switch (btype_size(atom->t & VT_BTYPE)) {
5831− case 1: atok += 1; break;
5832− case 2: atok += 2; break;
5833− case 4: atok += 3; break;
5834− case 8: atok += 4; break;
5826+ switch (btype_size(atom.t & VT_BTYPE)) {
5827+ case 8: mode = 4; break;
5828+ case 4: mode = 3; break;
5829+ case 2: mode = 2; break;
5830+ case 1: mode = 1; break;
58355831 default: tcc_error("only integer-sized types are supported");
58365832 }
5837− vswap();
5838− vpop();
5839− vpush_helper_func(atok);
5840− vswap();
58415833 break;
58425834
58435835 case 'p':
58445836 if (((vtop->type.t & VT_BTYPE) != VT_PTR)
5845− || !is_compatible_unqualified_types(atom, pointed_type(&vtop->type)))
5837+ || !is_compatible_unqualified_types(&atom, pointed_type(&vtop->type)))
58465838 expect_arg("pointer to compatible type", arg);
58475839 break;
58485840
@@ -5870,7 +5862,17 @@ static void parse_atomic(int atok) · 21 unmodified lines
58705862 expect("less parameters");
58715863 skip(')');
58725864
5865+ call->sym = external_helper_sym(atok + mode);
58735866 gfunc_call(argc);
5867+ vpushi(0);
5868+
5869+ switch (template[argc]) {
5870+ case 'b': PUT_R_RET(vtop, VT_BOOL); break;
5871+ case 'v': PUT_R_RET(vtop, atom.t); break;
5872+ case 'p': PUT_R_RET(vtop, VT_SIZE_T); break;
5873+ case '?': PUT_R_RET(vtop, VT_VOID); break;
5874+ default: tcc_error("incorrect atomic template");
5875+ }
58745876 }
58755877
58765878 ST_FUNC void unary(void)
@@ -6255,17 +6257,15 @@ ST_FUNC void unary(void) · 378 unmodified lines
62556257 #endif
62566258
62576259 /* atomic operations */
6258− case TOK___c11_atomic_init:
6259− case TOK___c11_atomic_store:
6260− case TOK___c11_atomic_load:
6261− case TOK___c11_atomic_exchange:
6262− case TOK___c11_atomic_compare_exchange_strong:
6263− case TOK___c11_atomic_compare_exchange_weak:
6264− case TOK___c11_atomic_fetch_add:
6265− case TOK___c11_atomic_fetch_sub:
6266− case TOK___c11_atomic_fetch_or:
6267− case TOK___c11_atomic_fetch_xor:
6268− case TOK___c11_atomic_fetch_and:
6260+ case TOK___atomic_store:
6261+ case TOK___atomic_load:
6262+ case TOK___atomic_exchange:
6263+ case TOK___atomic_compare_exchange:
6264+ case TOK___atomic_fetch_add:
6265+ case TOK___atomic_fetch_sub:
6266+ case TOK___atomic_fetch_or:
6267+ case TOK___atomic_fetch_xor:
6268+ case TOK___atomic_fetch_and:
62696269 parse_atomic(tok);
62706270 break;
62716271
tcctok.h+16−18
@@ -174,25 +174,23 @@ · 173 unmodified lines
174174 DEF(TOK_builtin_va_start, "__builtin_va_start")
175175 #endif
176176
177−#define DEF_ATOMIC(id, str) \
178− DEF(id, str) \
179− DEF(id##_8, str "_8") \
180− DEF(id##_16, str "_16") \
181− DEF(id##_32, str "_32") \
182− DEF(id##_64, str "_64")
183−
184177 /* atomic operations */
185− DEF_ATOMIC(TOK___c11_atomic_init, "__c11_atomic_init")
186− DEF_ATOMIC(TOK___c11_atomic_store, "__c11_atomic_store")
187− DEF_ATOMIC(TOK___c11_atomic_load, "__c11_atomic_load")
188− DEF_ATOMIC(TOK___c11_atomic_exchange, "__c11_atomic_exchange")
189− DEF_ATOMIC(TOK___c11_atomic_compare_exchange_strong, "__c11_atomic_compare_exchange_strong")
190− DEF_ATOMIC(TOK___c11_atomic_compare_exchange_weak, "__c11_atomic_compare_exchange_weak")
191− DEF_ATOMIC(TOK___c11_atomic_fetch_add, "__c11_atomic_fetch_add")
192− DEF_ATOMIC(TOK___c11_atomic_fetch_sub, "__c11_atomic_fetch_sub")
193− DEF_ATOMIC(TOK___c11_atomic_fetch_or, "__c11_atomic_fetch_or")
194− DEF_ATOMIC(TOK___c11_atomic_fetch_xor, "__c11_atomic_fetch_xor")
195− DEF_ATOMIC(TOK___c11_atomic_fetch_and, "__c11_atomic_fetch_and")
178+#define DEF_ATOMIC(ID) \
179+ DEF(TOK_##__##ID, "__"#ID) \
180+ DEF(TOK_##__##ID##_1, "__"#ID"_1") \
181+ DEF(TOK_##__##ID##_2, "__"#ID"_2") \
182+ DEF(TOK_##__##ID##_4, "__"#ID"_4") \
183+ DEF(TOK_##__##ID##_8, "__"#ID"_8")
184+
185+ DEF_ATOMIC(atomic_store)
186+ DEF_ATOMIC(atomic_load)
187+ DEF_ATOMIC(atomic_exchange)
188+ DEF_ATOMIC(atomic_compare_exchange)
189+ DEF_ATOMIC(atomic_fetch_add)
190+ DEF_ATOMIC(atomic_fetch_sub)
191+ DEF_ATOMIC(atomic_fetch_or)
192+ DEF_ATOMIC(atomic_fetch_xor)
193+ DEF_ATOMIC(atomic_fetch_and)
196194
197195 #undef DEF_ATOMIC
198196

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t