Commit 28690715 authored by binji's avatar binji Committed by Commit bot

[Atomics] Add dmb/dsb/isb instructions to ARM

This is not currently implemented in the simulator, just the assembler and
disassembler.

BUG=v8:4614
LOG=y

Review URL: https://codereview.chromium.org/1699173003

Cr-Commit-Position: refs/heads/master@{#34093}
parent 44823c3c
......@@ -2145,6 +2145,21 @@ void Assembler::svc(uint32_t imm24, Condition cond) {
}
void Assembler::dmb(BarrierOption option) {
emit(kSpecialCondition | 0x57ff*B12 | 5*B4 | option);
}
void Assembler::dsb(BarrierOption option) {
emit(kSpecialCondition | 0x57ff*B12 | 4*B4 | option);
}
void Assembler::isb(BarrierOption option) {
emit(kSpecialCondition | 0x57ff*B12 | 6*B4 | option);
}
// Coprocessor instructions.
void Assembler::cdp(Coprocessor coproc,
int opcode_1,
......
......@@ -990,6 +990,11 @@ class Assembler : public AssemblerBase {
void bkpt(uint32_t imm16); // v5 and above
void svc(uint32_t imm24, Condition cond = al);
// Synchronization instructions
void dmb(BarrierOption option);
void dsb(BarrierOption option);
void isb(BarrierOption option);
// Coprocessor instructions
void cdp(Coprocessor coproc, int opcode_1,
......
......@@ -219,6 +219,22 @@ enum {
};
enum BarrierOption {
OSHLD = 0x1,
OSHST = 0x2,
OSH = 0x3,
NSHLD = 0x5,
NSHST = 0x6,
NSH = 0x7,
ISHLD = 0x9,
ISHST = 0xa,
ISH = 0xb,
LD = 0xd,
ST = 0xe,
SY = 0xf,
};
// -----------------------------------------------------------------------------
// Addressing modes and instruction variants.
......
......@@ -1695,6 +1695,12 @@ void Decoder::DecodeType6CoprocessorIns(Instruction* instr) {
}
static const char* const barrier_option_names[] = {
"invalid", "oshld", "oshst", "osh", "invalid", "nshld", "nshst", "nsh",
"invalid", "ishld", "ishst", "ish", "invalid", "ld", "st", "sy",
};
void Decoder::DecodeSpecialCondition(Instruction* instr) {
switch (instr->SpecialValue()) {
case 5:
......@@ -1771,6 +1777,24 @@ void Decoder::DecodeSpecialCondition(Instruction* instr) {
out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
"pld [r%d, #+%d]", Rn, offset);
}
} else if (instr->SpecialValue() == 0xA && instr->Bits(22, 20) == 7) {
int option = instr->Bits(3, 0);
switch (instr->Bits(7, 4)) {
case 4:
out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
"dsb %s", barrier_option_names[option]);
break;
case 5:
out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
"dmb %s", barrier_option_names[option]);
break;
case 6:
out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
"isb %s", barrier_option_names[option]);
break;
default:
Unknown(instr);
}
} else {
Unknown(instr);
}
......
......@@ -3912,6 +3912,9 @@ void Simulator::DecodeSpecialCondition(Instruction* instr) {
case 0xB:
if ((instr->Bits(22, 20) == 5) && (instr->Bits(15, 12) == 0xf)) {
// pld: ignore instruction.
} else if (instr->SpecialValue() == 0xA && instr->Bits(22, 20) == 7) {
// dsb, dmb, isb: ignore instruction for now.
// TODO(binji): implement
} else {
UNIMPLEMENTED();
}
......
......@@ -1031,3 +1031,45 @@ TEST(LoadStore) {
VERIFY_RUN();
}
TEST(Barrier) {
SET_UP();
if (CpuFeatures::IsSupported(ARMv7)) {
CpuFeatureScope scope(&assm, ARMv7);
COMPARE(dmb(OSHLD),
"f57ff051 dmb oshld");
COMPARE(dmb(OSHST),
"f57ff052 dmb oshst");
COMPARE(dmb(OSH),
"f57ff053 dmb osh");
COMPARE(dmb(NSHLD),
"f57ff055 dmb nshld");
COMPARE(dmb(NSHST),
"f57ff056 dmb nshst");
COMPARE(dmb(NSH),
"f57ff057 dmb nsh");
COMPARE(dmb(ISHLD),
"f57ff059 dmb ishld");
COMPARE(dmb(ISHST),
"f57ff05a dmb ishst");
COMPARE(dmb(ISH),
"f57ff05b dmb ish");
COMPARE(dmb(LD),
"f57ff05d dmb ld");
COMPARE(dmb(ST),
"f57ff05e dmb st");
COMPARE(dmb(SY),
"f57ff05f dmb sy");
COMPARE(dsb(ISH),
"f57ff04b dsb ish");
COMPARE(isb(ISH),
"f57ff06b isb ish");
}
VERIFY_RUN();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment