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
72#define ATOMIC_FLAG_INIT {0}72#define ATOMIC_FLAG_INIT {0}
73 73
74#define atomic_flag_test_and_set(object) \74#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)
76#define atomic_flag_test_and_set_explicit(object, order) \76#define atomic_flag_test_and_set_explicit(object, order) \
77 __c11_atomic_exchange(&(object)->value, 1, order)77 __atomic_exchange(&(object)->value, 1, order)
78 78
79#define atomic_flag_clear(object) \79#define atomic_flag_clear(object) \
80 __c11_atomic_store(&(object)->value, 0, __ATOMIC_SEQ_CST)80 __atomic_store(&(object)->value, 0, __ATOMIC_SEQ_CST)
81#define atomic_flag_clear_explicit(object, order) \81#define atomic_flag_clear_explicit(object, order) \
82 __c11_atomic_store(&(object)->value, 0, order)82 __atomic_store(&(object)->value, 0, order)
83 83
84/* Generic routines */84/* Generic routines */
85#define atomic_init(object, desired) \85#define atomic_init(object, desired) \
86 __c11_atomic_init(object, desired)86 __atomic_store(object, desired, __ATOMIC_RELAXED)
87 87
88#define atomic_store(object, desired) \88#define atomic_store(object, desired) \
89 __c11_atomic_store(object, desired, __ATOMIC_SEQ_CST)89 __atomic_store(object, desired, __ATOMIC_SEQ_CST)
90#define atomic_store_explicit __c11_atomic_store90#define atomic_store_explicit __atomic_store
91 91
92#define atomic_load(object) \92#define atomic_load(object) \
93 __c11_atomic_load(object, __ATOMIC_SEQ_CST)93 __atomic_load(object, __ATOMIC_SEQ_CST)
94#define atomic_load_explicit __c11_atomic_load94#define atomic_load_explicit __atomic_load
95 95
96#define atomic_exchange(object, desired) \96#define atomic_exchange(object, desired) \
97 __c11_atomic_exchange(object, desired, __ATOMIC_SEQ_CST)97 __atomic_exchange(object, desired, __ATOMIC_SEQ_CST)
98#define atomic_exchange_explicit __c11_atomic_exchange98#define atomic_exchange_explicit __atomic_exchange
99 99
100#define atomic_compare_exchange_strong(object, expected, desired) \100#define atomic_compare_exchange_strong(object, expected, desired) \
101 __c11_atomic_compare_exchange_strong(object, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)101 __atomic_compare_exchange(object, expected, desired, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
102#define atomic_compare_exchange_strong_explicit __c11_atomic_compare_exchange_strong102#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
103 __atomic_compare_exchange(object, expected, desired, 0, success, failure)
103 104
104#define atomic_compare_exchange_weak(object, expected, desired) \105#define atomic_compare_exchange_weak(object, expected, desired) \
105 __c11_atomic_compare_exchange_weak(object, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)106 __atomic_compare_exchange(object, expected, desired, 1, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
106#define atomic_compare_exchange_weak_explicit __c11_atomic_compare_exchange_weak107#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
108 __atomic_compare_exchange(object, expected, desired, 1, success, failure)
107 109
108#define atomic_fetch_add(object, operand) \110#define atomic_fetch_add(object, operand) \
109 __c11_atomic_fetch_add(object, operand, __ATOMIC_SEQ_CST)111 __atomic_fetch_add(object, operand, __ATOMIC_SEQ_CST)
110#define atomic_fetch_add_explicit __c11_atomic_fetch_add112#define atomic_fetch_add_explicit __atomic_fetch_add
111 113
112#define atomic_fetch_sub(object, operand) \114#define atomic_fetch_sub(object, operand) \
113 __c11_atomic_fetch_sub(object, operand, __ATOMIC_SEQ_CST)115 __atomic_fetch_sub(object, operand, __ATOMIC_SEQ_CST)
114#define atomic_fetch_sub_explicit __c11_atomic_fetch_sub116#define atomic_fetch_sub_explicit __atomic_fetch_sub
115 117
116#define atomic_fetch_or(object, operand) \118#define atomic_fetch_or(object, operand) \
117 __c11_atomic_fetch_or(object, operand, __ATOMIC_SEQ_CST)119 __atomic_fetch_or(object, operand, __ATOMIC_SEQ_CST)
118#define atomic_fetch_or_explicit __c11_atomic_fetch_or120#define atomic_fetch_or_explicit __atomic_fetch_or
119 121
120#define atomic_fetch_xor(object, operand) \122#define atomic_fetch_xor(object, operand) \
121 __c11_atomic_fetch_xor(object, operand, __ATOMIC_SEQ_CST)123 __atomic_fetch_xor(object, operand, __ATOMIC_SEQ_CST)
122#define atomic_fetch_xor_explicit __c11_atomic_fetch_xor124#define atomic_fetch_xor_explicit __atomic_fetch_xor
123 125
124#define atomic_fetch_and(object, operand) \126#define atomic_fetch_and(object, operand) \
125 __c11_atomic_fetch_and(object, operand, __ATOMIC_SEQ_CST)127 __atomic_fetch_and(object, operand, __ATOMIC_SEQ_CST)
126#define atomic_fetch_and_explicit __c11_atomic_fetch_and128#define atomic_fetch_and_explicit __atomic_fetch_and
127 129
128#endif /* _STDATOMIC_H */130#endif /* _STDATOMIC_H */
tccgen.c+73−73
@@ -5755,94 +5755,86 @@ static inline int is_memory_model(const SValue *sv) · 5754 unmodified lines
5755 * Ideally we should check whether the model matches 1:1.5755 * Ideally we should check whether the model matches 1:1.
5756 * If it is possible, we should check by the name of the value.5756 * If it is possible, we should check by the name of the value.
5757 */5757 */
5758 return (((sv->type.t & VT_BTYPE) == VT_INT) && (sv->c.i < 6));5758 return 1;
5759}5759}
5760 5760
5761#define ATOMIC_ID(ATOK) \
5762 (ATOK - TOK___atomic_store)
5763
5761static void parse_atomic(int atok)5764static void parse_atomic(int atok)
5762{5765{
5763 size_t op;5766 int mode;
5764 size_t arg;5767 size_t arg;
5765 size_t argc;5768 SValue *call;
5766 CType *atom = NULL;5769 CType atom = {};
5767 char const *params = NULL;5770 static const char const *templates[] = {
5768 static struct {
5769 int const tok;
5770 char const *const params;
5771 } const ops[] = {
5772 /*5771 /*
5773 * a -- atomic5772 * Each entry consists of callback and function template.
5774 * A -- read-only atomic5773 * The template represents argument types and return type.
5775 * p -- pointer to memory5774 *
5776 * P -- pointer to read-only memory5775 * ? void (return-only)
5777 * v -- value5776 * b bool
5778 * m -- memory model5777 * a atomic
5778 * A read-only atomic
5779 * p pointer to memory
5780 * v value
5781 * m memory model
5779 */5782 */
5780 {TOK___c11_atomic_init, "-av"},5783 [ATOMIC_ID(TOK___atomic_store)] = "avm?",
5781 {TOK___c11_atomic_store, "-avm"},5784 [ATOMIC_ID(TOK___atomic_load)] = "Amv",
5782 {TOK___c11_atomic_load, "am"},5785 [ATOMIC_ID(TOK___atomic_exchange)] = "avmv",
5783 {TOK___c11_atomic_exchange, "avm"},5786 [ATOMIC_ID(TOK___atomic_compare_exchange)] = "apvbmmb",
5784 {TOK___c11_atomic_compare_exchange_strong, "apvmm"},5787 [ATOMIC_ID(TOK___atomic_fetch_add)] = "avmv",
5785 {TOK___c11_atomic_compare_exchange_weak, "apvmm"},5788 [ATOMIC_ID(TOK___atomic_fetch_sub)] = "avmv",
5786 {TOK___c11_atomic_fetch_add, "avm"},5789 [ATOMIC_ID(TOK___atomic_fetch_or)] = "avmv",
5787 {TOK___c11_atomic_fetch_sub, "avm"},5790 [ATOMIC_ID(TOK___atomic_fetch_xor)] = "avmv",
5788 {TOK___c11_atomic_fetch_or, "avm"},5791 [ATOMIC_ID(TOK___atomic_fetch_and)] = "avmv",
5789 {TOK___c11_atomic_fetch_xor, "avm"},
5790 {TOK___c11_atomic_fetch_and, "avm"},
5791 };5792 };
5793 const char *template = templates[ATOMIC_ID(atok)];
5794 const size_t argc = (strlen(template) - 1);
5792 5795
5793 next();5796 next();
5794 5797
5795 for (op = 0; op < (sizeof(ops) / sizeof(*ops)); ++op) {5798 vpush_helper_func(atok);
5796 if (ops[op].tok == atok) {5799 call = vtop;
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 */
5812 5800
5813 skip('(');5801 skip('(');
5802 if ((*template != 'a') && (*template != 'A'))
5803 expect_arg("pointer to atomic", 0);
5814 for (arg = 0; arg < argc; ++arg) {5804 for (arg = 0; arg < argc; ++arg) {
5815 expr_eq();5805 expr_eq();
5816 5806
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
5818 case 'a':5817 case 'a':
5819 case 'A':5818 case 'A':
5820 if (atom)
5821 expect_arg("exactly one pointer to atomic", arg);
5822 if ((vtop->type.t & VT_BTYPE) != VT_PTR)5819 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
5823 expect_arg("pointer to atomic expected", arg);5820 expect_arg("pointer to atomic value", arg);
5824 atom = pointed_type(&vtop->type);5821 memcpy(&atom, pointed_type(&vtop->type), sizeof(CType));
5825 if (!(atom->t & VT_ATOMIC))5822 if (!(atom.t & VT_ATOMIC))
5826 expect_arg("qualified pointer to atomic", arg);5823 expect_arg("qualified pointer to atomic value", arg);
5827 if ((params[arg] == 'a') && (atom->t & VT_CONSTANT))5824 if ((template[arg] == 'a') && (atom.t & VT_CONSTANT))
5828 expect_arg("pointer to writable atomic", arg);5825 expect_arg("pointer to writable atomic", arg);
5829 atom->t &= ~VT_ATOMIC;5826 switch (btype_size(atom.t & VT_BTYPE)) {
5830 switch (btype_size(atom->t & VT_BTYPE)) {5827 case 8: mode = 4; break;
5831 case 1: atok += 1; break;5828 case 4: mode = 3; break;
5832 case 2: atok += 2; break;5829 case 2: mode = 2; break;
5833 case 4: atok += 3; break;5830 case 1: mode = 1; break;
5834 case 8: atok += 4; break;
5835 default: tcc_error("only integer-sized types are supported");5831 default: tcc_error("only integer-sized types are supported");
5836 }5832 }
5837 vswap();
5838 vpop();
5839 vpush_helper_func(atok);
5840 vswap();
5841 break;5833 break;
5842 5834
5843 case 'p':5835 case 'p':
5844 if (((vtop->type.t & VT_BTYPE) != VT_PTR)5836 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)))
5846 expect_arg("pointer to compatible type", arg);5838 expect_arg("pointer to compatible type", arg);
5847 break;5839 break;
5848 5840
@@ -5870,7 +5862,17 @@ static void parse_atomic(int atok) · 21 unmodified lines
5870 expect("less parameters");5862 expect("less parameters");
5871 skip(')');5863 skip(')');
5872 5864
5865 call->sym = external_helper_sym(atok + mode);
5873 gfunc_call(argc);5866 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 }
5874}5876}
5875 5877
5876ST_FUNC void unary(void)5878ST_FUNC void unary(void)
@@ -6255,17 +6257,15 @@ ST_FUNC void unary(void) · 378 unmodified lines
6255#endif6257#endif
6256 6258
6257 /* atomic operations */6259 /* atomic operations */
6258 case TOK___c11_atomic_init:6260 case TOK___atomic_store:
6259 case TOK___c11_atomic_store:6261 case TOK___atomic_load:
6260 case TOK___c11_atomic_load:6262 case TOK___atomic_exchange:
6261 case TOK___c11_atomic_exchange:6263 case TOK___atomic_compare_exchange:
6262 case TOK___c11_atomic_compare_exchange_strong:6264 case TOK___atomic_fetch_add:
6263 case TOK___c11_atomic_compare_exchange_weak:6265 case TOK___atomic_fetch_sub:
6264 case TOK___c11_atomic_fetch_add:6266 case TOK___atomic_fetch_or:
6265 case TOK___c11_atomic_fetch_sub:6267 case TOK___atomic_fetch_xor:
6266 case TOK___c11_atomic_fetch_or:6268 case TOK___atomic_fetch_and:
6267 case TOK___c11_atomic_fetch_xor:
6268 case TOK___c11_atomic_fetch_and:
6269 parse_atomic(tok);6269 parse_atomic(tok);
6270 break;6270 break;
6271 6271
tcctok.h+16−18
@@ -174,25 +174,23 @@ · 173 unmodified lines
174 DEF(TOK_builtin_va_start, "__builtin_va_start")174 DEF(TOK_builtin_va_start, "__builtin_va_start")
175#endif175#endif
176 176
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
184/* atomic operations */177/* atomic operations */
185 DEF_ATOMIC(TOK___c11_atomic_init, "__c11_atomic_init")178#define DEF_ATOMIC(ID) \
186 DEF_ATOMIC(TOK___c11_atomic_store, "__c11_atomic_store")179 DEF(TOK_##__##ID, "__"#ID) \
187 DEF_ATOMIC(TOK___c11_atomic_load, "__c11_atomic_load")180 DEF(TOK_##__##ID##_1, "__"#ID"_1") \
188 DEF_ATOMIC(TOK___c11_atomic_exchange, "__c11_atomic_exchange")181 DEF(TOK_##__##ID##_2, "__"#ID"_2") \
189 DEF_ATOMIC(TOK___c11_atomic_compare_exchange_strong, "__c11_atomic_compare_exchange_strong")182 DEF(TOK_##__##ID##_4, "__"#ID"_4") \
190 DEF_ATOMIC(TOK___c11_atomic_compare_exchange_weak, "__c11_atomic_compare_exchange_weak")183 DEF(TOK_##__##ID##_8, "__"#ID"_8")
191 DEF_ATOMIC(TOK___c11_atomic_fetch_add, "__c11_atomic_fetch_add")184
192 DEF_ATOMIC(TOK___c11_atomic_fetch_sub, "__c11_atomic_fetch_sub")185 DEF_ATOMIC(atomic_store)
193 DEF_ATOMIC(TOK___c11_atomic_fetch_or, "__c11_atomic_fetch_or")186 DEF_ATOMIC(atomic_load)
194 DEF_ATOMIC(TOK___c11_atomic_fetch_xor, "__c11_atomic_fetch_xor")187 DEF_ATOMIC(atomic_exchange)
195 DEF_ATOMIC(TOK___c11_atomic_fetch_and, "__c11_atomic_fetch_and")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)
196 194
197#undef DEF_ATOMIC195#undef DEF_ATOMIC
198 196

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