[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:
parent
44823c3c69
commit
2869071588
@ -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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user