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
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:

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