Bug 1230005: Hide specifics of the LDR instruction; r=jolesen

--HG--
extra : commitid : 9ZRpi8bN8fE
extra : rebase_source : 0c3fa8f441a3857714ea005504ebba0928fbbb50
extra : histedit_source : b3ede24e43775e2416c1bb5d4f4cfd17b79cb2f1%2C2a24f2b472d879c2724f1889f0650022780fc28d
This commit is contained in:
Benjamin Bouvier 2015-12-24 11:28:16 +01:00
Родитель bcfe875382
Коммит c15a416116
2 изменённых файлов: 27 добавлений и 34 удалений

Просмотреть файл

@ -751,20 +751,8 @@ Assembler::GetCF32Target(Iter* iter)
return dest; return dest;
} }
if (inst1->is<InstLDR>()) { if (inst1->is<InstLDR>())
InstLDR* load = inst1->as<InstLDR>(); return *(uint32_t**) inst1->as<InstLDR>()->dest();
uint32_t inst = load->encode();
// Get the address of the instruction as a raw pointer.
char* dataInst = reinterpret_cast<char*>(load);
IsUp_ iu = IsUp_(inst & IsUp);
int32_t offset = inst & 0xfff;
if (iu != IsUp) {
offset = - offset;
}
uint32_t** ptr = (uint32_t**)&dataInst[offset + 8];
return *ptr;
}
MOZ_CRASH("unsupported branch relocation"); MOZ_CRASH("unsupported branch relocation");
} }
@ -785,6 +773,9 @@ Assembler::GetPtr32Target(Iter* start, Register* dest, RelocStyle* style)
Instruction* load2 = start->next(); Instruction* load2 = start->next();
if (load1->is<InstMovW>() && load2->is<InstMovT>()) { if (load1->is<InstMovW>() && load2->is<InstMovT>()) {
if (style)
*style = L_MOVWT;
// See if we have the complex case: // See if we have the complex case:
// movw r_temp, #imm1 // movw r_temp, #imm1
// movt r_temp, #imm2 // movt r_temp, #imm2
@ -807,27 +798,17 @@ Assembler::GetPtr32Target(Iter* start, Register* dest, RelocStyle* style)
if (dest) if (dest)
*dest = temp; *dest = temp;
if (style)
*style = L_MOVWT;
uint32_t* value = (uint32_t*) (targ_bot.decode() | (targ_top.decode() << 16)); uint32_t* value = (uint32_t*) (targ_bot.decode() | (targ_top.decode() << 16));
return value; return value;
} }
if (load1->is<InstLDR>()) { if (load1->is<InstLDR>()) {
InstLDR* load = load1->as<InstLDR>();
uint32_t inst = load->encode();
// Get the address of the instruction as a raw pointer.
char* dataInst = reinterpret_cast<char*>(load);
IsUp_ iu = IsUp_(inst & IsUp);
int32_t offset = inst & 0xfff;
if (iu == IsDown)
offset = - offset;
if (dest)
*dest = toRD(*load);
if (style) if (style)
*style = L_LDR; *style = L_LDR;
uint32_t** ptr = (uint32_t**)&dataInst[offset + 8]; if (dest)
return *ptr; *dest = toRD(*load1);
return *(uint32_t**) load1->as<InstLDR>()->dest();
} }
MOZ_CRASH("unsupported relocation"); MOZ_CRASH("unsupported relocation");
@ -2127,12 +2108,7 @@ Assembler::as_Imm32Pool(Register dest, uint32_t value, Condition c)
Assembler::WritePoolEntry(Instruction* addr, Condition c, uint32_t data) Assembler::WritePoolEntry(Instruction* addr, Condition c, uint32_t data)
{ {
MOZ_ASSERT(addr->is<InstLDR>()); MOZ_ASSERT(addr->is<InstLDR>());
int32_t offset = addr->encode() & 0xfff; *addr->as<InstLDR>()->dest() = data;
if ((addr->encode() & IsUp) != IsUp)
offset = -offset;
char * rawAddr = reinterpret_cast<char*>(addr);
uint32_t * dest = reinterpret_cast<uint32_t*>(&rawAddr[offset + 8]);
*dest = data;
MOZ_ASSERT(addr->extractCond() == c); MOZ_ASSERT(addr->extractCond() == c);
} }

Просмотреть файл

@ -2017,6 +2017,23 @@ class InstLDR : public InstDTR
static bool IsTHIS(const Instruction& i); static bool IsTHIS(const Instruction& i);
static InstLDR* AsTHIS(const Instruction& i); static InstLDR* AsTHIS(const Instruction& i);
int32_t signedOffset() const {
int32_t offset = encode() & 0xfff;
if (IsUp_(encode() & IsUp) != IsUp)
return -offset;
return offset;
}
uint32_t* dest() const {
int32_t offset = signedOffset();
// When patching the load in PatchConstantPoolLoad, we ensure that the
// offset is a multiple of 4, offset by 8 bytes from the actual
// location. Indeed, when the base register is PC, ARM's 3 stages
// pipeline design makes it that PC is off by 8 bytes (= 2 *
// sizeof(uint32*)) when we actually executed it.
MOZ_ASSERT(offset % 4 == 0);
offset >>= 2;
return (uint32_t*)raw() + offset + 2;
}
}; };
JS_STATIC_ASSERT(sizeof(InstDTR) == sizeof(InstLDR)); JS_STATIC_ASSERT(sizeof(InstDTR) == sizeof(InstLDR));