Skip to content

Commit

Permalink
AArch64: Implement ARM64Trg1ImmSymInstruction
Browse files Browse the repository at this point in the history
This commit implements ARM64Trg1ImmSymInstruction, for generating
PC relative load register instructions.

Signed-off-by: Akira Saitoh <saiaki@jp.ibm.com>
  • Loading branch information
Akira1Saitoh committed Nov 15, 2019
1 parent b372b24 commit 2cd0f0b
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 0 deletions.
20 changes: 20 additions & 0 deletions compiler/aarch64/codegen/ARM64BinaryEncoding.cpp
Expand Up @@ -353,6 +353,26 @@ uint8_t *TR::ARM64Trg1ImmInstruction::generateBinaryEncoding()
return cursor;
}

uint8_t *TR::ARM64Trg1ImmSymInstruction::generateBinaryEncoding()
{
uint8_t *instructionStart = cg()->getBinaryBufferCursor();
uint8_t *cursor = instructionStart;
cursor = getOpCode().copyBinaryToBuffer(instructionStart);
insertTargetRegister(toARM64Cursor(cursor));
insertImmediateField(toARM64Cursor(cursor));

auto label = getLabelSymbol();
if (label != NULL)
{
cg()->addRelocation(new (cg()->trHeapMemory()) TR::LabelRelative24BitRelocation(cursor, label));
}

cursor += ARM64_INSTRUCTION_LENGTH;
setBinaryLength(ARM64_INSTRUCTION_LENGTH);
setBinaryEncoding(instructionStart);
return cursor;
}

uint8_t *TR::ARM64Trg1Src1Instruction::generateBinaryEncoding()
{
uint8_t *instructionStart = cg()->getBinaryBufferCursor();
Expand Down
25 changes: 25 additions & 0 deletions compiler/aarch64/codegen/ARM64Debug.cpp
Expand Up @@ -564,6 +564,9 @@ TR_Debug::print(TR::FILE *pOutFile, TR::Instruction *instr)
case OMR::Instruction::IsTrg1Imm:
print(pOutFile, (TR::ARM64Trg1ImmInstruction *)instr);
break;
case OMR::Instruction::IsTrg1ImmSym:
print(pOutFile, (TR::ARM64Trg1ImmSymInstruction *)instr);
break;
case OMR::Instruction::IsTrg1Src1:
print(pOutFile, (TR::ARM64Trg1Src1Instruction *)instr);
break;
Expand Down Expand Up @@ -822,6 +825,28 @@ TR_Debug::print(TR::FILE *pOutFile, TR::ARM64Trg1ImmInstruction *instr)
trfflush(_comp->getOutFile());
}

void
TR_Debug::print(TR::FILE *pOutFile, TR::ARM64Trg1ImmSymInstruction *instr)
{
printPrefix(pOutFile, instr);
trfprintf(pOutFile, "%s \t", getOpCodeName(&instr->getOpCode()));
print(pOutFile, instr->getTargetRegister(), TR_WordReg);
uint32_t imm = instr->getSourceImmediate() & 0x7FFFF;
TR::LabelSymbol *label = instr->getLabelSymbol();
TR::Snippet *snippet = label ? label->getSnippet() : NULL;
if (snippet)
{
print(pOutFile, label);
trfprintf(pOutFile, " (%s)", getName(snippet));
}
else
{
trfprintf(pOutFile, " " POINTER_PRINTF_FORMAT, instr->getBinaryEncoding() + (imm << 2));
}

trfflush(_comp->getOutFile());
}

void
TR_Debug::print(TR::FILE *pOutFile, TR::ARM64Trg1Src1Instruction *instr)
{
Expand Down
66 changes: 66 additions & 0 deletions compiler/aarch64/codegen/ARM64Instruction.hpp
Expand Up @@ -1166,6 +1166,72 @@ class ARM64Trg1ImmInstruction : public ARM64Trg1Instruction
virtual uint8_t *generateBinaryEncoding();
};

class ARM64Trg1ImmSymInstruction : public ARM64Trg1ImmInstruction
{
TR::LabelSymbol *_symbol;

public:
/*
* @brief Constructor
* @param[in] op : instruction opcode
* @param[in] node : node
* @param[in] treg : target register
* @param[in] imm : immediate value
* @param[in] sym : label symbol
* @param[in] cg : CodeGenerator
*/
ARM64Trg1ImmSymInstruction(TR::InstOpCode::Mnemonic op, TR::Node *node, TR::Register *treg,
uint32_t imm, TR::LabelSymbol *sym, TR::CodeGenerator *cg)
: ARM64Trg1ImmInstruction(op, node, treg, imm, cg), _symbol(sym)
{
}

/*
* @brief Constructor
* @param[in] op : instruction opcode
* @param[in] node : node
* @param[in] treg : target register
* @param[in] imm : immediate value
* @param[in] sym : label symbol
* @param[in] precedingInstruction : preceding instruction
* @param[in] cg : CodeGenerator
*/
ARM64Trg1ImmSymInstruction(TR::InstOpCode::Mnemonic op, TR::Node *node, TR::Register *treg,
uint32_t imm, TR::LabelSymbol *sym,
TR::Instruction *precedingInstruction, TR::CodeGenerator *cg)
: ARM64Trg1ImmInstruction(op, node, treg, imm, precedingInstruction, cg), _symbol(sym)
{
}

/**
* @brief Gets instruction kind
* @return instruction kind
*/
virtual Kind getKind() { return IsTrg1ImmSym; }

/**
*
* @brief Gets label symbol
* @return label symbol
*/
TR::LabelSymbol *getLabelSymbol() {return _symbol;}

/**
* @brief Sets immediate field in binary encoding
* @param[in] instruction : instruction cursor
*/
void insertImmediateField(uint32_t *instruction)
{
*instruction |= ((getSourceImmediate() & 0x7ffff) << 5);
}

/**
* @brief Generates binary encoding of the instruction
* @return instruction cursor
*/
virtual uint8_t *generateBinaryEncoding();
};

class ARM64Trg1Src1Instruction : public ARM64Trg1Instruction
{
TR::Register *_source1Register;
Expand Down
8 changes: 8 additions & 0 deletions compiler/aarch64/codegen/GenerateInstructions.cpp
Expand Up @@ -141,6 +141,14 @@ TR::Instruction *generateTrg1ImmInstruction(TR::CodeGenerator *cg, TR::InstOpCod
return new (cg->trHeapMemory()) TR::ARM64Trg1ImmInstruction(op, node, treg, imm, cg);
}

TR::Instruction *generateTrg1ImmSymInstruction(TR::CodeGenerator *cg, TR::InstOpCode::Mnemonic op, TR::Node *node,
TR::Register *treg, uint32_t imm, TR::LabelSymbol *sym, TR::Instruction *preced)
{
if (preced)
return new (cg->trHeapMemory()) TR::ARM64Trg1ImmSymInstruction(op, node, treg, imm, sym, preced, cg);
return new (cg->trHeapMemory()) TR::ARM64Trg1ImmSymInstruction(op, node, treg, imm, sym, cg);
}

TR::Instruction *generateTrg1Src1Instruction(TR::CodeGenerator *cg, TR::InstOpCode::Mnemonic op, TR::Node *node,
TR::Register *treg, TR::Register *s1reg, TR::Instruction *preced)
{
Expand Down
20 changes: 20 additions & 0 deletions compiler/aarch64/codegen/GenerateInstructions.hpp
Expand Up @@ -270,6 +270,26 @@ TR::Instruction *generateTrg1ImmInstruction(
uint32_t imm,
TR::Instruction *preced = NULL);

/*
* @brief Generates imm-to-trg label instruction
* @param[in] cg : CodeGenerator
* @param[in] op : instruction opcode
* @param[in] node : node
* @param[in] treg : target register
* @param[in] imm : immediate value
* @param[in] sym : label symbol
* @param[in] preced : preceding instruction
* @return generated instruction
*/
TR::Instruction *generateTrg1ImmSymInstruction(
TR::CodeGenerator *cg,
TR::InstOpCode::Mnemonic op,
TR::Node *node,
TR::Register *treg,
uint32_t imm,
TR::LabelSymbol *sym,
TR::Instruction *preced = NULL);

/*
* @brief Generates src1-to-trg instruction
* @param[in] cg : CodeGenerator
Expand Down
1 change: 1 addition & 0 deletions compiler/aarch64/codegen/OMRInstructionKindEnum.hpp
Expand Up @@ -38,6 +38,7 @@
IsTrg1,
IsTrg1Cond,
IsTrg1Imm,
IsTrg1ImmSym,
IsTrg1Src1,
IsTrg1Src1Imm,
IsTrg1Src2,
Expand Down
2 changes: 2 additions & 0 deletions compiler/ras/Debug.hpp
Expand Up @@ -343,6 +343,7 @@ namespace TR { class ARM64AdminInstruction; }
namespace TR { class ARM64Trg1Instruction; }
namespace TR { class ARM64Trg1CondInstruction; }
namespace TR { class ARM64Trg1ImmInstruction; }
namespace TR { class ARM64Trg1ImmSymInstruction; }
namespace TR { class ARM64Trg1Src1Instruction; }
namespace TR { class ARM64Trg1Src1ImmInstruction; }
namespace TR { class ARM64Trg1Src2Instruction; }
Expand Down Expand Up @@ -1098,6 +1099,7 @@ class TR_Debug
void print(TR::FILE *, TR::ARM64Trg1Instruction *);
void print(TR::FILE *, TR::ARM64Trg1CondInstruction *);
void print(TR::FILE *, TR::ARM64Trg1ImmInstruction *);
void print(TR::FILE *, TR::ARM64Trg1ImmSymInstruction *);
void print(TR::FILE *, TR::ARM64Trg1Src1Instruction *);
void print(TR::FILE *, TR::ARM64Trg1Src1ImmInstruction *);
void print(TR::FILE *, TR::ARM64Trg1Src2Instruction *);
Expand Down

0 comments on commit 2cd0f0b

Please sign in to comment.