Commit 4d0ea36c authored by binji's avatar binji Committed by Commit bot

Add ldrex and strex instructions to ARM assembler/disassmbler

R=jarin@chromium.org,bmeurer@chromium.org

Review-Url: https://codereview.chromium.org/1993033002
Cr-Commit-Position: refs/heads/master@{#36380}
parent 67d393a3
......@@ -2073,6 +2073,53 @@ void Assembler::strd(Register src1, Register src2,
addrmod3(cond | B7 | B6 | B5 | B4, src1, dst);
}
// Load/Store exclusive instructions.
void Assembler::ldrex(Register dst, Register src, Condition cond) {
// Instruction details available in ARM DDI 0406C.b, A8.8.75.
// cond(31-28) | 00011001(27-20) | Rn(19-16) | Rt(15-12) | 111110011111(11-0)
emit(cond | B24 | B23 | B20 | src.code() * B16 | dst.code() * B12 | 0xf9f);
}
void Assembler::strex(Register src1, Register src2, Register dst,
Condition cond) {
// Instruction details available in ARM DDI 0406C.b, A8.8.212.
// cond(31-28) | 00011000(27-20) | Rn(19-16) | Rd(15-12) | 11111001(11-4) |
// Rt(3-0)
emit(cond | B24 | B23 | dst.code() * B16 | src1.code() * B12 | 0xf9 * B4 |
src2.code());
}
void Assembler::ldrexb(Register dst, Register src, Condition cond) {
// Instruction details available in ARM DDI 0406C.b, A8.8.76.
// cond(31-28) | 00011101(27-20) | Rn(19-16) | Rt(15-12) | 111110011111(11-0)
emit(cond | B24 | B23 | B22 | B20 | src.code() * B16 | dst.code() * B12 |
0xf9f);
}
void Assembler::strexb(Register src1, Register src2, Register dst,
Condition cond) {
// Instruction details available in ARM DDI 0406C.b, A8.8.213.
// cond(31-28) | 00011100(27-20) | Rn(19-16) | Rd(15-12) | 11111001(11-4) |
// Rt(3-0)
emit(cond | B24 | B23 | B22 | dst.code() * B16 | src1.code() * B12 |
0xf9 * B4 | src2.code());
}
void Assembler::ldrexh(Register dst, Register src, Condition cond) {
// Instruction details available in ARM DDI 0406C.b, A8.8.78.
// cond(31-28) | 00011111(27-20) | Rn(19-16) | Rt(15-12) | 111110011111(11-0)
emit(cond | B24 | B23 | B22 | B21 | B20 | src.code() * B16 |
dst.code() * B12 | 0xf9f);
}
void Assembler::strexh(Register src1, Register src2, Register dst,
Condition cond) {
// Instruction details available in ARM DDI 0406C.b, A8.8.215.
// cond(31-28) | 00011110(27-20) | Rn(19-16) | Rd(15-12) | 11111001(11-4) |
// Rt(3-0)
emit(cond | B24 | B23 | B22 | B21 | dst.code() * B16 | src1.code() * B12 |
0xf9 * B4 | src2.code());
}
// Preload instructions.
void Assembler::pld(const MemOperand& address) {
......
......@@ -986,6 +986,14 @@ class Assembler : public AssemblerBase {
Register src2,
const MemOperand& dst, Condition cond = al);
// Load/Store exclusive instructions
void ldrex(Register dst, Register src, Condition cond = al);
void strex(Register src1, Register src2, Register dst, Condition cond = al);
void ldrexb(Register dst, Register src, Condition cond = al);
void strexb(Register src1, Register src2, Register dst, Condition cond = al);
void ldrexh(Register dst, Register src, Condition cond = al);
void strexh(Register src1, Register src2, Register dst, Condition cond = al);
// Preload instructions
void pld(const MemOperand& address);
......
......@@ -755,7 +755,45 @@ void Decoder::DecodeType01(Instruction* instr) {
Format(instr, "'um'al'cond's 'rd, 'rn, 'rm, 'rs");
}
} else {
Unknown(instr); // not used by V8
if (instr->Bits(24, 23) == 3) {
if (instr->Bit(20) == 1) {
// ldrex
switch (instr->Bits(22, 21)) {
case 0:
Format(instr, "ldrex'cond 'rt, ['rn]");
break;
case 2:
Format(instr, "ldrexb'cond 'rt, ['rn]");
break;
case 3:
Format(instr, "ldrexh'cond 'rt, ['rn]");
break;
default:
UNREACHABLE();
break;
}
} else {
// strex
// The instruction is documented as strex rd, rt, [rn], but the
// "rt" register is using the rm bits.
switch (instr->Bits(22, 21)) {
case 0:
Format(instr, "strex'cond 'rd, 'rm, ['rn]");
break;
case 2:
Format(instr, "strexb'cond 'rd, 'rm, ['rn]");
break;
case 3:
Format(instr, "strexh'cond 'rd, 'rm, ['rn]");
break;
default:
UNREACHABLE();
break;
}
}
} else {
Unknown(instr); // not used by V8
}
}
} else if ((instr->Bit(20) == 0) && ((instr->Bits(7, 4) & 0xd) == 0xd)) {
// ldrd, strd
......
......@@ -1171,3 +1171,17 @@ TEST(Barrier) {
VERIFY_RUN();
}
TEST(LoadStoreExclusive) {
SET_UP();
COMPARE(ldrexb(r0, r1), "e1d10f9f ldrexb r0, [r1]");
COMPARE(strexb(r0, r1, r2), "e1c20f91 strexb r0, r1, [r2]");
COMPARE(ldrexh(r0, r1), "e1f10f9f ldrexh r0, [r1]");
COMPARE(strexh(r0, r1, r2), "e1e20f91 strexh r0, r1, [r2]");
COMPARE(ldrex(r0, r1), "e1910f9f ldrex r0, [r1]");
COMPARE(strex(r0, r1, r2), "e1820f91 strex r0, r1, [r2]");
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