mirror of
https://github.com/RPCSX/llvm.git
synced 2025-02-01 18:12:49 +00:00
Sketch streamer support for .align, .org functionality.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74109 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b5299dd06a
commit
84a2926fb7
@ -10,6 +10,8 @@
|
||||
#ifndef LLVM_MC_MCSTREAMER_H
|
||||
#define LLVM_MC_MCSTREAMER_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
class MCContext;
|
||||
class MCValue;
|
||||
@ -53,6 +55,9 @@ namespace llvm {
|
||||
|
||||
MCContext &getContext() const { return Context; }
|
||||
|
||||
/// @name Symbol & Section Management
|
||||
/// @{
|
||||
|
||||
/// SwitchSection - Set the current section where code is being emitted to
|
||||
/// @param Section.
|
||||
///
|
||||
@ -98,6 +103,10 @@ namespace llvm {
|
||||
virtual void EmitSymbolAttribute(MCSymbol *Symbol,
|
||||
SymbolAttr Attribute) = 0;
|
||||
|
||||
/// @}
|
||||
/// @name Generating Data
|
||||
/// @{
|
||||
|
||||
/// EmitBytes - Emit @param Length bytes starting at @param Data into the
|
||||
/// output.
|
||||
///
|
||||
@ -116,6 +125,42 @@ namespace llvm {
|
||||
/// match a native machine width.
|
||||
virtual void EmitValue(const MCValue &Value, unsigned Size) = 0;
|
||||
|
||||
/// EmitValueToAlignment - Emit some number of copies of @param Value until
|
||||
/// the byte alignment @param ByteAlignment is reached.
|
||||
///
|
||||
/// If the number of bytes need to emit for the alignment is not a multiple
|
||||
/// of @param ValueSize, then the contents of the emitted fill bytes is
|
||||
/// undefined.
|
||||
///
|
||||
/// This used to implement the .align assembler directive.
|
||||
///
|
||||
/// @param ByteAlignment - The alignment to reach. This must be a power of
|
||||
/// two.
|
||||
/// @param Value - The value to use when filling bytes.
|
||||
/// @param Size - The size of the integer (in bytes) to emit for @param
|
||||
/// Value. This must match a native machine width.
|
||||
/// @param MaxBytesToEmit - The maximum numbers of bytes to emit, or 0. If
|
||||
/// the alignment cannot be reached in this many bytes, no bytes are
|
||||
/// emitted.
|
||||
virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
|
||||
unsigned ValueSize = 1,
|
||||
unsigned MaxBytesToEmit = 0) = 0;
|
||||
|
||||
/// EmitValueToOffset - Emit some number of copies of @param Value until the
|
||||
/// byte offset @param Offset is reached.
|
||||
///
|
||||
/// This is used to implement assembler directives such as .org.
|
||||
///
|
||||
/// @param Offset - The offset to reach.This may be an expression, but the
|
||||
/// expression must be associated with the current section.
|
||||
/// @param Value - The value to use when filling bytes.
|
||||
//
|
||||
// FIXME: How are we going to signal failures out of this?
|
||||
virtual void EmitValueToOffset(const MCValue &Offset,
|
||||
unsigned char Value = 0) = 0;
|
||||
|
||||
/// @}
|
||||
|
||||
/// EmitInstruction - Emit the given @param Instruction into the current
|
||||
/// section.
|
||||
virtual void EmitInstruction(const MCInst &Inst) = 0;
|
||||
|
@ -44,6 +44,13 @@ namespace {
|
||||
|
||||
virtual void EmitValue(const MCValue &Value, unsigned Size);
|
||||
|
||||
virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
|
||||
unsigned ValueSize = 1,
|
||||
unsigned MaxBytesToEmit = 0);
|
||||
|
||||
virtual void EmitValueToOffset(const MCValue &Offset,
|
||||
unsigned char Value = 0);
|
||||
|
||||
virtual void EmitInstruction(const MCInst &Inst);
|
||||
|
||||
virtual void Finish();
|
||||
@ -144,6 +151,36 @@ void MCAsmStreamer::EmitValue(const MCValue &Value, unsigned Size) {
|
||||
OS << ' ' << Value << '\n';
|
||||
}
|
||||
|
||||
void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
|
||||
unsigned ValueSize,
|
||||
unsigned MaxBytesToEmit) {
|
||||
unsigned Pow2 = Log2_32(ByteAlignment);
|
||||
assert((1U << Pow2) == ByteAlignment && "Invalid alignment!");
|
||||
|
||||
switch (ValueSize) {
|
||||
default:
|
||||
assert(0 && "Invalid size for machine code value!");
|
||||
case 8:
|
||||
assert(0 && "Unsupported alignment size!");
|
||||
case 1: OS << ".p2align"; break;
|
||||
case 2: OS << ".p2alignw"; break;
|
||||
case 4: OS << ".p2alignl"; break;
|
||||
}
|
||||
|
||||
OS << ' ' << Pow2;
|
||||
|
||||
OS << ", " << Value;
|
||||
if (MaxBytesToEmit)
|
||||
OS << ", " << MaxBytesToEmit;
|
||||
OS << '\n';
|
||||
}
|
||||
|
||||
void MCAsmStreamer::EmitValueToOffset(const MCValue &Offset,
|
||||
unsigned char Value) {
|
||||
// FIXME: Verify that Offset is associated with the current section.
|
||||
OS << ".org " << Offset << ", " << (unsigned) Value << '\n';
|
||||
}
|
||||
|
||||
void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
|
||||
assert(CurSection && "Cannot emit contents before setting section!");
|
||||
// FIXME: Implement.
|
||||
|
@ -72,4 +72,32 @@ b:\n\
|
||||
");
|
||||
}
|
||||
|
||||
TEST(AsmStreamer, Align) {
|
||||
StringAsmStreamer S;
|
||||
MCSection *Sec0 = S.getContext().GetSection("foo");
|
||||
S.getStreamer().SwitchSection(Sec0);
|
||||
S.getStreamer().EmitValueToAlignment(4);
|
||||
S.getStreamer().EmitValueToAlignment(4, /*Value=*/12, /*ValueSize=*/2);
|
||||
S.getStreamer().EmitValueToAlignment(8, /*Value=*/12, /*ValueSize=*/4,
|
||||
/*MaxBytesToEmit=*/24);
|
||||
EXPECT_EQ(S.getString(), ".section foo\n\
|
||||
.p2align 2, 0\n\
|
||||
.p2alignw 2, 12\n\
|
||||
.p2alignl 3, 12, 24\n\
|
||||
");
|
||||
}
|
||||
|
||||
TEST(AsmStreamer, Org) {
|
||||
StringAsmStreamer S;
|
||||
MCSection *Sec0 = S.getContext().GetSection("foo");
|
||||
S.getStreamer().SwitchSection(Sec0);
|
||||
MCSymbol *A = S.getContext().CreateSymbol("a");
|
||||
S.getStreamer().EmitLabel(A);
|
||||
S.getStreamer().EmitValueToOffset(MCValue::get(A, 0, 4), 32);
|
||||
EXPECT_EQ(S.getString(), ".section foo\n\
|
||||
a:\n\
|
||||
.org a + 4, 32\n\
|
||||
");
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user