History

stdatomic: atomic builtins parsing support

Dmitry Selyutin committed 5 years ago

Commit a1102871 parent 557b4a14 files · +184 −0Browse files

Unified · Split

4 files
  1. tcc.h +4 −0
  2. tccgen.c +153 −0
  3. tccpp.c +5 −0
  4. tcctok.h +22 −0
tcc.h+4−0
@@ -1051,6 +1051,9 @@ struct filespec { · 1050 unmodified lines
1051#define IS_ENUM_VAL(t) ((t & VT_STRUCT_MASK) == VT_ENUM_VAL)1051#define IS_ENUM_VAL(t) ((t & VT_STRUCT_MASK) == VT_ENUM_VAL)
1052#define IS_UNION(t) ((t & (VT_STRUCT_MASK|VT_BTYPE)) == VT_UNION)1052#define IS_UNION(t) ((t & (VT_STRUCT_MASK|VT_BTYPE)) == VT_UNION)
1053 1053
1054#define VT_ATOMIC VT_VOLATILE
1055#define VT_MEMMODEL (VT_STATIC | VT_ENUM_VAL | VT_TYPEDEF)
1056
1054/* type mask (except storage) */1057/* type mask (except storage) */
1055#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)1058#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
1056#define VT_TYPE (~(VT_STORAGE|VT_STRUCT_MASK))1059#define VT_TYPE (~(VT_STORAGE|VT_STRUCT_MASK))
@@ -1418,6 +1421,7 @@ ST_FUNC void tccpp_delete(TCCState *s); · 361 unmodified lines
1418ST_FUNC int tcc_preprocess(TCCState *s1);1421ST_FUNC int tcc_preprocess(TCCState *s1);
1419ST_FUNC void skip(int c);1422ST_FUNC void skip(int c);
1420ST_FUNC NORETURN void expect(const char *msg);1423ST_FUNC NORETURN void expect(const char *msg);
1424ST_FUNC NORETURN void expect_arg(const char *msg, size_t arg);
1421 1425
1422/* space excluding newline */1426/* space excluding newline */
1423static inline int is_space(int ch) {1427static inline int is_space(int ch) {
tccgen.c+153−0
@@ -5160,6 +5160,20 @@ static int parse_btype(CType *type, AttributeDef *ad) · 5159 unmodified lines
5160 goto basic_type2;5160 goto basic_type2;
5161 5161
5162 /* type modifiers */5162 /* type modifiers */
5163 case TOK__Atomic:
5164 next();
5165 type->t = t;
5166 parse_btype_qualify(type, VT_ATOMIC);
5167 t = type->t;
5168 if (tok == '(') {
5169 parse_expr_type(&type1);
5170 /* remove all storage modifiers except typedef */
5171 type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
5172 if (type1.ref)
5173 sym_to_attr(ad, type1.ref);
5174 goto basic_type2;
5175 }
5176 break;
5163 case TOK_CONST1:5177 case TOK_CONST1:
5164 case TOK_CONST2:5178 case TOK_CONST2:
5165 case TOK_CONST3:5179 case TOK_CONST3:
@@ -5515,6 +5529,9 @@ static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td) · 349 unmodified lines
5515 redo:5529 redo:
5516 next();5530 next();
5517 switch(tok) {5531 switch(tok) {
5532 case TOK__Atomic:
5533 qualifiers |= VT_ATOMIC;
5534 goto redo;
5518 case TOK_CONST1:5535 case TOK_CONST1:
5519 case TOK_CONST2:5536 case TOK_CONST2:
5520 case TOK_CONST3:5537 case TOK_CONST3:
@@ -5710,6 +5727,117 @@ static void parse_builtin_params(int nc, const char *args) · 189 unmodified lines
5710 nocode_wanted--;5727 nocode_wanted--;
5711}5728}
5712 5729
5730static void parse_memory_model(int mtok)
5731{
5732 next();
5733
5734 switch (mtok) {
5735 case TOK___ATOMIC_RELAXED: vpushs(0); break;
5736 case TOK___ATOMIC_CONSUME: vpushs(1); break;
5737 case TOK___ATOMIC_ACQUIRE: vpushs(2); break;
5738 case TOK___ATOMIC_RELEASE: vpushs(3); break;
5739 case TOK___ATOMIC_ACQ_REL: vpushs(4); break;
5740 case TOK___ATOMIC_SEQ_CST: vpushs(5); break;
5741 }
5742
5743 vtop->type.t |= (VT_UNSIGNED | VT_MEMMODEL);
5744}
5745
5746static void parse_atomic(int atok)
5747{
5748 size_t arg;
5749 size_t argc;
5750 int param;
5751 char const *params;
5752 CType *atom = NULL;
5753
5754 next();
5755
5756 /*
5757 * a -- atomic
5758 * A -- read-only atomic
5759 * p -- pointer to memory
5760 * P -- pointer to read-only memory
5761 * v -- value
5762 * m -- memory model
5763 */
5764 switch (atok) {
5765 case TOK___atomic_init: params = "-a"; break;
5766 case TOK___atomic_store: params = "-avm"; break;
5767 case TOK___atomic_load: params = "am"; break;
5768 case TOK___atomic_exchange: params = "avm"; break;
5769 case TOK___atomic_compare_exchange_strong: params = "apvmm"; break;
5770 case TOK___atomic_compare_exchange_weak: params = "apvmm"; break;
5771 case TOK___atomic_fetch_add: params = "avm"; break;
5772 case TOK___atomic_fetch_sub: params = "avm"; break;
5773 case TOK___atomic_fetch_or: params = "avm"; break;
5774 case TOK___atomic_fetch_xor: params = "avm"; break;
5775 case TOK___atomic_fetch_and: params = "avm"; break;
5776 }
5777
5778 argc = strlen(params);
5779 if (params[0] == '-') {
5780 ++params;
5781 --argc;
5782 }
5783
5784 skip('(');
5785 for (arg = 0; arg < argc; ++arg) {
5786 expr_eq();
5787
5788 param = params[arg];
5789 switch (param) {
5790 case 'a':
5791 case 'A':
5792 if (atom)
5793 expect_arg("exactly one pointer to atomic", arg);
5794 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
5795 expect_arg("pointer to atomic expected", arg);
5796 atom = pointed_type(&vtop->type);
5797 if (!(atom->t & VT_ATOMIC))
5798 expect_arg("qualified pointer to atomic", arg);
5799 if ((param == 'a') && (atom->t & VT_CONSTANT))
5800 expect_arg("pointer to writable atomic", arg);
5801 if (!is_integer_btype(atom->t & VT_BTYPE))
5802 expect_arg("only atomic integers are supported", arg);
5803 atom->t &= ~VT_ATOMIC;
5804 break;
5805
5806 case 'p':
5807 if (((vtop->type.t & VT_BTYPE) != VT_PTR)
5808 || !is_compatible_unqualified_types(atom, pointed_type(&vtop->type)))
5809 expect_arg("pointer to compatible type", arg);
5810 break;
5811
5812 case 'v':
5813 if (!is_integer_btype(vtop->type.t & VT_BTYPE))
5814 expect_arg("only atomic integers are supported", arg);
5815 break;
5816
5817 case 'm':
5818 if ((vtop->type.t & VT_MEMMODEL) != VT_MEMMODEL)
5819 expect_arg("memory model constant", arg);
5820 vtop->type.t &= ~VT_MEMMODEL;
5821 break;
5822
5823 default:
5824 tcc_error("unknown parameter type");
5825 }
5826 if (tok == ')')
5827 break;
5828 skip(',');
5829 }
5830 if (arg < (argc - 1))
5831 expect("more parameters");
5832 if (arg > (argc - 1))
5833 expect("less parameters");
5834 skip(')');
5835
5836 for (arg = 0; arg < (argc - 1); ++arg)
5837 vpop();
5838 tcc_error("atomics are not supported yet");
5839}
5840
5713ST_FUNC void unary(void)5841ST_FUNC void unary(void)
5714{5842{
5715 int n, t, align, size, r, sizeof_caller;5843 int n, t, align, size, r, sizeof_caller;
@@ -6086,6 +6214,31 @@ ST_FUNC void unary(void) · 370 unmodified lines
6086 }6214 }
6087#endif6215#endif
6088 6216
6217 /* memory models */
6218 case TOK___ATOMIC_RELAXED:
6219 case TOK___ATOMIC_CONSUME:
6220 case TOK___ATOMIC_ACQUIRE:
6221 case TOK___ATOMIC_RELEASE:
6222 case TOK___ATOMIC_ACQ_REL:
6223 case TOK___ATOMIC_SEQ_CST:
6224 parse_memory_model(tok);
6225 break;
6226
6227 /* atomic operations */
6228 case TOK___atomic_init:
6229 case TOK___atomic_store:
6230 case TOK___atomic_load:
6231 case TOK___atomic_exchange:
6232 case TOK___atomic_compare_exchange_strong:
6233 case TOK___atomic_compare_exchange_weak:
6234 case TOK___atomic_fetch_add:
6235 case TOK___atomic_fetch_sub:
6236 case TOK___atomic_fetch_or:
6237 case TOK___atomic_fetch_xor:
6238 case TOK___atomic_fetch_and:
6239 parse_atomic(tok);
6240 break;
6241
6089 /* pre operations */6242 /* pre operations */
6090 case TOK_INC:6243 case TOK_INC:
6091 case TOK_DEC:6244 case TOK_DEC:
tccpp.c+5−0
@@ -107,6 +107,11 @@ ST_FUNC void expect(const char *msg) · 106 unmodified lines
107 tcc_error("%s expected", msg);107 tcc_error("%s expected", msg);
108}108}
109 109
110ST_FUNC void expect_arg(const char *msg, size_t arg)
111{
112 tcc_error("%s expected as arg #%zu", msg, arg);
113}
114
110/* ------------------------------------------------------------------------- */115/* ------------------------------------------------------------------------- */
111/* Custom allocator for tiny objects */116/* Custom allocator for tiny objects */
112 117
tcctok.h+22−0
@@ -17,6 +17,7 @@ · 16 unmodified lines
17 DEF(TOK_SWITCH, "switch")17 DEF(TOK_SWITCH, "switch")
18 DEF(TOK_CASE, "case")18 DEF(TOK_CASE, "case")
19 19
20 DEF(TOK__Atomic, "_Atomic")
20 DEF(TOK_CONST1, "const")21 DEF(TOK_CONST1, "const")
21 DEF(TOK_CONST2, "__const") /* gcc keyword */22 DEF(TOK_CONST2, "__const") /* gcc keyword */
22 DEF(TOK_CONST3, "__const__") /* gcc keyword */23 DEF(TOK_CONST3, "__const__") /* gcc keyword */
@@ -173,6 +174,27 @@ · 150 unmodified lines
173 DEF(TOK_builtin_va_start, "__builtin_va_start")174 DEF(TOK_builtin_va_start, "__builtin_va_start")
174#endif175#endif
175 176
177/* memory models */
178 DEF(TOK___ATOMIC_RELAXED, "__ATOMIC_RELAXED")
179 DEF(TOK___ATOMIC_CONSUME, "__ATOMIC_CONSUME")
180 DEF(TOK___ATOMIC_ACQUIRE, "__ATOMIC_ACQUIRE")
181 DEF(TOK___ATOMIC_RELEASE, "__ATOMIC_RELEASE")
182 DEF(TOK___ATOMIC_ACQ_REL, "__ATOMIC_ACQ_REL")
183 DEF(TOK___ATOMIC_SEQ_CST, "__ATOMIC_SEQ_CST")
184
185/* atomic operations */
186 DEF(TOK___atomic_init, "__atomic_init")
187 DEF(TOK___atomic_store, "__atomic_store")
188 DEF(TOK___atomic_load, "__atomic_load")
189 DEF(TOK___atomic_exchange, "__atomic_exchange")
190 DEF(TOK___atomic_compare_exchange_strong, "__atomic_compare_exchange_strong")
191 DEF(TOK___atomic_compare_exchange_weak, "__atomic_compare_exchange_weak")
192 DEF(TOK___atomic_fetch_add, "__atomic_fetch_add")
193 DEF(TOK___atomic_fetch_sub, "__atomic_fetch_sub")
194 DEF(TOK___atomic_fetch_or, "__atomic_fetch_or")
195 DEF(TOK___atomic_fetch_xor, "__atomic_fetch_xor")
196 DEF(TOK___atomic_fetch_and, "__atomic_fetch_and")
197
176/* pragma */198/* pragma */
177 DEF(TOK_pack, "pack")199 DEF(TOK_pack, "pack")
178#if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_X86_64) && \200#if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_X86_64) && \

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