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

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

Issue 1128009: Replace the constant pool access ldr instructions with movw/movt, and remove ... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 8 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
Index: src/arm/assembler-arm.cc
===================================================================
--- src/arm/assembler-arm.cc (revision 4311)
+++ src/arm/assembler-arm.cc (working copy)
@@ -263,6 +263,11 @@
// ldr rd, [pc, #offset]
const Instr kLdrPCMask = CondMask | 15 * B24 | 7 * B20 | 15 * B16;
const Instr kLdrPCPattern = al | 5 * B24 | L | pc.code() * B16;
+const Instr kLdrMask = 15 * B24 | 7 * B20 | 15 * B16;
+const Instr kLdrPattern = 5 * B24 | B20 | 15 * B16;
+const Instr kMovwMovtMask = 15 * B24 | 15 * B20;
+const Instr kMovwPattern = 3 * B24;
+const Instr kMovtPattern = 3 * B24 | 4 * B20;
// blxcc rm
const Instr kBlxRegMask =
15 * B24 | 15 * B20 | 15 * B16 | 15 * B12 | 15 * B8 | 15 * B4;
@@ -564,7 +569,8 @@
void Assembler::addrmod1(Instr instr,
Register rn,
Register rd,
- const Operand& x) {
+ const Operand& x,
+ bool use_movw_movt) {
CheckBuffer();
ASSERT((instr & ~(CondMask | OpCodeMask | S)) == 0);
if (!x.rm_.is_valid()) {
@@ -573,19 +579,30 @@
uint32_t immed_8;
if (MustUseIp(x.rmode_) ||
!fits_shifter(x.imm32_, &rotate_imm, &immed_8, &instr)) {
- // The immediate operand cannot be encoded as a shifter operand, so load
- // it first to register ip and change the original instruction to use ip.
- // However, if the original instruction is a 'mov rd, x' (not setting the
- // condition code), then replace it with a 'ldr rd, [pc]'.
- RecordRelocInfo(x.rmode_, x.imm32_);
- CHECK(!rn.is(ip)); // rn should never be ip, or will be trashed
- Condition cond = static_cast<Condition>(instr & CondMask);
- if ((instr & ~CondMask) == 13*B21) { // mov, S not set
- ldr(rd, MemOperand(pc, 0), cond);
- } else {
- ldr(ip, MemOperand(pc, 0), cond);
- addrmod1(instr, rn, rd, Operand(ip));
- }
+ Condition cond = static_cast<Condition>(instr & CondMask);
+ if (!Serializer::enabled() && CpuFeatures::IsSupported(ARMv7) &&
+ use_movw_movt && (x.rmode_ != RelocInfo::EMBEDDED_OBJECT) &&
+ ((instr & ~CondMask) == 13*B21) &&
+ (x.imm32_ >= 0) && !rd.is(pc)) {
+ RecordRelocInfo(x.rmode_, x.imm32_, false);
+ CHECK(!rn.is(ip)); // rn should never be ip, or will be trashed
+ movw(rd, x, cond);
+ movt(rd, x, cond);
Erik Corry 2010/05/03 10:06:28 In the case of the relocinfo being "None" we don't
+ } else {
+ // The immediate operand cannot be encoded as a shifter operand, so
+ // load it first to register ip and change the original instruction
+ // to use ip.
+ // However, if the original instruction is a 'mov rd, x' (not setting
+ // the condition code), then replace it with a 'ldr rd, [pc]'
+ RecordRelocInfo(x.rmode_, x.imm32_);
+ CHECK(!rn.is(ip)); // rn should never be ip, or will be trashed
+ if ((instr & ~CondMask) == 13*B21) { // mov, S not set
+ ldr(rd, MemOperand(pc, 0), cond);
+ } else {
+ ldr(ip, MemOperand(pc, 0), cond);
Erik Corry 2010/05/03 10:06:28 This code, that handles instructions other than mo
+ addrmod1(instr, rn, rd, Operand(ip));
+ }
+ }
return;
}
instr |= I | rotate_imm*B8 | immed_8;
@@ -898,14 +915,29 @@
}
-void Assembler::mov(Register dst, const Operand& src, SBit s, Condition cond) {
+void Assembler::mov(Register dst, const Operand& src, SBit s,
+ Condition cond, bool use_movw_movt) {
if (dst.is(pc)) {
WriteRecordedPositions();
}
- addrmod1(cond | 13*B21 | s, r0, dst, src);
+ addrmod1(cond | 13*B21 | s, r0, dst, src, use_movw_movt);
}
+void Assembler::movt(Register dst, const Operand& src, Condition cond) {
+ ASSERT(!src.rm_.is_valid());
+ emit(cond | (0x34)*B20 | ((src.imm32_ >> 28) & 15) * B16
+ | dst.code()*B12 | ((src.imm32_ >> 16) & 0xfff));
+}
+
+
+void Assembler::movw(Register dst, const Operand& src, Condition cond) {
+ ASSERT(!src.rm_.is_valid());
+ emit(cond | (0x30)*B20 | ((src.imm32_ >> 12) & 15) * B16
+ | dst.code()*B12 | ((src.imm32_ & 0xfff)));
+}
+
+
void Assembler::bic(Register dst, Register src1, const Operand& src2,
SBit s, Condition cond) {
addrmod1(cond | 14*B21 | s, src1, dst, src2);
@@ -1832,7 +1864,9 @@
}
-void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
+void Assembler::RecordRelocInfo(RelocInfo::Mode rmode,
+ intptr_t data,
+ bool with_const_pool) {
RelocInfo rinfo(pc_, rmode, data); // we do not try to reuse pool constants
if (rmode >= RelocInfo::JS_RETURN && rmode <= RelocInfo::STATEMENT_POSITION) {
// Adjust code for new modes.
@@ -1843,9 +1877,11 @@
} else {
ASSERT(num_prinfo_ < kMaxNumPRInfo);
prinfo_[num_prinfo_++] = rinfo;
- // Make sure the constant pool is not emitted in place of the next
- // instruction for which we just recorded relocation info.
- BlockConstPoolBefore(pc_offset() + kInstrSize);
+ if (with_const_pool) {
+ // Make sure the constant pool is not emitted in place of the next
+ // instruction for which we just recorded relocation info
+ BlockConstPoolBefore(pc_offset() + kInstrSize);
+ }
}
if (rinfo.rmode() != RelocInfo::NONE) {
// Don't record external references unless the heap will be serialized.
@@ -1915,9 +1951,21 @@
jump_instr + kInstrSize + num_prinfo_*(kInstrSize + kMaxRelocSize);
while (buffer_space() <= (max_needed_space + kGap)) GrowBuffer();
+ int block_for_prinfo = num_prinfo_*kInstrSize;
Erik Corry 2010/05/03 10:06:28 There should be spaces around '*'.
+
+ // Movw/movt instructions do not have const pool entries.
+ for (int i = 0; i < num_prinfo_; i++) {
+ RelocInfo& rinfo = prinfo_[i];
+ Instr instr = instr_at(rinfo.pc());
+
+ if (((instr & (7*B25 | P | U | B | W | 15*B16 | Off12Mask)) !=
Erik Corry 2010/05/03 10:06:28 It must be possible to rewrite this with a named m
+ (2*B25 | P | U | pc.code()*B16)))
+ block_for_prinfo -= kInstrSize;
+ }
+
// Block recursive calls to CheckConstPool.
BlockConstPoolBefore(pc_offset() + jump_instr + kInstrSize +
- num_prinfo_*kInstrSize);
+ block_for_prinfo);
// Don't bother to check for the emit calls below.
next_buffer_check_ = no_const_pool_before_;
@@ -1939,6 +1987,11 @@
rinfo.rmode() != RelocInfo::STATEMENT_POSITION);
Instr instr = instr_at(rinfo.pc());
+ // Do not generate const pool entries for movw/movt instructions.
+ if (((instr & (7*B25 | P | U | B | W | 15*B16 | Off12Mask)) !=
Erik Corry 2010/05/03 10:06:28 And this.
+ (2*B25 | P | U | pc.code()*B16)))
+ continue;
Erik Corry 2010/05/03 10:06:28 Use braces on multi-line ifs.
+
// Instruction to patch must be a ldr/str [pc, #offset].
// P and U set, B and W clear, Rn == pc, offset12 still 0.
ASSERT((instr & (7*B25 | P | U | B | W | 15*B16 | Off12Mask)) ==

Powered by Google App Engine
This is Rietveld 408576698