Skip to content

Commit

Permalink
AArch64: Support PRFM instruction
Browse files Browse the repository at this point in the history
Add ARM64MemImmInstruction class and generateMemImmInstruction helper function.
Add enum class for Prefetch operations.

Signed-off-by: Akira Saitoh <saiaki@jp.ibm.com>
  • Loading branch information
Akira Saitoh committed Mar 19, 2021
1 parent 9e05a3b commit d9c0dbc
Show file tree
Hide file tree
Showing 7 changed files with 201 additions and 6 deletions.
15 changes: 14 additions & 1 deletion compiler/aarch64/codegen/ARM64BinaryEncoding.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2018, 2020 IBM Corp. and others
* Copyright (c) 2018, 2021 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -654,6 +654,19 @@ int32_t TR::ARM64MemInstruction::estimateBinaryLength(int32_t currentEstimate)
return(currentEstimate + getEstimatedBinaryLength());
}

uint8_t *TR::ARM64MemImmInstruction::generateBinaryEncoding()
{
uint8_t *instructionStart = cg()->getBinaryBufferCursor();
uint8_t *cursor = instructionStart;
cursor = getOpCode().copyBinaryToBuffer(instructionStart);
insertImmediateField(toARM64Cursor(cursor));
cursor = getMemoryReference()->generateBinaryEncoding(this, cursor, cg());
setBinaryLength(cursor - instructionStart);
setBinaryEncoding(instructionStart);
cg()->addAccumulatedInstructionLengthError(getEstimatedBinaryLength() - getBinaryLength());
return cursor;
}

uint8_t *TR::ARM64MemSrc1Instruction::generateBinaryEncoding()
{
uint8_t *instructionStart = cg()->getBinaryBufferCursor();
Expand Down
40 changes: 39 additions & 1 deletion compiler/aarch64/codegen/ARM64Debug.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2018, 2020 IBM Corp. and others
* Copyright (c) 2018, 2021 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -618,6 +618,9 @@ TR_Debug::print(TR::FILE *pOutFile, TR::Instruction *instr)
case OMR::Instruction::IsMem:
print(pOutFile, (TR::ARM64MemInstruction *)instr);
break;
case OMR::Instruction::IsMemImm:
print(pOutFile, (TR::ARM64MemImmInstruction *)instr);
break;
case OMR::Instruction::IsMemSrc1:
print(pOutFile, (TR::ARM64MemSrc1Instruction *)instr);
break;
Expand Down Expand Up @@ -1436,6 +1439,41 @@ TR_Debug::print(TR::FILE *pOutFile, TR::ARM64MemInstruction *instr)
trfflush(_comp->getOutFile());
}

void
TR_Debug::print(TR::FILE *pOutFile, TR::ARM64MemImmInstruction *instr)
{
TR::InstOpCode::Mnemonic op = instr->getOpCodeValue();
printPrefix(pOutFile, instr);
trfprintf(pOutFile, "%s \t", getOpCodeName(&instr->getOpCode()));
if ((op == TR::InstOpCode::prfmoff || op == TR::InstOpCode::prfmimm))
{
uint32_t immediate = instr->getImmediate();
uint32_t typeValue = (immediate >> 3) & 0x3;
uint32_t targetValue = (immediate >> 1) & 0x3;
if ((typeValue != 3) && (targetValue != 3))
{
ARM64PrefetchType type = static_cast<ARM64PrefetchType>(typeValue);
ARM64PrefetchTarget target = static_cast<ARM64PrefetchTarget>(targetValue);
ARM64PrefetchPolicy policy = static_cast<ARM64PrefetchPolicy>(immediate & 0x1);
trfprintf(pOutFile, "%s%s%s, ", (type == ARM64PrefetchType::LOAD) ? "pld" : ((type == ARM64PrefetchType::INSTRUCTION) ? "pli" : "pst"),
(target == ARM64PrefetchTarget::L1) ? "l1" : ((target == ARM64PrefetchTarget::L2) ? "l2" : "l3"),
(policy == ARM64PrefetchPolicy::KEEP) ? "keep" : "strm");
}
else
{
trfprintf(pOutFile, "#%d, ", instr->getImmediate());
}
}
else
{
trfprintf(pOutFile, "#%d, ", instr->getImmediate());
}
print(pOutFile, instr->getMemoryReference());
printMemoryReferenceComment(pOutFile, instr->getMemoryReference());
printInstructionComment(pOutFile, 1, instr);
trfflush(_comp->getOutFile());
}

void
TR_Debug::print(TR::FILE *pOutFile, TR::ARM64MemSrc1Instruction *instr)
{
Expand Down
117 changes: 116 additions & 1 deletion compiler/aarch64/codegen/ARM64Instruction.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2018, 2020 IBM Corp. and others
* Copyright (c) 2018, 2021 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -40,6 +40,47 @@ namespace TR { class SymbolReference; }

#define ARM64_INSTRUCTION_LENGTH 4

/*
* Prefetch type used in PRFM instructions
*/
enum class ARM64PrefetchType
{
LOAD = 0,
INSTRUCTION = 1,
STORE = 2
};

/*
* Prefetch target used in PRFM instructions
*/
enum class ARM64PrefetchTarget
{
L1 = 0,
L2 = 1,
L3 = 2
};

/*
* Prefetch policy used in PRFM instructions
*/
enum class ARM64PrefetchPolicy
{
KEEP = 0,
STRM = 1
};

/*
* @brief returns Prefetch operation from specified type, target, and policy.
* @param[in] type : prefetch type
* @param[in] target : prefetch target
* @param[in] policy : prefetch policy
* @return prefetch operation
*/
inline uint32_t toPrefetchOp(ARM64PrefetchType type, ARM64PrefetchTarget target, ARM64PrefetchPolicy policy)
{
return (static_cast<uint32_t>(type) << 3) | (static_cast<uint32_t>(target) << 1) | static_cast<uint32_t>(policy);
}

/*
* @brief Answers if the signed integer value can be placed in 7-bit field
* @param[in] intValue : signed integer value
Expand Down Expand Up @@ -3355,6 +3396,80 @@ class ARM64Trg1MemSrc1Instruction : public ARM64Trg1MemInstruction
virtual int32_t estimateBinaryLength(int32_t currentEstimate);
};

class ARM64MemImmInstruction : public ARM64MemInstruction
{
uint32_t _immediate; // Imm5

public:
/*
* @brief Constructor
* @param[in] op : instruction opcode
* @param[in] node : node
* @param[in] mr : memory reference
* @param[in] immediate : 5bit immediate
* @param[in] cg : CodeGenerator
*/
ARM64MemImmInstruction(TR::InstOpCode::Mnemonic op,
TR::Node *node,
TR::MemoryReference *mr,
uint32_t immediate,
TR::CodeGenerator *cg)
: ARM64MemInstruction(op, node, mr, cg), _immediate(immediate)
{
}

/*
* @brief Constructor
* @param[in] op : instruction opcode
* @param[in] node : node
* @param[in] mr : memory reference
* @param[in] precedingInstruction : preceding instruction
* @param[in] immediate : 5bit immediate
* @param[in] cg : CodeGenerator
*/
ARM64MemImmInstruction(TR::InstOpCode::Mnemonic op,
TR::Node *node,
TR::MemoryReference *mr,
uint32_t immediate,
TR::Instruction *precedingInstruction, TR::CodeGenerator *cg)
: ARM64MemInstruction(op, node, mr, precedingInstruction, cg), _immediate(immediate)
{
}

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

/**
* @brief Gets immediate
* @return immediate
*/
uint32_t getImmediate() {return _immediate;}
/**
* @brief Sets immediate
* @param[in] immediate : immediate value
* @return immediate
*/
uint32_t setImmediate(uint32_t immediate) {return (_immediate = immediate);}

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

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

class ARM64Src1Instruction : public TR::Instruction
{
TR::Register *_source1Register;
Expand Down
10 changes: 9 additions & 1 deletion compiler/aarch64/codegen/GenerateInstructions.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2018, 2020 IBM Corp. and others
* Copyright (c) 2018, 2021 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -280,6 +280,14 @@ TR::Instruction *generateTrg1MemInstruction(TR::CodeGenerator *cg, TR::InstOpCod
return new (cg->trHeapMemory()) TR::ARM64Trg1MemInstruction(op, node, treg, mr, cg);
}

TR::Instruction *generateMemImmInstruction(TR::CodeGenerator *cg, TR::InstOpCode::Mnemonic op, TR::Node *node,
TR::MemoryReference *mr, uint32_t imm, TR::Instruction *preced)
{
if (preced)
return new (cg->trHeapMemory()) TR::ARM64MemImmInstruction(op, node, mr, imm, preced, cg);
return new (cg->trHeapMemory()) TR::ARM64MemImmInstruction(op, node, mr, imm, cg);
}

TR::Instruction *generateMemSrc1Instruction(TR::CodeGenerator *cg, TR::InstOpCode::Mnemonic op, TR::Node *node,
TR::MemoryReference *mr, TR::Register *sreg, TR::Instruction *preced)
{
Expand Down
20 changes: 19 additions & 1 deletion compiler/aarch64/codegen/GenerateInstructions.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2018, 2020 IBM Corp. and others
* Copyright (c) 2018, 2021 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -622,6 +622,24 @@ TR::Instruction *generateTrg1MemInstruction(
TR::MemoryReference *mr,
TR::Instruction *preced = NULL);

/*
* @brief Generates mem-imm instruction
* @param[in] cg : CodeGenerator
* @param[in] op : instruction opcode
* @param[in] node : node
* @param[in] mr : memory reference
* @param[in] imm : immediate
* @param[in] preced : preceding instruction
* @return generated instruction
*/
TR::Instruction *generateMemImmInstruction(
TR::CodeGenerator *cg,
TR::InstOpCode::Mnemonic op,
TR::Node *node,
TR::MemoryReference *mr,
uint32_t imm,
TR::Instruction *preced = NULL);

/*
* @brief Generates src-to-mem instruction
* @param[in] cg : CodeGenerator
Expand Down
3 changes: 2 additions & 1 deletion compiler/aarch64/codegen/OMRInstructionKindEnum.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2018, 2020 IBM Corp. and others
* Copyright (c) 2018, 2021 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -55,6 +55,7 @@
IsMem,
IsMemSrc1,
IsMemSrc2,
IsMemImm,
IsSrc1,
IsZeroSrc1Imm,
IsSrc2,
Expand Down
2 changes: 2 additions & 0 deletions compiler/ras/Debug.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ namespace TR { class ARM64Trg1Src2ZeroInstruction; }
namespace TR { class ARM64Trg1Src3Instruction; }
namespace TR { class ARM64Trg1MemInstruction; }
namespace TR { class ARM64MemInstruction; }
namespace TR { class ARM64MemImmInstruction; }
namespace TR { class ARM64MemSrc1Instruction; }
namespace TR { class ARM64MemSrc2Instruction; }
namespace TR { class ARM64Trg1MemSrc1Instruction; }
Expand Down Expand Up @@ -1135,6 +1136,7 @@ class TR_Debug
void print(TR::FILE *, TR::ARM64Trg1Src3Instruction *);
void print(TR::FILE *, TR::ARM64Trg1MemInstruction *);
void print(TR::FILE *, TR::ARM64MemInstruction *);
void print(TR::FILE *, TR::ARM64MemImmInstruction *);
void print(TR::FILE *, TR::ARM64MemSrc1Instruction *);
void print(TR::FILE *, TR::ARM64MemSrc2Instruction *);
void print(TR::FILE *, TR::ARM64Trg1MemSrc1Instruction *);
Expand Down

0 comments on commit d9c0dbc

Please sign in to comment.