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 { ...@@ -144,13 +144,7 @@ void Assembler::emitIASBytes() const {
Str.write_hex(Buffer.load<uint8_t>(i)); Str.write_hex(Buffer.load<uint8_t>(i));
Str << "\n"; Str << "\n";
} }
// For PCRel fixups, we write the pc-offset from a symbol into the Buffer CurPosition = NextFixupLoc + NextFixup->emit(Ctx, *this);
// (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()));
assert(CurPosition <= EndPosition); assert(CurPosition <= EndPosition);
} }
// Handle any bytes that are not prefixed by a fixup. // Handle any bytes that are not prefixed by a fixup.
......
...@@ -284,9 +284,14 @@ public: ...@@ -284,9 +284,14 @@ public:
virtual bool fixupIsPCRel(FixupKind Kind) const = 0; 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; 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. /// Emit a fixup at the current location.
void emitFixup(AssemblerFixup *Fixup) { Buffer.emitFixup(Fixup); } void emitFixup(AssemblerFixup *Fixup) { Buffer.emitFixup(Fixup); }
......
...@@ -48,8 +48,7 @@ IceString AssemblerFixup::symbol(const GlobalContext *Ctx) const { ...@@ -48,8 +48,7 @@ IceString AssemblerFixup::symbol(const GlobalContext *Ctx) const {
return Str.str(); return Str.str();
} }
size_t AssemblerFixup::emit(GlobalContext *Ctx, RelocOffsetT OverrideOffset, size_t AssemblerFixup::emit(GlobalContext *Ctx, const Assembler &Asm) const {
bool IsPCRel) const {
static constexpr const size_t FixupSize = 4; static constexpr const size_t FixupSize = 4;
if (!BuildDefs::dump()) if (!BuildDefs::dump())
return FixupSize; return FixupSize;
...@@ -59,23 +58,20 @@ size_t AssemblerFixup::emit(GlobalContext *Ctx, RelocOffsetT OverrideOffset, ...@@ -59,23 +58,20 @@ size_t AssemblerFixup::emit(GlobalContext *Ctx, RelocOffsetT OverrideOffset,
Str << "__Sz_AbsoluteZero"; Str << "__Sz_AbsoluteZero";
else else
Str << symbol(Ctx); Str << symbol(Ctx);
RelocOffsetT Offset = OverrideOffset; RelocOffsetT Offset = Asm.load<RelocOffsetT>(position());
if (Offset) if (Offset)
Str << " + " << Offset; Str << " + " << Offset;
// For PCRel fixups, we write the pc-offset from a symbol into the Buffer // 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 // (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 // the fixup holds the true offset, and so does the Buffer. Just load the
// offset from the buffer. // offset from the buffer.
if (IsPCRel) if (Asm.fixupIsPCRel(kind()))
Str << " - ."; Str << " - .";
Str << "\n"; Str << "\n";
return FixupSize; return FixupSize;
} }
size_t AssemblerTextFixup::emit(GlobalContext *Ctx, RelocOffsetT OverrideOffset, size_t AssemblerTextFixup::emit(GlobalContext *Ctx, const Assembler &) const {
bool IsPCRel) const {
(void)OverrideOffset;
(void)IsPCRel;
Ctx->getStrEmit() << Message << "\n"; Ctx->getStrEmit() << Message << "\n";
return NumBytes; return NumBytes;
} }
......
...@@ -46,8 +46,7 @@ public: ...@@ -46,8 +46,7 @@ public:
void set_value(const Constant *Value) { value_ = Value; } void set_value(const Constant *Value) { value_ = Value; }
/// Emits fixup, then returns the number of bytes to skip. /// Emits fixup, then returns the number of bytes to skip.
virtual size_t emit(GlobalContext *Ctx, RelocOffsetT OverrideOffset, virtual size_t emit(GlobalContext *Ctx, const Assembler &Asm) const;
bool IsPCRel) const;
private: private:
intptr_t position_ = 0; intptr_t position_ = 0;
...@@ -67,8 +66,7 @@ public: ...@@ -67,8 +66,7 @@ public:
AssemblerTextFixup(const std::string &Message, size_t NumBytes) AssemblerTextFixup(const std::string &Message, size_t NumBytes)
: AssemblerFixup(), Message(Message), NumBytes(NumBytes) {} : AssemblerFixup(), Message(Message), NumBytes(NumBytes) {}
~AssemblerTextFixup() = default; ~AssemblerTextFixup() = default;
virtual size_t emit(GlobalContext *Ctx, RelocOffsetT OverrideOffset, size_t emit(GlobalContext *Ctx, const Assembler &Asm) const override;
bool isPcRel) const;
private: private:
const std::string Message; const std::string Message;
......
...@@ -689,7 +689,6 @@ void InstARM32Mov::emit(const Cfg *Func) const { ...@@ -689,7 +689,6 @@ void InstARM32Mov::emit(const Cfg *Func) const {
} }
void InstARM32Mov::emitIAS(const Cfg *Func) const { void InstARM32Mov::emitIAS(const Cfg *Func) const {
assert(getSrcSize() == 1);
(void)Func; (void)Func;
assert(!(isMultiDest() && isMultiSource()) && "Invalid vmov type."); assert(!(isMultiDest() && isMultiSource()) && "Invalid vmov type.");
ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>(); ARM32::AssemblerARM32 *Asm = Func->getAssembler<ARM32::AssemblerARM32>();
...@@ -752,8 +751,8 @@ void InstARM32Br::emitIAS(const Cfg *Func) const { ...@@ -752,8 +751,8 @@ void InstARM32Br::emitIAS(const Cfg *Func) const {
} else { } else {
Asm->b(Asm->getOrCreateCfgNodeLabel(getTargetTrue()->getIndex()), Asm->b(Asm->getOrCreateCfgNodeLabel(getTargetTrue()->getIndex()),
getPredicate()); getPredicate());
Asm->b(Asm->getOrCreateCfgNodeLabel(getTargetFalse()->getIndex()), if (const CfgNode *False = getTargetFalse())
CondARM32::AL); Asm->b(Asm->getOrCreateCfgNodeLabel(False->getIndex()), CondARM32::AL);
} }
if (Asm->needsTextFixup()) if (Asm->needsTextFixup())
emitUsingTextFixup(Func); 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