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
10511051 #define IS_ENUM_VAL(t) ((t & VT_STRUCT_MASK) == VT_ENUM_VAL)
10521052 #define IS_UNION(t) ((t & (VT_STRUCT_MASK|VT_BTYPE)) == VT_UNION)
10531053
1054+#define VT_ATOMIC VT_VOLATILE
1055+#define VT_MEMMODEL (VT_STATIC | VT_ENUM_VAL | VT_TYPEDEF)
1056+
10541057 /* type mask (except storage) */
10551058 #define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
10561059 #define VT_TYPE (~(VT_STORAGE|VT_STRUCT_MASK))
@@ -1418,6 +1421,7 @@ ST_FUNC void tccpp_delete(TCCState *s); · 361 unmodified lines
14181421 ST_FUNC int tcc_preprocess(TCCState *s1);
14191422 ST_FUNC void skip(int c);
14201423 ST_FUNC NORETURN void expect(const char *msg);
1424+ST_FUNC NORETURN void expect_arg(const char *msg, size_t arg);
14211425
14221426 /* space excluding newline */
14231427 static 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
51605160 goto basic_type2;
51615161
51625162 /* 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;
51635177 case TOK_CONST1:
51645178 case TOK_CONST2:
51655179 case TOK_CONST3:
@@ -5515,6 +5529,9 @@ static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td) · 349 unmodified lines
55155529 redo:
55165530 next();
55175531 switch(tok) {
5532+ case TOK__Atomic:
5533+ qualifiers |= VT_ATOMIC;
5534+ goto redo;
55185535 case TOK_CONST1:
55195536 case TOK_CONST2:
55205537 case TOK_CONST3:
@@ -5710,6 +5727,117 @@ static void parse_builtin_params(int nc, const char *args) · 189 unmodified lines
57105727 nocode_wanted--;
57115728 }
57125729
5730+static 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+
5746+static 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+
57135841 ST_FUNC void unary(void)
57145842 {
57155843 int n, t, align, size, r, sizeof_caller;
@@ -6086,6 +6214,31 @@ ST_FUNC void unary(void) · 370 unmodified lines
60866214 }
60876215 #endif
60886216
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+
60896242 /* pre operations */
60906243 case TOK_INC:
60916244 case TOK_DEC:
tccpp.c+5−0
@@ -107,6 +107,11 @@ ST_FUNC void expect(const char *msg) · 106 unmodified lines
107107 tcc_error("%s expected", msg);
108108 }
109109
110+ST_FUNC void expect_arg(const char *msg, size_t arg)
111+{
112+ tcc_error("%s expected as arg #%zu", msg, arg);
113+}
114+
110115 /* ------------------------------------------------------------------------- */
111116 /* Custom allocator for tiny objects */
112117
tcctok.h+22−0
@@ -17,6 +17,7 @@ · 16 unmodified lines
1717 DEF(TOK_SWITCH, "switch")
1818 DEF(TOK_CASE, "case")
1919
20+ DEF(TOK__Atomic, "_Atomic")
2021 DEF(TOK_CONST1, "const")
2122 DEF(TOK_CONST2, "__const") /* gcc keyword */
2223 DEF(TOK_CONST3, "__const__") /* gcc keyword */
@@ -173,6 +174,27 @@ · 150 unmodified lines
173174 DEF(TOK_builtin_va_start, "__builtin_va_start")
174175 #endif
175176
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+
176198 /* pragma */
177199 DEF(TOK_pack, "pack")
178200 #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