Showing the changes to tccgen.c (1 of 4 files). Show all
Unified · Split
| @@ -5160,6 +5160,20 @@ static int parse_btype(CType *type, AttributeDef *ad) · 5159 unmodified lines | ||
| 5160 | 5160 | goto basic_type2; |
| 5161 | 5161 | |
| 5162 | 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 | 5177 | case TOK_CONST1: |
| 5164 | 5178 | case TOK_CONST2: |
| 5165 | 5179 | case TOK_CONST3: |
| @@ -5515,6 +5529,9 @@ static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td) · 349 unmodified lines | ||
| 5515 | 5529 | redo: |
| 5516 | 5530 | next(); |
| 5517 | 5531 | switch(tok) { |
| 5532 | + case TOK__Atomic: | |
| 5533 | + qualifiers |= VT_ATOMIC; | |
| 5534 | + goto redo; | |
| 5518 | 5535 | case TOK_CONST1: |
| 5519 | 5536 | case TOK_CONST2: |
| 5520 | 5537 | case TOK_CONST3: |
| @@ -5710,6 +5727,117 @@ static void parse_builtin_params(int nc, const char *args) · 189 unmodified lines | ||
| 5710 | 5727 | nocode_wanted--; |
| 5711 | 5728 | } |
| 5712 | 5729 | |
| 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 | + | |
| 5713 | 5841 | ST_FUNC void unary(void) |
| 5714 | 5842 | { |
| 5715 | 5843 | int n, t, align, size, r, sizeof_caller; |
| @@ -6086,6 +6214,31 @@ ST_FUNC void unary(void) · 370 unmodified lines | ||
| 6086 | 6214 | } |
| 6087 | 6215 | #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 | 6242 | /* pre operations */ |
| 6090 | 6243 | case TOK_INC: |
| 6091 | 6244 | case TOK_DEC: |