Skip to content

Commit

Permalink
Add support for atomic XCHG
Browse files Browse the repository at this point in the history
Signed-off-by: Dave Thaler <[email protected]>
  • Loading branch information
dthaler committed Jan 3, 2024
1 parent cef7a13 commit 7f11e03
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 8 deletions.
8 changes: 5 additions & 3 deletions src/asm_ostream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,17 +341,19 @@ struct InstructionPrinterVisitor {

print(b.access);
os_ << " ";
bool showfetch = true;
switch ((AtomicOp)((uint32_t)b.op & (uint32_t)AtomicOp::INST_ATOMIC_BASE_MASK)) {
case AtomicOp::INST_ATOMIC_ADD: os_ << "+"; break;
case AtomicOp::INST_ATOMIC_OR: os_ << "|"; break;
case AtomicOp::INST_ATOMIC_AND: os_ << "&"; break;
case AtomicOp::INST_ATOMIC_XOR: os_ << "^"; break;
case AtomicOp::INST_ATOMIC_XCHG_BASE: os_ << "x"; showfetch = false; break;
case AtomicOp::INST_ATOMIC_CMPXCHG_BASE: os_ << "cx";showfetch = false; break;
}
os_ << "= " << b.valreg;

if ((uint32_t)b.op & (uint32_t)AtomicOp::INST_ATOMIC_FETCH) {
os_ << "; " << b.valreg << " = ";
print(b.access);
if (showfetch && ((uint32_t)b.op & (uint32_t)AtomicOp::INST_ATOMIC_FETCH)) {
os_ << " fetch";
}
}

Expand Down
6 changes: 4 additions & 2 deletions src/asm_parse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ using crab::linear_expression_t;
#define ASSIGN R"_(\s*=\s*)_"
#define LONGLONG R"_(\s*(ll|)\s*)_"
#define UNOP R"_((-|be16|be32|be64|le16|le32|le64|swap16|swap32|swap64))_"
#define ATOMICOP R"_((\+|\||&|\^)=)_"
#define ATOMICOP R"_((\+|\||&|\^|x|cx)=)_"

#define PLUSMINUS R"_((\s*[+-])\s*)_"
#define LPAREN R"_(\s*\(\s*)_"
Expand Down Expand Up @@ -85,7 +85,9 @@ static const std::map<std::string, Condition::Op> str_to_cmpop = {
static const std::map<std::string, AtomicOp> str_to_atomicop = {{"+", AtomicOp::INST_ATOMIC_ADD},
{"|", AtomicOp::INST_ATOMIC_OR},
{"&", AtomicOp::INST_ATOMIC_AND},
{"^", AtomicOp::INST_ATOMIC_XOR}};
{"^", AtomicOp::INST_ATOMIC_XOR},
{"x", AtomicOp::INST_ATOMIC_XCHG},
{"cx", AtomicOp::INST_ATOMIC_CMPXCHG}};

static const std::map<std::string, AtomicOp> str_to_atomicfetchop = {{"+", AtomicOp::INST_ATOMIC_ADD_FETCH},
{"|", AtomicOp::INST_ATOMIC_OR_FETCH},
Expand Down
3 changes: 2 additions & 1 deletion src/crab/ebpf_domain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2130,7 +2130,8 @@ void ebpf_domain_t::operator()(const Atomic& a) {
case AtomicOp::INST_ATOMIC_OR: bin.op = Bin::Op::OR; break;
case AtomicOp::INST_ATOMIC_AND: bin.op = Bin::Op::AND; break;
case AtomicOp::INST_ATOMIC_XOR: bin.op = Bin::Op::XOR; break;
default:
case AtomicOp::INST_ATOMIC_XCHG_BASE: bin.op = Bin::Op::MOV; break;
case AtomicOp::INST_ATOMIC_CMPXCHG_BASE:
// TODO: handle other instructions.
m_inv.set_to_bottom(); return;
}
Expand Down
4 changes: 2 additions & 2 deletions src/ebpf_vm_isa.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,10 @@ enum class AtomicOp {
INST_ATOMIC_XOR = 0xa0,
INST_ATOMIC_XOR_FETCH = (INST_ATOMIC_XOR | INST_ATOMIC_FETCH),
INST_ATOMIC_XCHG_BASE = 0xe0, // Not valid by itself
INST_ATOMIX_CMPXCHG_BASE = 0xf0, // Not valid by itself
INST_ATOMIC_CMPXCHG_BASE = 0xf0, // Not valid by itself

INST_ATOMIC_XCHG = (INST_ATOMIC_XCHG_BASE | INST_ATOMIC_FETCH),
INST_ATOMIC_CMPXCHG = (INST_ATOMIX_CMPXCHG_BASE | INST_ATOMIC_FETCH),
INST_ATOMIC_CMPXCHG = (INST_ATOMIC_CMPXCHG_BASE | INST_ATOMIC_FETCH),
};

int opcode_to_width(uint8_t opcode);
Expand Down
24 changes: 24 additions & 0 deletions test-data/atomic.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,27 @@ code:
post: ["r1.type=number",
"r2.type=shared", "r2.shared_region_size=16", "r2.shared_offset=4", "r2.svalue=[1, 2147418112]", "r2.uvalue=[1, 2147418112]", "r2.svalue=r2.uvalue"]
---
test-case: atomic 32-bit XCHG

pre: ["r1.type=number", "r1.svalue=2", "r1.uvalue=2",
"r2.type=shared", "r2.shared_region_size=12", "r2.shared_offset=4", "r2.svalue=[1, 2147418112]", "r2.uvalue=[1, 2147418112]", "r2.svalue=r2.uvalue"]

code:
<start>: |
lock *(u32 *)(r2 + 4) x= r1
post: ["r1.type=number",
"r2.type=shared", "r2.shared_region_size=12", "r2.shared_offset=4", "r2.svalue=[1, 2147418112]", "r2.uvalue=[1, 2147418112]", "r2.svalue=r2.uvalue"]
---
test-case: atomic 64-bit XCHG

pre: ["r1.type=number", "r1.svalue=2", "r1.uvalue=2",
"r2.type=shared", "r2.shared_region_size=16", "r2.shared_offset=4", "r2.svalue=[1, 2147418112]", "r2.uvalue=[1, 2147418112]", "r2.svalue=r2.uvalue"]

code:
<start>: |
lock *(u64 *)(r2 + 4) x= r1
post: ["r1.type=number",
"r2.type=shared", "r2.shared_region_size=16", "r2.shared_offset=4", "r2.svalue=[1, 2147418112]", "r2.uvalue=[1, 2147418112]", "r2.svalue=r2.uvalue"]

0 comments on commit 7f11e03

Please sign in to comment.