Commit e4289e23 by Karl Schimpf

Fix ARM integrated assembler to be able to compile spec2k examples.

Fixes a couple of bugs that stopped the ARM integrated assembler from generating assembly code for any spec2k examples. Fixes are: 1) Handle conditional branches with no else branch. 2) Fix usage of fixups so that the emit method does any needed buffer lookups. This fixes case where textual fixups (with zero length) appear at the end of the assembly file. BUG= https://code.google.com/p/nativeclient/issues/detail?id=4334 R=stichnot@chromium.org Review URL: https://codereview.chromium.org/1417173003 .
parent db098880
......@@ -144,13 +144,7 @@ void Assembler::emitIASBytes() const {
Str.write_hex(Buffer.load<uint8_t>(i));
Str << "\n";
}
// For PCRel fixups, we write the pc-offset from a symbol into the Buffer
// (e.g., -4), but we don't represent that in the fixup's offset. Otherwise
// the fixup holds the true offset, and so does the Buffer. Just load the
// offset from the buffer.
CurPosition = NextFixupLoc +
NextFixup->emit(Ctx, Buffer.load<RelocOffsetT>(NextFixupLoc),
fixupIsPCRel(NextFixup->kind()));
CurPosition = NextFixupLoc + NextFixup->emit(Ctx, *this);
assert(CurPosition <= EndPosition);
}
// Handle any bytes that are not prefixed by a fixup.
......
......@@ -284,9 +284,14 @@ public:
virtual bool fixupIsPCRel(FixupKind Kind) const = 0;
// Return a view of all the bytes of code for the current function.
/// Return a view of all the bytes of code for the current function.
llvm::StringRef getBufferView() const;
/// Return the value of the given type in the corresponding buffer.
template <typename T> T load(intptr_t Position) const {
return Buffer.load<T>(Position);
}
/// Emit a fixup at the current location.
void emitFixup(AssemblerFixup *Fixup) { Buffer.emitFixup(Fixup); }
......
......@@ -48,8 +48,7 @@ IceString AssemblerFixup::symbol(const GlobalContext *Ctx) const {
return Str.str();
}
size_t AssemblerFixup::emit(GlobalContext *Ctx, RelocOffsetT OverrideOffset,
bool IsPCRel) const {
size_t AssemblerFixup::emit(GlobalContext *Ctx, const Assembler &Asm) const {
static constexpr const size_t FixupSize = 4;
if (!BuildDefs::dump())
return FixupSize;
......@@ -59,23 +58,20 @@ size_t AssemblerFixup::emit(GlobalContext *Ctx, RelocOffsetT OverrideOffset,
Str << "__Sz_AbsoluteZero";
else
Str << symbol(Ctx);
RelocOffsetT Offset = OverrideOffset;
RelocOffsetT Offset = Asm.load<RelocOffsetT>(position());
if (Offset)
Str << " + " << Offset;
// For PCRel fixups, we write the pc-offset from a symbol into the Buffer
// (e.g., -4), but we don't represent that in the fixup's offset. Otherwise
// the fixup holds the true offset, and so does the Buffer. Just load the
// offset from the buffer.
if (IsPCRel)
if (Asm.fixupIsPCRel(kind()))
Str << " - .";
Str << "\n";
return FixupSize;
}
size_t AssemblerTextFixup::emit(GlobalContext *Ctx, RelocOffsetT OverrideOffset,
bool IsPCRel) const {
(void)OverrideOffset;
(void)IsPCRel;
size_t AssemblerTextFixup::emit(GlobalContext *Ctx, const Assembler &) const {
Ctx->getStrEmit() << Message << "\n";
return NumBytes;
}
......
......@@ -46,8 +46,7 @@ public:
void set_value(const Constant *Value) { value_ = Value; }
/// Emits fixup, then returns the number of bytes to skip.
virtual size_t emit(GlobalContext *Ctx, RelocOffsetT OverrideOffset,
bool IsPCRel) const;
virtual size_t emit(GlobalContext *Ctx, const Assembler &Asm) const;
private:
intptr_t position_ = 0;
......@@ -67,8 +66,7 @@ public:
AssemblerTextFixup(const std::string &Message, size_t NumBytes)
: AssemblerFixup(), Message(Message), NumBytes(NumBytes) {}
~AssemblerTextFixup() = default;
virtual size_t emit(GlobalContext *Ctx, RelocOffsetT OverrideOffset,
bool isPcRel) const;
size_t emit(GlobalContext *Ctx, const Assembler &Asm) const override;
private:
const std::string Message;
......
......@@ -689,7 +689,6 @@ void InstARM32Mov::emit(const Cfg *Func) const {
}
void InstARM32Mov::emitIAS(const Cfg *Func) const {
assert(getSrcSize() == 1);
(void)Func;
assert(!(isMultiDest() && isMultiSource()) && "Invalid vmov type.");
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
......@@ -752,8 +751,8 @@ void InstARM32Br::emitIAS(const Cfg *Func) const {
} else {
Asm->b(Asm->getOrCreateCfgNodeLabel(getTargetTrue()->getIndex()),
getPredicate());
Asm->b(Asm->getOrCreateCfgNodeLabel(getTargetFalse()->getIndex()),
CondARM32::AL);
if (const CfgNode *False = getTargetFalse())
Asm->b(Asm->getOrCreateCfgNodeLabel(False->getIndex()), CondARM32::AL);
}
if (Asm->needsTextFixup())
emitUsingTextFixup(Func);
......
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