[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}
This commit is contained in:
binji 2016-02-17 11:57:18 -08:00 committed by Commit bot
parent 44823c3c69
commit 2869071588
6 changed files with 105 additions and 0 deletions

View File

@ -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. // Coprocessor instructions.
void Assembler::cdp(Coprocessor coproc, void Assembler::cdp(Coprocessor coproc,
int opcode_1, int opcode_1,

View File

@ -990,6 +990,11 @@ class Assembler : public AssemblerBase {
void bkpt(uint32_t imm16); // v5 and above void bkpt(uint32_t imm16); // v5 and above
void svc(uint32_t imm24, Condition cond = al); void svc(uint32_t imm24, Condition cond = al);
// Synchronization instructions
void dmb(BarrierOption option);
void dsb(BarrierOption option);
void isb(BarrierOption option);
// Coprocessor instructions // Coprocessor instructions
void cdp(Coprocessor coproc, int opcode_1, void cdp(Coprocessor coproc, int opcode_1,

View File

@ -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. // Addressing modes and instruction variants.

View File

@ -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) { void Decoder::DecodeSpecialCondition(Instruction* instr) {
switch (instr->SpecialValue()) { switch (instr->SpecialValue()) {
case 5: case 5:
@ -1771,6 +1777,24 @@ void Decoder::DecodeSpecialCondition(Instruction* instr) {
out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
"pld [r%d, #+%d]", Rn, offset); "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 { } else {
Unknown(instr); Unknown(instr);
} }

View File

@ -3912,6 +3912,9 @@ void Simulator::DecodeSpecialCondition(Instruction* instr) {
case 0xB: case 0xB:
if ((instr->Bits(22, 20) == 5) && (instr->Bits(15, 12) == 0xf)) { if ((instr->Bits(22, 20) == 5) && (instr->Bits(15, 12) == 0xf)) {
// pld: ignore instruction. // pld: ignore instruction.
} else if (instr->SpecialValue() == 0xA && instr->Bits(22, 20) == 7) {
// dsb, dmb, isb: ignore instruction for now.
// TODO(binji): implement
} else { } else {
UNIMPLEMENTED(); UNIMPLEMENTED();
} }

View File

@ -1031,3 +1031,45 @@ TEST(LoadStore) {
VERIFY_RUN(); 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();
}