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 | 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 | ||
| 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 | ST_FUNC void unary(void) | 5841 | ST_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 | #endif | 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 | /* pre operations */ | 6242 | /* pre operations */ |
| 6090 | case TOK_INC: | 6243 | case TOK_INC: |
| 6091 | case TOK_DEC: | 6244 | case TOK_DEC: |