History

stdatomic: atomic builtins parsing support

Dmitry Selyutin committed 5 years ago

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

Showing the changes to tccgen.c (1 of 4 files). Show all

Unified · Split

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:

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