Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Unified Diff: src/arm/assembler-arm.cc

Issue 23536056: Thumb2 Backend: Enable Assembler to encode Thumb2 instructions Base URL: HEAD^
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/arm/assembler-thumb.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/assembler-arm.cc
diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc
index fc33b660011afc7731c5136a4d9a7720bd96353f..2b6f416e8506f6d312c108901ebdd10d4fe8402b 100644
--- a/src/arm/assembler-arm.cc
+++ b/src/arm/assembler-arm.cc
@@ -510,11 +510,14 @@ const Instr kLdrStrInstrTypeMask = 0xffff0000;
const Instr kLdrStrInstrArgumentMask = 0x0000ffff;
const Instr kLdrStrOffsetMask = 0x00000fff;
+const Instr kThumbLdrPCMask = BH15 | 7 * BH12 | 15 * BH8 | 7 * BH4 | 15 * BH0;
+const Instr kThumbLdrPCPattern = BH15 | 7 * BH12 | BH11 | BH6 | BH4 | 15 * BH0;
Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
: AssemblerBase(isolate, buffer, buffer_size),
recorded_ast_id_(TypeFeedbackId::None()),
- positions_recorder_(this) {
+ positions_recorder_(this),
+ thumb_mode_(false) {
reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
num_pending_reloc_info_ = 0;
num_pending_64_bit_reloc_info_ = 0;
@@ -775,6 +778,10 @@ int Assembler::GetCmpImmediateRawImmediate(Instr instr) {
int Assembler::target_at(int pos) {
+ if (is_thumb_mode()) {
+ return target_at_thumb(pos);
+ }
+
Instr instr = instr_at(pos);
if (is_uint24(instr)) {
// Emitted link to a label, not part of a branch.
@@ -792,6 +799,11 @@ int Assembler::target_at(int pos) {
void Assembler::target_at_put(int pos, int target_pos) {
+ if (is_thumb_mode()) {
+ target_at_put_thumb(pos, target_pos);
+ return;
+ }
+
Instr instr = instr_at(pos);
if (is_uint24(instr)) {
ASSERT(target_pos == pos || target_pos >= 0);
@@ -1313,12 +1325,20 @@ int Assembler::branch_offset(Label* L, bool jump_elimination_allowed) {
// Block the emission of the constant pool, since the branch instruction must
// be emitted at the pc offset recorded by the label.
BlockConstPoolFor(1);
+ if (is_thumb_mode()) {
+ return target_pos - (pc_offset() + kThumbPcLoadDelta);
+ }
return target_pos - (pc_offset() + kPcLoadDelta);
}
// Branch instructions.
void Assembler::b(int branch_offset, Condition cond) {
+ if (is_thumb_mode()) {
+ ASSERT((branch_offset & 1) == 0);
+ b_thumb(branch_offset, cond);
+ return;
+ }
ASSERT((branch_offset & 3) == 0);
int imm24 = branch_offset >> 2;
ASSERT(is_int24(imm24));
@@ -1333,6 +1353,13 @@ void Assembler::b(int branch_offset, Condition cond) {
void Assembler::bl(int branch_offset, Condition cond) {
positions_recorder()->WriteRecordedPositions();
+ if (is_thumb_mode()) {
+ ASSERT(cond == al);
+ ASSERT((branch_offset & 1) == 0);
+ int imm = branch_offset >> 1;
+ emit32(thumb32_mode4(BL_32_IMM) | thumb32_sign_extend_imm24(imm));
+ return;
+ }
ASSERT((branch_offset & 3) == 0);
int imm24 = branch_offset >> 2;
ASSERT(is_int24(imm24));
@@ -1342,6 +1369,12 @@ void Assembler::bl(int branch_offset, Condition cond) {
void Assembler::blx(int branch_offset) { // v5 and above
positions_recorder()->WriteRecordedPositions();
+ if (is_thumb_mode()) {
+ ASSERT((branch_offset & 3) == 0);
+ int imm = branch_offset >> 1;
+ emit32(thumb32_mode4(BLX_32_IMM) | thumb32_sign_extend_imm24(imm));
+ return;
+ }
ASSERT((branch_offset & 1) == 0);
int h = ((branch_offset & 2) >> 1)*B24;
int imm24 = branch_offset >> 2;
@@ -1353,6 +1386,11 @@ void Assembler::blx(int branch_offset) { // v5 and above
void Assembler::blx(Register target, Condition cond) { // v5 and above
positions_recorder()->WriteRecordedPositions();
ASSERT(!target.is(pc));
+ if (is_thumb_mode()) {
+ ASSERT(cond == al);
+ emit16(thumb16_mode3(BLX_REG) | thumb16_anyreg_encoding(target));
+ return;
+ }
emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | BLX | target.code());
}
@@ -1360,6 +1398,11 @@ void Assembler::blx(Register target, Condition cond) { // v5 and above
void Assembler::bx(Register target, Condition cond) { // v5 and above, plus v4t
positions_recorder()->WriteRecordedPositions();
ASSERT(!target.is(pc)); // use of pc is actually allowed, but discouraged
+ if (is_thumb_mode()) {
+ ASSERT(cond == al);
+ emit16(thumb16_mode3(BX_REG) | thumb16_anyreg_encoding(target));
+ return;
+ }
emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | BX | target.code());
}
@@ -1368,42 +1411,70 @@ void Assembler::bx(Register target, Condition cond) { // v5 and above, plus v4t
void Assembler::and_(Register dst, Register src1, const Operand& src2,
SBit s, Condition cond) {
+ if (is_thumb_mode()) {
+ and_thumb(dst, src1, src2, s, cond);
+ return;
+ }
addrmod1(cond | AND | s, src1, dst, src2);
}
void Assembler::eor(Register dst, Register src1, const Operand& src2,
SBit s, Condition cond) {
+ if (is_thumb_mode()) {
+ eor_thumb(dst, src1, src2, s, cond);
+ return;
+ }
addrmod1(cond | EOR | s, src1, dst, src2);
}
void Assembler::sub(Register dst, Register src1, const Operand& src2,
SBit s, Condition cond) {
+ if (is_thumb_mode()) {
+ sub_thumb(dst, src1, src2, s, cond);
+ return;
+ }
addrmod1(cond | SUB | s, src1, dst, src2);
}
void Assembler::rsb(Register dst, Register src1, const Operand& src2,
SBit s, Condition cond) {
+ if (is_thumb_mode()) {
+ rsb_thumb(dst, src1, src2, s, cond);
+ return;
+ }
addrmod1(cond | RSB | s, src1, dst, src2);
}
void Assembler::add(Register dst, Register src1, const Operand& src2,
SBit s, Condition cond) {
+ if (is_thumb_mode()) {
+ add_thumb(dst, src1, src2, s, cond);
+ return;
+ }
addrmod1(cond | ADD | s, src1, dst, src2);
}
void Assembler::adc(Register dst, Register src1, const Operand& src2,
SBit s, Condition cond) {
+ if (is_thumb_mode()) {
+ adc_thumb(dst, src1, src2, s, cond);
+ return;
+ }
addrmod1(cond | ADC | s, src1, dst, src2);
}
void Assembler::sbc(Register dst, Register src1, const Operand& src2,
SBit s, Condition cond) {
+ if (is_thumb_mode()) {
+ sbc_thumb(dst, src1, src2, s, cond);
+ return;
+ }
addrmod1(cond | SBC | s, src1, dst, src2);
}
@@ -1415,16 +1486,28 @@ void Assembler::rsc(Register dst, Register src1, const Operand& src2,
void Assembler::tst(Register src1, const Operand& src2, Condition cond) {
+ if (is_thumb_mode()) {
+ tst_thumb(src1, src2, cond);
+ return;
+ }
addrmod1(cond | TST | S, src1, r0, src2);
}
void Assembler::teq(Register src1, const Operand& src2, Condition cond) {
+ if (is_thumb_mode()) {
+ teq_thumb(src1, src2, cond);
+ return;
+ }
addrmod1(cond | TEQ | S, src1, r0, src2);
}
void Assembler::cmp(Register src1, const Operand& src2, Condition cond) {
+ if (is_thumb_mode()) {
+ cmp_thumb(src1, src2, cond);
+ return;
+ }
addrmod1(cond | CMP | S, src1, r0, src2);
}
@@ -1437,12 +1520,20 @@ void Assembler::cmp_raw_immediate(
void Assembler::cmn(Register src1, const Operand& src2, Condition cond) {
+ if (is_thumb_mode()) {
+ cmn_thumb(src1, src2, cond);
+ return;
+ }
addrmod1(cond | CMN | S, src1, r0, src2);
}
void Assembler::orr(Register dst, Register src1, const Operand& src2,
SBit s, Condition cond) {
+ if (is_thumb_mode()) {
+ orr_thumb(dst, src1, src2, s, cond);
+ return;
+ }
addrmod1(cond | ORR | s, src1, dst, src2);
}
@@ -1455,6 +1546,10 @@ void Assembler::mov(Register dst, const Operand& src, SBit s, Condition cond) {
// the mov instruction. They must be generated using nop(int/NopMarkerTypes)
// or MarkCode(int/NopMarkerTypes) pseudo instructions.
ASSERT(!(src.is_reg() && src.rm().is(dst) && s == LeaveCC && cond == al));
+ if (is_thumb_mode()) {
+ mov_thumb(dst, src, s, cond);
+ return;
+ }
addrmod1(cond | MOV | s, r0, dst, src);
}
@@ -1508,17 +1603,29 @@ void Assembler::movw(Register reg, uint32_t immediate, Condition cond) {
void Assembler::movt(Register reg, uint32_t immediate, Condition cond) {
+ if (is_thumb_mode()) {
+ movt_thumb(reg, immediate, cond);
+ return;
+ }
emit(cond | 0x34*B20 | reg.code()*B12 | EncodeMovwImmediate(immediate));
}
void Assembler::bic(Register dst, Register src1, const Operand& src2,
SBit s, Condition cond) {
+ if (is_thumb_mode()) {
+ bic_thumb(dst, src1, src2, s, cond);
+ return;
+ }
addrmod1(cond | BIC | s, src1, dst, src2);
}
void Assembler::mvn(Register dst, const Operand& src, SBit s, Condition cond) {
+ if (is_thumb_mode()) {
+ mvn_thumb(dst, src, s, cond);
+ return;
+ }
addrmod1(cond | MVN | s, r0, dst, src);
}
@@ -1526,6 +1633,10 @@ void Assembler::mvn(Register dst, const Operand& src, SBit s, Condition cond) {
// Multiply instructions.
void Assembler::mla(Register dst, Register src1, Register src2, Register srcA,
SBit s, Condition cond) {
+ if (is_thumb_mode()) {
+ mla_thumb(dst, src1, src2, srcA, s, cond);
+ return;
+ }
ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc) && !srcA.is(pc));
emit(cond | A | s | dst.code()*B16 | srcA.code()*B12 |
src2.code()*B8 | B7 | B4 | src1.code());
@@ -1534,6 +1645,10 @@ void Assembler::mla(Register dst, Register src1, Register src2, Register srcA,
void Assembler::mls(Register dst, Register src1, Register src2, Register srcA,
Condition cond) {
+ if (is_thumb_mode()) {
+ mls_thumb(dst, src1, src2, srcA, cond);
+ return;
+ }
ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc) && !srcA.is(pc));
emit(cond | B22 | B21 | dst.code()*B16 | srcA.code()*B12 |
src2.code()*B8 | B7 | B4 | src1.code());
@@ -1542,6 +1657,10 @@ void Assembler::mls(Register dst, Register src1, Register src2, Register srcA,
void Assembler::sdiv(Register dst, Register src1, Register src2,
Condition cond) {
+ if (is_thumb_mode()) {
+ sdiv_thumb(dst, src1, src2, cond);
+ return;
+ }
ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
ASSERT(IsEnabled(SUDIV));
emit(cond | B26 | B25| B24 | B20 | dst.code()*B16 | 0xf * B12 |
@@ -1552,6 +1671,10 @@ void Assembler::sdiv(Register dst, Register src1, Register src2,
void Assembler::mul(Register dst, Register src1, Register src2,
SBit s, Condition cond) {
ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
+ if (is_thumb_mode()) {
+ mul_thumb(dst, src1, src2, s, cond);
+ return;
+ }
// dst goes in bits 16-19 for this instruction!
emit(cond | s | dst.code()*B16 | src2.code()*B8 | B7 | B4 | src1.code());
}
@@ -1563,6 +1686,10 @@ void Assembler::smlal(Register dstL,
Register src2,
SBit s,
Condition cond) {
+ if (is_thumb_mode()) {
+ smlal_thumb(dstL, dstH, src1, src2, s, cond);
+ return;
+ }
ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
ASSERT(!dstL.is(dstH));
emit(cond | B23 | B22 | A | s | dstH.code()*B16 | dstL.code()*B12 |
@@ -1576,6 +1703,10 @@ void Assembler::smull(Register dstL,
Register src2,
SBit s,
Condition cond) {
+ if (is_thumb_mode()) {
+ smull_thumb(dstL, dstH, src1, src2, s, cond);
+ return;
+ }
ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
ASSERT(!dstL.is(dstH));
emit(cond | B23 | B22 | s | dstH.code()*B16 | dstL.code()*B12 |
@@ -1589,6 +1720,10 @@ void Assembler::umlal(Register dstL,
Register src2,
SBit s,
Condition cond) {
+ if (is_thumb_mode()) {
+ umlal_thumb(dstL, dstH, src1, src2, s, cond);
+ return;
+ }
ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
ASSERT(!dstL.is(dstH));
emit(cond | B23 | A | s | dstH.code()*B16 | dstL.code()*B12 |
@@ -1602,6 +1737,10 @@ void Assembler::umull(Register dstL,
Register src2,
SBit s,
Condition cond) {
+ if (is_thumb_mode()) {
+ umull_thumb(dstL, dstH, src1, src2, s, cond);
+ return;
+ }
ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc));
ASSERT(!dstL.is(dstH));
emit(cond | B23 | s | dstH.code()*B16 | dstL.code()*B12 |
@@ -1613,6 +1752,14 @@ void Assembler::umull(Register dstL,
void Assembler::clz(Register dst, Register src, Condition cond) {
// v5 and above.
ASSERT(!dst.is(pc) && !src.is(pc));
+
+ if (is_thumb_mode()) {
+ ASSERT(cond == al);
+ emit32(BH15 | BH14 | BH13 | BH12 | BH11 | BH9 | BH7 | src.code()*BH0 |
+ B15 | B14 | B13 | B12 | dst.code()*B8 | B7 | src.code());
+ return;
+ }
+
emit(cond | B24 | B22 | B21 | 15*B16 | dst.code()*B12 |
15*B8 | CLZ | src.code());
}
@@ -1637,6 +1784,13 @@ void Assembler::usat(Register dst,
sh = 1;
}
+ if (is_thumb_mode()) {
+ ASSERT(cond == al);
+ emit32(thumb32_mode3(USAT_32_IMM) | sh*BH5 |
+ thumb32_bit_field(src.rm_, dst, src.shift_imm_, satpos));
+ return;
+ }
+
emit(cond | 0x6*B24 | 0xe*B20 | satpos*B16 | dst.code()*B12 |
src.shift_imm_*B7 | sh*B6 | 0x1*B4 | src.rm_.code());
}
@@ -1658,6 +1812,14 @@ void Assembler::ubfx(Register dst,
ASSERT(!dst.is(pc) && !src.is(pc));
ASSERT((lsb >= 0) && (lsb <= 31));
ASSERT((width >= 1) && (width <= (32 - lsb)));
+
+ if (is_thumb_mode()) {
+ ASSERT(cond == al);
+ emit32(thumb32_mode3(UBFX_32_IMM) |
+ thumb32_bit_field(src, dst, lsb, width - 1));
+ return;
+ }
+
emit(cond | 0xf*B23 | B22 | B21 | (width - 1)*B16 | dst.code()*B12 |
lsb*B7 | B6 | B4 | src.code());
}
@@ -1678,6 +1840,14 @@ void Assembler::sbfx(Register dst,
ASSERT(!dst.is(pc) && !src.is(pc));
ASSERT((lsb >= 0) && (lsb <= 31));
ASSERT((width >= 1) && (width <= (32 - lsb)));
+
+ if (is_thumb_mode()) {
+ ASSERT(cond == al);
+ emit32(thumb32_mode3(SBFX_32_IMM) |
+ thumb32_bit_field(src, dst, lsb, width - 1));
+ return;
+ }
+
emit(cond | 0xf*B23 | B21 | (width - 1)*B16 | dst.code()*B12 |
lsb*B7 | B6 | B4 | src.code());
}
@@ -1694,6 +1864,13 @@ void Assembler::bfc(Register dst, int lsb, int width, Condition cond) {
ASSERT((lsb >= 0) && (lsb <= 31));
ASSERT((width >= 1) && (width <= (32 - lsb)));
int msb = lsb + width - 1;
+
+ if (is_thumb_mode()) {
+ ASSERT(cond == al);
+ emit32(thumb32_mode3(BFC_32_IMM) | thumb32_bit_field(pc, dst, lsb, msb));
+ return;
+ }
+
emit(cond | 0x1f*B22 | msb*B16 | dst.code()*B12 | lsb*B7 | B4 | 0xf);
}
@@ -1713,6 +1890,13 @@ void Assembler::bfi(Register dst,
ASSERT((lsb >= 0) && (lsb <= 31));
ASSERT((width >= 1) && (width <= (32 - lsb)));
int msb = lsb + width - 1;
+
+ if (is_thumb_mode()) {
+ ASSERT(cond == al);
+ emit32(thumb32_mode3(BFI_32_IMM) | thumb32_bit_field(src, dst, lsb, msb));
+ return;
+ }
+
emit(cond | 0x1f*B22 | msb*B16 | dst.code()*B12 | lsb*B7 | B4 |
src.code());
}
@@ -1856,41 +2040,82 @@ void Assembler::ldr(Register dst, const MemOperand& src, Condition cond) {
if (dst.is(pc)) {
positions_recorder()->WriteRecordedPositions();
}
+
+ if (is_thumb_mode()) {
+ ldr_thumb(dst, src);
+ return;
+ }
+
addrmod2(cond | B26 | L, dst, src);
}
void Assembler::str(Register src, const MemOperand& dst, Condition cond) {
+ if (is_thumb_mode()) {
+ ASSERT(cond == al);
+ str_thumb(src, dst);
+ return;
+ }
addrmod2(cond | B26, src, dst);
}
void Assembler::ldrb(Register dst, const MemOperand& src, Condition cond) {
+ if (is_thumb_mode()) {
+ ASSERT(cond == al);
+ ldrb_thumb(dst, src);
+ return;
+ }
addrmod2(cond | B26 | B | L, dst, src);
}
void Assembler::strb(Register src, const MemOperand& dst, Condition cond) {
+ if (is_thumb_mode()) {
+ ASSERT(cond == al);
+ strb_thumb(src, dst);
+ return;
+ }
addrmod2(cond | B26 | B, src, dst);
}
void Assembler::ldrh(Register dst, const MemOperand& src, Condition cond) {
+ if (is_thumb_mode()) {
+ ASSERT(cond == al);
+ ldrh_thumb(dst, src);
+ return;
+ }
addrmod3(cond | L | B7 | H | B4, dst, src);
}
void Assembler::strh(Register src, const MemOperand& dst, Condition cond) {
+ if (is_thumb_mode()) {
+ ASSERT(cond == al);
+ strh_thumb(src, dst);
+ return;
+ }
addrmod3(cond | B7 | H | B4, src, dst);
}
void Assembler::ldrsb(Register dst, const MemOperand& src, Condition cond) {
+ if (is_thumb_mode()) {
+ ASSERT(cond == al);
+ ldrsb_thumb(dst, src);
+ return;
+ }
addrmod3(cond | L | B7 | S6 | B4, dst, src);
}
void Assembler::ldrsh(Register dst, const MemOperand& src, Condition cond) {
+ if (is_thumb_mode()) {
+ ASSERT(cond == al);
+ ldrsh_thumb(dst, src);
+ return;
+ }
addrmod3(cond | L | B7 | S6 | H | B4, dst, src);
}
@@ -1901,6 +2126,12 @@ void Assembler::ldrd(Register dst1, Register dst2,
ASSERT(src.rm().is(no_reg));
ASSERT(!dst1.is(lr)); // r14.
ASSERT_EQ(0, dst1.code() % 2);
+ if (is_thumb_mode()) {
+ ASSERT(cond == al);
+ ASSERT(!src.rm_.is_valid()); // Immediate.
+ ldrd_imm_t1(dst1, dst2, src);
+ return;
+ }
ASSERT_EQ(dst1.code() + 1, dst2.code());
addrmod3(cond | B7 | B6 | B4, dst1, src);
}
@@ -1911,8 +2142,14 @@ void Assembler::strd(Register src1, Register src2,
ASSERT(dst.rm().is(no_reg));
ASSERT(!src1.is(lr)); // r14.
ASSERT_EQ(0, src1.code() % 2);
- ASSERT_EQ(src1.code() + 1, src2.code());
ASSERT(IsEnabled(ARMv7));
+ if (is_thumb_mode()) {
+ ASSERT(cond == al);
+ ASSERT(!dst.rm_.is_valid()); // Immediate.
+ strd_imm_t1(src1, src2, dst);
+ return;
+ }
+ ASSERT_EQ(src1.code() + 1, src2.code());
addrmod3(cond | B7 | B6 | B5 | B4, src1, dst);
}
@@ -1943,7 +2180,10 @@ void Assembler::ldm(BlockAddrMode am,
Condition cond) {
// ABI stack constraint: ldmxx base, {..sp..} base != sp is not restartable.
ASSERT(base.is(sp) || (dst & sp.bit()) == 0);
-
+ if (is_thumb_mode()) {
+ ldm_thumb(am, base, dst, cond);
+ return;
+ }
addrmod4(cond | B27 | am | L, base, dst);
// Emit the constant pool after a function return implemented by ldm ..{..pc}.
@@ -1962,6 +2202,10 @@ void Assembler::stm(BlockAddrMode am,
Register base,
RegList src,
Condition cond) {
+ if (is_thumb_mode()) {
+ stm_thumb(am, base, src, cond);
+ return;
+ }
addrmod4(cond | B27 | am, base, src);
}
@@ -1997,6 +2241,11 @@ void Assembler::stop(const char* msg, Condition cond, int32_t code) {
void Assembler::bkpt(uint32_t imm16) { // v5 and above
+ if (is_thumb_mode()) {
+ ASSERT(is_uint8(imm16));
+ emit16(B15 | B13 | B12 | B11 | B10 | B9 | (imm16 & 0xFF));
+ return;
+ }
ASSERT(is_uint16(imm16));
emit(al | B24 | B21 | (imm16 >> 4)*B8 | BKPT | (imm16 & 0xf));
}
@@ -2539,6 +2788,12 @@ void Assembler::vmov(const DwVfpRegister dst,
ASSERT(index.index == 0 || index.index == 1);
int vd, d;
dst.split_code(&vd, &d);
+ if (is_thumb_mode() && cond != al) {
+ it_thumb(cond, 1);
+ emit(al | 0xE*B24 | index.index*B21 | vd*B16 | src.code()*B12 | 0xB*B8 |
+ d*B7 | B4);
+ return;
+ }
emit(cond | 0xE*B24 | index.index*B21 | vd*B16 | src.code()*B12 | 0xB*B8 |
d*B7 | B4);
}
@@ -2816,7 +3071,12 @@ void Assembler::vneg(const DwVfpRegister dst,
dst.split_code(&vd, &d);
int vm, m;
src.split_code(&vm, &m);
-
+ if (is_thumb_mode() && cond != al) {
+ it_thumb(cond, 1);
+ emit(al | 0x1D*B23 | d*B22 | 0x3*B20 | B16 | vd*B12 | 0x5*B9 | B8 | B6 |
+ m*B5 | vm);
+ return;
+ }
emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | B16 | vd*B12 | 0x5*B9 | B8 | B6 |
m*B5 | vm);
}
@@ -3068,6 +3328,11 @@ void Assembler::nop(int type) {
// We therefore use MOV Rx, Rx, even on newer CPUs, and use Rx to encode
// a type.
ASSERT(0 <= type && type <= 14); // mov pc, pc isn't a nop.
+ if (is_thumb_mode()) {
+ uint16_t d = type >> 3;
+ emit16(4*B12 | 6*B8 | d*B7 | type*B3 | (type & 7));
+ return;
+ }
emit(al | 13*B21 | type*B12 | type);
}
@@ -3088,6 +3353,16 @@ bool Assembler::IsMovW(Instr instr) {
}
+bool Assembler::IsMovTThumb(Instr instr) {
+ return ((instr & ~MOVW_THUMB_IMM_MASK) == (MOVW_THUMB_MASK | BH7));
+}
+
+
+bool Assembler::IsMovWThumb(Instr instr) {
+ return ((instr & ~MOVW_THUMB_IMM_MASK) == MOVW_THUMB_MASK);
+}
+
+
bool Assembler::IsNop(Instr instr, int type) {
ASSERT(0 <= type && type <= 14); // mov pc, pc isn't a nop.
// Check for mov rx, rx where x = type.
@@ -3379,8 +3654,13 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
// Put down constant pool marker "Undefined instruction".
// The data size helps disassembly know what to print.
- emit(kConstantPoolMarker |
- EncodeConstantPoolLength(size_after_marker / kPointerSize));
+ if (is_thumb_mode()) {
+ emit32(kConstantPoolMarker |
+ EncodeConstantPoolLength(size_after_marker / kPointerSize));
+ } else {
+ emit(kConstantPoolMarker |
+ EncodeConstantPoolLength(size_after_marker / kPointerSize));
+ }
if (require_64_bit_align) {
emit(kConstantPoolMarker);
@@ -3428,6 +3708,23 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
continue;
}
+ if (is_thumb_mode()) {
+ Instr instr = thumb32_instr_at(rinfo.pc());
+ int thumb_ldr_delta = 2;
+ if ((reinterpret_cast<int>(rinfo.pc()) & 3) == 0) {
+ thumb_ldr_delta = 4;
+ }
+ int delta = pc_ - rinfo.pc() - thumb_ldr_delta;
+ ASSERT(is_uint12(delta));
+ instr &= ~kOff12Mask;
+ instr |= delta;
+ thumb32_instr_at_put(rinfo.pc(), instr);
+ set_arm_mode();
+ emit(rinfo.data());
+ set_thumb_mode();
+ continue;
+ }
+
Instr instr = instr_at(rinfo.pc());
// 64-bit loads shouldn't get here.
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/arm/assembler-thumb.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698