Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions compiler/aarch64/codegen/ARM64BinaryEncoding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,21 @@ uint8_t *TR::ARM64Trg1ZeroSrc1Instruction::generateBinaryEncoding()
return cursor;
}

uint8_t *TR::ARM64Trg1ZeroImmInstruction::generateBinaryEncoding()
{
uint8_t *instructionStart = cg()->getBinaryBufferCursor();
uint8_t *cursor = instructionStart;
cursor = getOpCode().copyBinaryToBuffer(instructionStart);
insertTargetRegister(toARM64Cursor(cursor));
insertZeroRegister(toARM64Cursor(cursor));
insertImmediateField(toARM64Cursor(cursor));
insertNbit(toARM64Cursor(cursor));
cursor += ARM64_INSTRUCTION_LENGTH;
setBinaryLength(ARM64_INSTRUCTION_LENGTH);
setBinaryEncoding(instructionStart);
return cursor;
}

uint8_t *TR::ARM64Trg1Src1ImmInstruction::generateBinaryEncoding()
{
uint8_t *instructionStart = cg()->getBinaryBufferCursor();
Expand Down
51 changes: 51 additions & 0 deletions compiler/aarch64/codegen/ARM64Debug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,9 @@ TR_Debug::print(TR::FILE *pOutFile, TR::Instruction *instr)
case OMR::Instruction::IsTrg1ZeroSrc1:
print(pOutFile, (TR::ARM64Trg1ZeroSrc1Instruction *)instr);
break;
case OMR::Instruction::IsTrg1ZeroImm:
print(pOutFile, (TR::ARM64Trg1ZeroImmInstruction *)instr);
break;
case OMR::Instruction::IsTrg1Src1:
print(pOutFile, (TR::ARM64Trg1Src1Instruction *)instr);
break;
Expand Down Expand Up @@ -1507,6 +1510,54 @@ TR_Debug::print(TR::FILE *pOutFile, TR::ARM64Trg1Src1ImmInstruction *instr)
}

void
TR_Debug::print(TR::FILE *pOutFile, TR::ARM64Trg1ZeroImmInstruction *instr)
{
printPrefix(pOutFile, instr);
TR::InstOpCode::Mnemonic op = instr->getOpCodeValue();
bool done = false;
if (op == TR::InstOpCode::orrimmx || op == TR::InstOpCode::orrimmw)
{
// mov (bitmask immediate) alias
uint32_t imm12 = instr->getSourceImmediate();
auto immr = imm12 >> 6;
auto imms = imm12 & 0x3f;
auto n = instr->getNbit();
if (op == TR::InstOpCode::orrimmx)
{
uint64_t immediate;
if (decodeBitMasks(n, immr, imms, immediate))
{
done = true;
trfprintf(pOutFile, "movx \t");
print(pOutFile, instr->getTargetRegister(), TR_WordReg);
trfprintf(pOutFile, ", 0x%llx", immediate);
}
}
else
{
uint32_t immediate;
if (decodeBitMasks(n, immr, imms, immediate))
{
done = true;
trfprintf(pOutFile, "movw \t");
print(pOutFile, instr->getTargetRegister(), TR_WordReg);
trfprintf(pOutFile, ", 0x%lx", immediate);
}
}
}
if (!done)
{
trfprintf(pOutFile, "%s \t", getOpCodeName(&instr->getOpCode()));
print(pOutFile, instr->getTargetRegister(), TR_WordReg);
trfprintf(pOutFile, ", %d", instr->getSourceImmediate());
}

if (instr->getDependencyConditions())
print(pOutFile, instr->getDependencyConditions());

trfflush(_comp->getOutFile());
}
void
TR_Debug::print(TR::FILE *pOutFile, TR::ARM64ZeroSrc1ImmInstruction *instr)
{
printPrefix(pOutFile, instr);
Expand Down
141 changes: 141 additions & 0 deletions compiler/aarch64/codegen/ARM64Instruction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1926,6 +1926,147 @@ class ARM64Trg1ZeroSrc1Instruction : public ARM64Trg1Src1Instruction
virtual uint8_t *generateBinaryEncoding();
};

/*
* This class is designated to be used for alias instruction such as movw, movx (bitmask immediate)
*/
class ARM64Trg1ZeroImmInstruction : public ARM64Trg1Instruction
{
uint32_t _source1Immediate;
bool _Nbit;

public:

/*
* @brief Constructor
* @param[in] op : instruction opcode
* @param[in] node : node
* @param[in] treg : target register
* @param[in] imm : immediate value
* @param[in] cg : CodeGenerator
*/
ARM64Trg1ZeroImmInstruction(TR::InstOpCode::Mnemonic op, TR::Node *node, TR::Register *treg,
uint32_t imm, TR::CodeGenerator *cg)
: ARM64Trg1Instruction(op, node, treg, cg), _source1Immediate(imm), _Nbit(false)
{
}

/*
* @brief Constructor
* @param[in] op : instruction opcode
* @param[in] node : node
* @param[in] treg : target register
* @param[in] N : N bit value
* @param[in] imm : immediate value
* @param[in] cg : CodeGenerator
*/
ARM64Trg1ZeroImmInstruction(TR::InstOpCode::Mnemonic op, TR::Node *node, TR::Register *treg,
bool N, uint32_t imm, TR::CodeGenerator *cg)
: ARM64Trg1Instruction(op, node, treg, cg), _source1Immediate(imm), _Nbit(N)
{
}

/*
* @brief Constructor
* @param[in] op : instruction opcode
* @param[in] node : node
* @param[in] treg : target register
* @param[in] imm : immediate value
* @param[in] precedingInstruction : preceding instruction
* @param[in] cg : CodeGenerator
*/
ARM64Trg1ZeroImmInstruction(TR::InstOpCode::Mnemonic op, TR::Node *node, TR::Register *treg,
uint32_t imm,
TR::Instruction *precedingInstruction, TR::CodeGenerator *cg)
: ARM64Trg1Instruction(op, node, treg, precedingInstruction, cg), _source1Immediate(imm), _Nbit(false)
{
}

/*
* @brief Constructor
* @param[in] op : instruction opcode
* @param[in] node : node
* @param[in] treg : target register
* @param[in] N : N bit value
* @param[in] imm : immediate value
* @param[in] precedingInstruction : preceding instruction
* @param[in] cg : CodeGenerator
*/
ARM64Trg1ZeroImmInstruction(TR::InstOpCode::Mnemonic op, TR::Node *node, TR::Register *treg,
bool N, uint32_t imm,
TR::Instruction *precedingInstruction, TR::CodeGenerator *cg)
: ARM64Trg1Instruction(op, node, treg, precedingInstruction, cg), _source1Immediate(imm), _Nbit(N)
{
}

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

/**
* @brief Gets source immediate
* @return source immediate
*/
uint32_t getSourceImmediate() {return _source1Immediate;}
/**
* @brief Sets source immediate
* @param[in] si : immediate value
* @return source immediate
*/
uint32_t setSourceImmediate(uint32_t si) {return (_source1Immediate = si);}

/**
* @brief Gets the N bit (bit 22)
* @return N bit value
*/
bool getNbit() { return _Nbit;}
/**
* @brief Sets the N bit (bit 22)
* @param[in] n : N bit value
* @return N bit value
*/
bool setNbit(bool n) { return (_Nbit = n);}

/**
* @brief Sets zero register in binary encoding
* @param[in] instruction : instruction cursor
*/
void insertZeroRegister(uint32_t *instruction)
{
TR::RealRegister *zeroReg = cg()->machine()->getRealRegister(TR::RealRegister::xzr);
zeroReg->setRegisterFieldRN(instruction);
}

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

/**
* @brief Sets N bit (bit 22) field in binary encoding
* @param[in] instruction : instruction cursor
*/
void insertNbit(uint32_t *instruction)
{
if (_Nbit)
{
*instruction |= (1 << 22);
}
}

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


class ARM64Trg1Src1ImmInstruction : public ARM64Trg1Src1Instruction
{
uint32_t _source1Immediate;
Expand Down
11 changes: 11 additions & 0 deletions compiler/aarch64/codegen/GenerateInstructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,17 @@ TR::Instruction *generateNegInstruction(TR::CodeGenerator *cg, TR::Node *node,
return new (cg->trHeapMemory()) TR::ARM64Trg1ZeroSrc1Instruction(op, node, treg, sreg, cg);
}

TR::Instruction *generateMovBitMaskInstruction(TR::CodeGenerator *cg, TR::Node *node,
TR::Register *treg, bool N, uint32_t imm, bool is64bit, TR::Instruction *preced)
{
/* Alias of ORR instruction */
TR::InstOpCode::Mnemonic op = is64bit ? TR::InstOpCode::orrimmx : TR::InstOpCode::orrimmw;

if (preced)
return new (cg->trHeapMemory()) TR::ARM64Trg1ZeroImmInstruction(op, node, treg, N, imm, preced, cg);
return new (cg->trHeapMemory()) TR::ARM64Trg1ZeroImmInstruction(op, node,treg, N, imm, cg);
}

TR::Instruction *generateMulInstruction(TR::CodeGenerator *cg, TR::Node *node,
TR::Register *treg, TR::Register *s1reg, TR::Register *s2reg, TR::Instruction *preced)
{
Expand Down
20 changes: 20 additions & 0 deletions compiler/aarch64/codegen/GenerateInstructions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -922,6 +922,26 @@ TR::Instruction *generateNegInstruction(
bool is64bit = false,
TR::Instruction *preced = NULL);

/*
* @brief Generates MOV (bitmask immediate) instruction
* @param[in] cg : CodeGenerator
* @param[in] node : node
* @param[in] treg : target register
* @param[in] N : N bit (bit 22) value
* @param[in] imm : immediate value
* @param[in] is64bit : true when it is 64-bit operation
* @param[in] preced : preceding instruction
* @return generated instruction
*/
TR::Instruction *generateMovBitMaskInstruction(
TR::CodeGenerator *cg,
TR::Node *node,
TR::Register *treg,
bool N,
uint32_t imm,
bool is64bit = true,
TR::Instruction *preced = NULL);

/*
* @brief Generates MUL (register) instruction
* @param[in] cg : CodeGenerator
Expand Down
1 change: 1 addition & 0 deletions compiler/aarch64/codegen/OMRInstructionKindEnum.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
IsTrg1Imm,
IsTrg1ImmSym,
IsTrg1ZeroSrc1,
IsTrg1ZeroImm,
IsTrg1Src1,
IsTrg1Src1Imm,
IsTrg1Src2,
Expand Down
Loading