History

stdatomic: ld/st/xchg/cmpxchg on simple types

Some complex types can still be small and simple enough to fit into register. Other compilers allow some operations on these types, and it seems to be quite a reasonable choice. From now on, we should be able to compile the following artificial example: struct combo { uint16_t lo; uint16_t hi; }; struct combo load(const _Atomic(struct combo) *atom) { return atomic_load(atom); } void store(_Atomic(struct combo) *atom, struct combo value) { atomic_store(atom, value); } struct combo xchg(_Atomic(struct combo) *atom, struct combo value) { return atomic_exchange(atom, value); } bool cmpxchg(_Atomic(struct combo) *atom, struct combo *cmp, struct combo xchg) { return atomic_compare_exchange_strong(atom, cmp, xchg); } This might be useful for some corner cases, though it is quite likely that many programmers will prefer operating on a single 32-bit value instead of using the structure consisting of 16-bit pair. Things will work as long as the overall structure size happens to be the same as for any integer type we support in atomics.

Dmitry Selyutin committed 5 years ago

Commit 47da8e41 parent 82b0af71 file · +34 −9Browse files

Unified · Split

tccgen.c+34−9
@@ -5766,6 +5766,7 @@ static void parse_atomic(int atok) · 5765 unmodified lines
5766 int mode;5766 int mode;
5767 size_t arg;5767 size_t arg;
5768 SValue *call;5768 SValue *call;
5769 CType rv;
5769 CType atom;5770 CType atom;
5770 static const char *const templates[] = {5771 static const char *const templates[] = {
5771 /*5772 /*
@@ -5795,6 +5796,8 @@ static void parse_atomic(int atok) · 23 unmodified lines
5795 5796
5796 next();5797 next();
5797 5798
5799 memset(&rv, 0, sizeof(rv));
5800 memset(&atom, 0, sizeof(atom));
5798 mode = 0; /* pacify compiler */5801 mode = 0; /* pacify compiler */
5799 vpush_helper_func(atok);5802 vpush_helper_func(atok);
5800 call = vtop;5803 call = vtop;
@@ -5824,7 +5827,7 @@ static void parse_atomic(int atok) · 23 unmodified lines
5824 expect_arg("qualified pointer to atomic value", arg);5827 expect_arg("qualified pointer to atomic value", arg);
5825 if ((template[arg] == 'a') && (atom.t & VT_CONSTANT))5828 if ((template[arg] == 'a') && (atom.t & VT_CONSTANT))
5826 expect_arg("pointer to writable atomic", arg);5829 expect_arg("pointer to writable atomic", arg);
5827 switch (btype_size(atom.t & VT_BTYPE)) {5830 switch (type_size(&atom, &(int){0})) {
5828 case 8: mode = 4; break;5831 case 8: mode = 4; break;
5829 case 4: mode = 3; break;5832 case 4: mode = 3; break;
5830 case 2: mode = 2; break;5833 case 2: mode = 2; break;
@@ -5840,8 +5843,13 @@ static void parse_atomic(int atok) · 9 unmodified lines
5840 break;5843 break;
5841 5844
5842 case 'v':5845 case 'v':
5843 if (!is_integer_btype(vtop->type.t & VT_BTYPE))5846 if (atom.ref && is_integer_btype(vtop->type.t & VT_BTYPE)) {
5844 expect_arg("integer type", arg);5847 if ((tok != TOK___atomic_store) &&
5848 (tok != TOK___atomic_load) &&
5849 (tok != TOK___atomic_exchange) &&
5850 (tok != TOK___atomic_compare_exchange))
5851 expect_arg("integer type", arg);
5852 }
5845 break;5853 break;
5846 5854
5847 case 'm':5855 case 'm':
@@ -5865,15 +5873,32 @@ static void parse_atomic(int atok) · 17 unmodified lines
5865 5873
5866 call->sym = external_helper_sym(atok + mode);5874 call->sym = external_helper_sym(atok + mode);
5867 gfunc_call(argc);5875 gfunc_call(argc);
5868 vpushi(0);
5869 5876
5870 switch (template[argc]) {5877 switch (template[argc]) {
5871 case 'b': PUT_R_RET(vtop, VT_BOOL); break;5878 case 'b':
5872 case 'v': PUT_R_RET(vtop, atom.t); break;5879 vpushi(0);
5873 case 'p': PUT_R_RET(vtop, VT_SIZE_T); break;5880 PUT_R_RET(vtop, VT_BOOL);
5874 case '?': PUT_R_RET(vtop, VT_VOID); break;5881 break;
5875 default: tcc_error("incorrect atomic template");5882
5883 case 'p':
5884 vpushs(0);
5885 PUT_R_RET(vtop, VT_SIZE_T);
5886 break;
5887
5888 case 'v':
5889 vpush(&atom);
5890 PUT_R_RET(vtop, atom.t);
5891 break;
5892
5893 case '?':
5894 vpushi(0);
5895 PUT_R_RET(vtop, VT_VOID);
5896 break;
5897
5898 default:
5899 tcc_error("incorrect atomic template");
5876 }5900 }
5901 vtop->r2 = VT_CONST;
5877}5902}
5878 5903
5879ST_FUNC void unary(void)5904ST_FUNC void unary(void)

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