Skip to content

Commit

Permalink
Merge pull request #5371 from aviansie-ben/p10-pc-relative
Browse files Browse the repository at this point in the history
  • Loading branch information
fjeremic authored Jul 22, 2020
2 parents 8792e78 + 33d699a commit 8c05fb5
Show file tree
Hide file tree
Showing 7 changed files with 720 additions and 11 deletions.
4 changes: 4 additions & 0 deletions compiler/p/codegen/MemoryReference.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ class OMR_EXTENSIBLE MemoryReference : public OMR::MemoryReferenceConnector
int) :
OMR::MemoryReferenceConnector(br, disp, len, cg, 0) {}

MemoryReference(TR::LabelSymbol *label, int64_t disp, int8_t len, TR::CodeGenerator *cg) :
OMR::MemoryReferenceConnector(label, disp, len, cg) {}

public:

MemoryReference(TR::CodeGenerator *cg) :
Expand Down Expand Up @@ -72,6 +75,7 @@ class OMR_EXTENSIBLE MemoryReference : public OMR::MemoryReferenceConnector
OMR::MemoryReferenceConnector(node, mr, n, len, cg) {}

static TR::MemoryReference *withDisplacement(TR::CodeGenerator *cg, TR::Register *baseReg, int64_t displacement, int8_t length);
static TR::MemoryReference *withLabel(TR::CodeGenerator *cg, TR::LabelSymbol *label, int64_t offset, int8_t length);
};
}

Expand Down
43 changes: 38 additions & 5 deletions compiler/p/codegen/OMRMemoryReference.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ TR::MemoryReference *TR::MemoryReference::withDisplacement(TR::CodeGenerator *cg
return new (cg->trHeapMemory()) TR::MemoryReference(baseReg, displacement, length, cg, 0);
}

TR::MemoryReference *TR::MemoryReference::withLabel(TR::CodeGenerator *cg, TR::LabelSymbol *label, int64_t offset, int8_t length)
{
return new (cg->trHeapMemory()) TR::MemoryReference(label, offset, length, cg);
}

OMR::Power::MemoryReference::MemoryReference(
TR::CodeGenerator *cg) :
_baseRegister(NULL),
Expand All @@ -84,12 +89,34 @@ OMR::Power::MemoryReference::MemoryReference(
_staticRelocation(NULL),
_unresolvedSnippet(NULL),
_conditions(NULL),
_flag(0)
_flag(0),
_label(NULL)
{
_symbolReference = new (cg->trHeapMemory()) TR::SymbolReference(cg->comp()->getSymRefTab());
_offset = _symbolReference->getOffset();
}

OMR::Power::MemoryReference::MemoryReference(
TR::LabelSymbol *label,
int64_t disp,
uint8_t len,
TR::CodeGenerator *cg) :
_baseRegister(NULL),
_baseNode(NULL),
_indexRegister(NULL),
_indexNode(NULL),
_modBase(NULL),
_unresolvedSnippet(NULL),
_staticRelocation(NULL),
_conditions(NULL),
_length(len),
_offset(disp),
_flag(0),
_label(label)
{
_symbolReference = new (cg->trHeapMemory()) TR::SymbolReference(cg->comp()->getSymRefTab());
}

OMR::Power::MemoryReference::MemoryReference(
TR::Register *br,
TR::Register *ir,
Expand All @@ -104,7 +131,8 @@ OMR::Power::MemoryReference::MemoryReference(
_staticRelocation(NULL),
_conditions(NULL),
_length(len),
_flag(0)
_flag(0),
_label(NULL)
{
_symbolReference = new (cg->trHeapMemory()) TR::SymbolReference(cg->comp()->getSymRefTab());
_offset = _symbolReference->getOffset();
Expand Down Expand Up @@ -133,7 +161,8 @@ OMR::Power::MemoryReference::MemoryReference(
_conditions(NULL),
_length(len),
_offset(disp),
_flag(0)
_flag(0),
_label(NULL)
{
_symbolReference = new (cg->trHeapMemory()) TR::SymbolReference(cg->comp()->getSymRefTab());
}
Expand All @@ -147,7 +176,7 @@ OMR::Power::MemoryReference::MemoryReference(TR::Node *rootLoadOrStore, uint32_t
: _baseRegister(NULL), _indexRegister(NULL), _unresolvedSnippet(NULL),
_modBase(NULL), _flag(0), _baseNode(NULL), _indexNode(NULL),
_symbolReference(rootLoadOrStore->getSymbolReference()), _offset(0),
_conditions(NULL), _length(len), _staticRelocation(NULL)
_conditions(NULL), _length(len), _staticRelocation(NULL), _label(NULL)
{
TR::Compilation *comp = cg->comp();
TR::SymbolReference *ref = rootLoadOrStore->getSymbolReference();
Expand Down Expand Up @@ -223,7 +252,7 @@ OMR::Power::MemoryReference::MemoryReference(TR::Node *node, TR::SymbolReference
: _baseRegister(NULL), _indexRegister(NULL), _unresolvedSnippet(NULL),
_modBase(NULL), _flag(0), _baseNode(NULL), _indexNode(NULL),
_symbolReference(symRef), _offset(0),
_conditions(NULL), _length(len), _staticRelocation(NULL)
_conditions(NULL), _length(len), _staticRelocation(NULL), _label(NULL)
{
TR::Symbol *symbol = symRef->getSymbol();

Expand Down Expand Up @@ -266,6 +295,7 @@ OMR::Power::MemoryReference::MemoryReference(TR::Node *node, TR::MemoryReference
_staticRelocation = NULL;
_conditions = NULL;
mr._flag = 0;
_label = mr._label;

TR_ASSERT(mr.getStaticRelocation() == NULL, "Relocated memory reference should not be re-used.");

Expand Down Expand Up @@ -1197,6 +1227,9 @@ TR::Instruction *OMR::Power::MemoryReference::expandInstruction(TR::Instruction
// a memory instruction.
TR_ASSERT_FATAL(currentInstruction->getPrev(), "The first instruction cannot be a memory instruction");

if (self()->getLabel())
return currentInstruction;

self()->mapOpCode(currentInstruction);

if (self()->getUnresolvedSnippet() != NULL)
Expand Down
10 changes: 10 additions & 0 deletions compiler/p/codegen/OMRMemoryReference.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class OMR_EXTENSIBLE MemoryReference : public OMR::MemoryReference
TR::Register *_indexRegister;
TR::Node *_indexNode;
TR::Register *_modBase;
TR::LabelSymbol *_label;
int64_t _offset;

TR::UnresolvedDataSnippet *_unresolvedSnippet;
Expand All @@ -90,6 +91,12 @@ class OMR_EXTENSIBLE MemoryReference : public OMR::MemoryReference
TR::CodeGenerator *cg,
int);

MemoryReference(
TR::LabelSymbol *label,
int64_t disp,
uint8_t len,
TR::CodeGenerator *cg);

public:

TR_ALLOC(TR_Memory::MemoryReference)
Expand Down Expand Up @@ -141,6 +148,9 @@ class OMR_EXTENSIBLE MemoryReference : public OMR::MemoryReference
uint32_t getLength() {return _length;}
uint32_t setLength(uint32_t len) {return (_length = len);}

TR::LabelSymbol *getLabel() {return _label;}
TR::LabelSymbol *setLabel(TR::LabelSymbol *label) {return (_label = label);}

bool useIndexedForm();

bool hasDelayedOffset()
Expand Down
41 changes: 38 additions & 3 deletions compiler/p/codegen/PPCAOTRelocation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ class PPCPairedRelocation: public TR::PPCRelocation
TR::Node *_node;
};

// This class has nothing to do with AOT, but for the lack of more appropriate locations
// this class is defined here.
//
// TODO(#5404): The classes defined below here are specific to Power, but are not actually AOT
// relocations. They are only here for lack of a better place to put them.

// PPC Specific Relocation: update the immediate fields of a pair of ppc instructions
// with the absolute address of a label (extended to 64bit as well). For example:
// lis gr3, addr_hi
Expand All @@ -109,6 +109,41 @@ class PPCPairedLabelAbsoluteRelocation : public TR::LabelRelocation
TR::Instruction *_instr4;
};

/**
* \brief Represents a relocation on the D34 field of a PC-relative prefixed load/store instruction
* that should use an offset from a TR::LabelSymbol.
*/
class PPCD34LabelRelocation : public TR::LabelRelocation
{
public:

/**
* \brief
* Creates a new PPCD34LabelRelocation.
*
* \param instr
* The TR::Instruction for which this relocation was created, or \c NULL if this relocation is
* not associated with an instruction object.
*
* \param cursor
* The start of the prefixed load/store instruction to relocate.
*
* \param label
* The label relative to which the load/store should occur.
*
* \param offset
* The byte offset from the label at which the load/store should occur.
*/
PPCD34LabelRelocation(TR::Instruction *instr, uint32_t *cursor, TR::LabelSymbol *label, int64_t offset)
: TR::LabelRelocation(reinterpret_cast<uint8_t*>(cursor), label), _instr(instr), _offset(offset) {}

virtual void apply(TR::CodeGenerator *cg);

private:
TR::Instruction *_instr;
int64_t _offset;
};

}

typedef TR::PPCRelocation TR_PPCRelocation;
Expand Down
94 changes: 91 additions & 3 deletions compiler/p/codegen/PPCBinaryEncoding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include "infra/Bit.hpp"
#include "infra/List.hpp"
#include "p/codegen/GenerateInstructions.hpp"
#include "p/codegen/PPCAOTRelocation.hpp"
#include "p/codegen/PPCInstruction.hpp"
#include "p/codegen/PPCOpsDefines.hpp"
#include "runtime/Runtime.hpp"
Expand Down Expand Up @@ -1454,6 +1455,36 @@ void TR::PPCSrc1Instruction::fillBinaryEncodingFields(uint32_t *cursor)
fillFieldFXM1(self(), cursor, imm);
break;

case FORMAT_RS_D34_RA_R:
fillFieldRS(self(), cursor + 1, src);
fillFieldD34(self(), cursor, static_cast<int64_t>(static_cast<int32_t>(imm)));
fillFieldR(self(), cursor, 1);
break;

case FORMAT_RSP_D34_RA_R:
fillFieldRSP(self(), cursor + 1, src);
fillFieldD34(self(), cursor, static_cast<int64_t>(static_cast<int32_t>(imm)));
fillFieldR(self(), cursor, 1);
break;

case FORMAT_FRS_D34_RA_R:
fillFieldFRS(self(), cursor + 1, src);
fillFieldD34(self(), cursor, static_cast<int64_t>(static_cast<int32_t>(imm)));
fillFieldR(self(), cursor, 1);
break;

case FORMAT_VRS_D34_RA_R:
fillFieldVRS(self(), cursor + 1, src);
fillFieldD34(self(), cursor, static_cast<int64_t>(static_cast<int32_t>(imm)));
fillFieldR(self(), cursor, 1);
break;

case FORMAT_XS5_D34_RA_R:
fillFieldXS5(self(), cursor + 1, src);
fillFieldD34(self(), cursor, static_cast<int64_t>(static_cast<int32_t>(imm)));
fillFieldR(self(), cursor, 1);
break;

default:
TR_ASSERT_FATAL_WITH_INSTRUCTION(self(), false, "Format %d cannot be binary encoded by PPCSrc1Instruction", getOpCode().getFormat());
}
Expand Down Expand Up @@ -1584,6 +1615,36 @@ TR::PPCTrg1ImmInstruction::fillBinaryEncodingFields(uint32_t *cursor)
fillFieldSIM(self(), cursor, imm);
break;

case FORMAT_RT_D34_RA_R:
fillFieldRT(self(), cursor + 1, trg);
fillFieldD34(self(), cursor, static_cast<int64_t>(static_cast<int32_t>(imm)));
fillFieldR(self(), cursor, 1);
break;

case FORMAT_RTP_D34_RA_R:
fillFieldRTP(self(), cursor + 1, trg);
fillFieldD34(self(), cursor, static_cast<int64_t>(static_cast<int32_t>(imm)));
fillFieldR(self(), cursor, 1);
break;

case FORMAT_FRT_D34_RA_R:
fillFieldFRT(self(), cursor + 1, trg);
fillFieldD34(self(), cursor, static_cast<int64_t>(static_cast<int32_t>(imm)));
fillFieldR(self(), cursor, 1);
break;

case FORMAT_VRT_D34_RA_R:
fillFieldVRT(self(), cursor + 1, trg);
fillFieldD34(self(), cursor, static_cast<int64_t>(static_cast<int32_t>(imm)));
fillFieldR(self(), cursor, 1);
break;

case FORMAT_XT5_D34_RA_R:
fillFieldXT5(self(), cursor + 1, trg);
fillFieldD34(self(), cursor, static_cast<int64_t>(static_cast<int32_t>(imm)));
fillFieldR(self(), cursor, 1);
break;

default:
TR_ASSERT_FATAL_WITH_INSTRUCTION(self(), false, "Format %d cannot be binary encoded by PPCTrg1ImmInstruction", getOpCode().getFormat());
}
Expand Down Expand Up @@ -2135,13 +2196,15 @@ TR::RealRegister *toRealBaseRegister(TR::Instruction *instr, TR::Register *r)

void fillMemoryReferenceD16RA(TR::Instruction *instr, uint32_t *cursor, TR::MemoryReference *mr)
{
TR_ASSERT_FATAL_WITH_INSTRUCTION(instr, !mr->getLabel(), "Cannot use PC-relative load with non-prefixed instruction");
TR_ASSERT_FATAL_WITH_INSTRUCTION(instr, !mr->getIndexRegister(), "Cannot use index-form MemoryReference with non-index-form instruction");
fillFieldD16(instr, cursor, mr->getOffset());
fillFieldRA(instr, cursor, toRealBaseRegister(instr, mr->getBaseRegister()));
}

void fillMemoryReferenceDSRA(TR::Instruction *instr, uint32_t *cursor, TR::MemoryReference *mr)
{
TR_ASSERT_FATAL_WITH_INSTRUCTION(instr, !mr->getLabel(), "Cannot use PC-relative load with non-prefixed instruction");
TR_ASSERT_FATAL_WITH_INSTRUCTION(instr, !mr->getIndexRegister(), "Cannot use index-form MemoryReference with non-index-form instruction");
fillFieldDS(instr, cursor, mr->getOffset());
fillFieldRA(instr, cursor, toRealBaseRegister(instr, mr->getBaseRegister()));
Expand All @@ -2157,13 +2220,27 @@ void fillMemoryReferenceDQRA(TR::Instruction *instr, uint32_t *cursor, TR::Memor
void fillMemoryReferenceD34RAR(TR::Instruction *instr, uint32_t *cursor, TR::MemoryReference *mr)
{
TR_ASSERT_FATAL_WITH_INSTRUCTION(instr, !mr->getIndexRegister(), "Cannot use index-form MemoryReference with non-index-form instruction");
fillFieldD34(instr, cursor, mr->getOffset());
fillFieldRA(instr, cursor + 1, toRealBaseRegister(instr, mr->getBaseRegister()));
fillFieldR(instr, cursor, 0);
if (mr->getLabel())
{
TR_ASSERT_FATAL_WITH_INSTRUCTION(instr, !mr->getBaseRegister(), "Cannot have base register on PC-relative MemoryReference");

if (mr->getLabel()->getCodeLocation())
fillFieldD34(instr, cursor, static_cast<uint64_t>(mr->getLabel()->getCodeLocation() - reinterpret_cast<uint8_t*>(cursor)) + mr->getOffset());
else
instr->cg()->addRelocation(new (instr->cg()->trHeapMemory()) TR::PPCD34LabelRelocation(instr, cursor, mr->getLabel(), mr->getOffset()));
fillFieldR(instr, cursor, 1);
}
else
{
fillFieldD34(instr, cursor, mr->getOffset());
fillFieldRA(instr, cursor + 1, toRealBaseRegister(instr, mr->getBaseRegister()));
fillFieldR(instr, cursor, 0);
}
}

void fillMemoryReferenceRARB(TR::Instruction *instr, uint32_t *cursor, TR::MemoryReference *mr)
{
TR_ASSERT_FATAL_WITH_INSTRUCTION(instr, !mr->getLabel(), "Cannot use PC-relative load with non-prefixed instruction");
TR_ASSERT_FATAL_WITH_INSTRUCTION(instr, mr->getOffset() == 0, "Cannot use non-index-form MemoryReference with index-form instruction");
fillFieldRA(instr, cursor, toRealBaseRegister(instr, mr->getBaseRegister()));
fillFieldRB(instr, cursor, toRealRegister(mr->getIndexRegister()));
Expand Down Expand Up @@ -2351,6 +2428,17 @@ TR::Instruction *TR::PPCTrg1MemInstruction::expandInstruction()
return getMemoryReference()->expandInstruction(self(), cg());
}

void TR::PPCD34LabelRelocation::apply(TR::CodeGenerator *cg)
{
TR_ASSERT_FATAL_WITH_INSTRUCTION(_instr, getLabel()->getCodeLocation(), "Attempt to relocate against an unencoded label");

fillFieldD34(
_instr,
reinterpret_cast<uint32_t*>(getUpdateLocation()),
static_cast<uint64_t>(getLabel()->getCodeLocation() - getUpdateLocation()) + _offset
);
}

uint8_t *TR::PPCControlFlowInstruction::generateBinaryEncoding()
{
uint8_t *instructionStart = cg()->getBinaryBufferCursor();
Expand Down
5 changes: 5 additions & 0 deletions compiler/p/codegen/PPCDebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,11 @@ TR_Debug::print(TR::FILE *pOutFile, TR::MemoryReference * mr, bool d_form)
print(pOutFile, mr->getBaseRegister());
trfprintf(pOutFile, ", ");
}
else if (mr->getLabel() != NULL)
{
print(pOutFile, mr->getLabel());
trfprintf(pOutFile, ", ");
}

if (mr->getIndexRegister() != NULL)
print(pOutFile, mr->getIndexRegister());
Expand Down
Loading

0 comments on commit 8c05fb5

Please sign in to comment.