mirror of
https://github.com/rui314/chibicc
synced 2024-11-23 22:59:36 +03:00
Add atomic_exchange
This commit is contained in:
parent
ca27455b92
commit
80ea9d427c
@ -221,6 +221,7 @@ typedef enum {
|
||||
ND_MEMZERO, // Zero-clear a stack variable
|
||||
ND_ASM, // "asm"
|
||||
ND_CAS, // Atomic compare-and-swap
|
||||
ND_EXCH, // Atomic exchange
|
||||
} NodeKind;
|
||||
|
||||
// AST node type
|
||||
|
10
codegen.c
10
codegen.c
@ -983,6 +983,16 @@ static void gen_expr(Node *node) {
|
||||
println(" movzbl %%cl, %%eax");
|
||||
return;
|
||||
}
|
||||
case ND_EXCH: {
|
||||
gen_expr(node->lhs);
|
||||
push();
|
||||
gen_expr(node->rhs);
|
||||
pop("%rdi");
|
||||
|
||||
int sz = node->lhs->ty->base->size;
|
||||
println(" xchg %s, (%%rdi)", reg_ax(sz));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (node->lhs->ty->kind) {
|
||||
|
@ -7,4 +7,7 @@
|
||||
#define atomic_compare_exchange_strong(p, old, new) \
|
||||
__builtin_compare_and_swap((p), (old), (new))
|
||||
|
||||
#define atomic_exchange(obj, val) __builtin_atomic_exchange(obj, val)
|
||||
#define atomic_exchange_explicit(obj, val, order) __builtin_atomic_exchange(obj, val)
|
||||
|
||||
#endif
|
||||
|
10
parse.c
10
parse.c
@ -2954,6 +2954,16 @@ static Node *primary(Token **rest, Token *tok) {
|
||||
return node;
|
||||
}
|
||||
|
||||
if (equal(tok, "__builtin_atomic_exchange")) {
|
||||
Node *node = new_node(ND_EXCH, tok);
|
||||
tok = skip(tok->next, "(");
|
||||
node->lhs = assign(&tok, tok);
|
||||
tok = skip(tok, ",");
|
||||
node->rhs = assign(&tok, tok);
|
||||
*rest = skip(tok, ")");
|
||||
return node;
|
||||
}
|
||||
|
||||
if (tok->kind == TK_IDENT) {
|
||||
// Variable or enum constant
|
||||
VarScope *sc = find_var(tok);
|
||||
|
@ -38,6 +38,9 @@ static int add_millions(void) {
|
||||
int main() {
|
||||
ASSERT(3*1000*1000, add_millions());
|
||||
|
||||
ASSERT(3, ({ int x=3; atomic_exchange(&x, 5); }));
|
||||
ASSERT(5, ({ int x=3; atomic_exchange(&x, 5); x; }));
|
||||
|
||||
printf("OK\n");
|
||||
return 0;
|
||||
}
|
||||
|
5
type.c
5
type.c
@ -298,5 +298,10 @@ void add_type(Node *node) {
|
||||
if (node->cas_old->ty->kind != TY_PTR)
|
||||
error_tok(node->cas_old->tok, "pointer expected");
|
||||
return;
|
||||
case ND_EXCH:
|
||||
if (node->lhs->ty->kind != TY_PTR)
|
||||
error_tok(node->cas_addr->tok, "pointer expected");
|
||||
node->ty = node->lhs->ty->base;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user