Skip to content

Commit

Permalink
RISC-V: refactor instruction encoding macros
Browse files Browse the repository at this point in the history
This commit replaces `TR_RISCV_?TYPE()` macros with (inline) functions
and provide overloaded versions for easier use. This provides a nicer
instruction encoding interface for encoding snippets.

Signed-off-by: Jan Vrany <jan.vrany@fit.cvut.cz>
  • Loading branch information
janvrany committed Dec 2, 2020
1 parent db64908 commit d5418ee
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 44 deletions.
52 changes: 8 additions & 44 deletions compiler/riscv/codegen/RVInstruction.cpp
Expand Up @@ -23,7 +23,6 @@

#include <stddef.h> // for NULL
#include <stdint.h> // for int32_t, uint32_t, etc
#include <riscv.h>
#include "codegen/CodeGenerator.hpp" // for CodeGenerator, etc
#include "codegen/InstOpCode.hpp" // for InstOpCode, etc
#include "codegen/Instruction.hpp" // for Instruction
Expand All @@ -50,19 +49,6 @@
#include "codegen/RVOutOfLineCodeSection.hpp"
#include "codegen/GenerateInstructions.hpp"

#define TR_RISCV_RTYPE(insn, rd, rs1, rs2) \
((insn) | ((rd) << OP_SH_RD) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2))
#define TR_RISCV_ITYPE(insn, rd, rs1, imm) \
((insn) | ((rd) << OP_SH_RD) | ((rs1) << OP_SH_RS1) | ENCODE_ITYPE_IMM(imm))
#define TR_RISCV_STYPE(insn, rs1, rs2, imm) \
((insn) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2) | ENCODE_STYPE_IMM(imm))
#define TR_RISCV_SBTYPE(insn, rs1, rs2, target) \
((insn) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2) | ENCODE_SBTYPE_IMM(target))
#define TR_RISCV_UTYPE(insn, rd, bigimm) \
((insn) | ((rd) << OP_SH_RD) | ENCODE_UTYPE_IMM(bigimm))
#define TR_RISCV_UJTYPE(insn, rd, target) \
((insn) | ((rd) << OP_SH_RD) | ENCODE_UJTYPE_IMM(target))

// TR::RtypeInstruction:: member functions

bool TR::RtypeInstruction::refsRegister(TR::Register *reg)
Expand Down Expand Up @@ -128,10 +114,7 @@ uint8_t *TR::RtypeInstruction::generateBinaryEncoding() {
uint8_t *cursor = instructionStart;
uint32_t *iPtr = (uint32_t*)instructionStart;

*iPtr = TR_RISCV_RTYPE ((uint32_t)(getOpCode().getOpCodeBinaryEncoding()),
toRealRegister(getTargetRegister())->binaryRegCode(),
toRealRegister(getSource1Register())->binaryRegCode(),
toRealRegister(getSource2Register())->binaryRegCode());
*iPtr = TR_RISCV_RTYPE(getOpCode().getMnemonic(), getTargetRegister(), getSource1Register(), getSource2Register());

cursor += RISCV_INSTRUCTION_LENGTH;
setBinaryLength(RISCV_INSTRUCTION_LENGTH);
Expand Down Expand Up @@ -191,10 +174,7 @@ uint8_t *TR::ItypeInstruction::generateBinaryEncoding() {
uint8_t *cursor = instructionStart;
uint32_t *iPtr = (uint32_t*)instructionStart;

*iPtr = TR_RISCV_ITYPE ((uint32_t)(getOpCode().getOpCodeBinaryEncoding()),
toRealRegister(getTargetRegister())->binaryRegCode(),
toRealRegister(getSource1Register())->binaryRegCode(),
getSourceImmediate());
*iPtr = TR_RISCV_ITYPE(getOpCode().getMnemonic(), getTargetRegister(), getSource1Register(), getSourceImmediate());

cursor += RISCV_INSTRUCTION_LENGTH;
setBinaryLength(RISCV_INSTRUCTION_LENGTH);
Expand Down Expand Up @@ -250,10 +230,7 @@ uint8_t *TR::LoadInstruction::generateBinaryEncoding() {
uint8_t *cursor = instructionStart;
uint32_t *iPtr = (uint32_t*)instructionStart;

*iPtr = TR_RISCV_ITYPE ((uint32_t)(getOpCode().getOpCodeBinaryEncoding()),
toRealRegister(getTargetRegister())->binaryRegCode(),
toRealRegister(getMemoryBase())->binaryRegCode(),
getMemoryReference()->getOffset(true));
*iPtr = TR_RISCV_ITYPE (getOpCode().getMnemonic(), getTargetRegister(), getMemoryBase(), getMemoryReference()->getOffset(true));

cursor += RISCV_INSTRUCTION_LENGTH;
setBinaryLength(RISCV_INSTRUCTION_LENGTH);
Expand Down Expand Up @@ -313,10 +290,7 @@ uint8_t *TR::StypeInstruction::generateBinaryEncoding() {
uint8_t *cursor = instructionStart;
uint32_t *iPtr = (uint32_t*)instructionStart;

*iPtr = TR_RISCV_STYPE ((uint32_t)(getOpCode().getOpCodeBinaryEncoding()),
toRealRegister(getSource1Register())->binaryRegCode(),
toRealRegister(getSource2Register())->binaryRegCode(),
getSourceImmediate());
*iPtr = TR_RISCV_STYPE (getOpCode().getMnemonic(), getSource1Register(), getSource2Register(), getSourceImmediate());

cursor += RISCV_INSTRUCTION_LENGTH;
setBinaryLength(RISCV_INSTRUCTION_LENGTH);
Expand Down Expand Up @@ -372,10 +346,7 @@ uint8_t *TR::StoreInstruction::generateBinaryEncoding() {
uint8_t *cursor = instructionStart;
uint32_t *iPtr = (uint32_t*)instructionStart;

*iPtr = TR_RISCV_STYPE ((uint32_t)(getOpCode().getOpCodeBinaryEncoding()),
toRealRegister(getMemoryBase())->binaryRegCode(),
toRealRegister(getSource1Register())->binaryRegCode(),
getMemoryReference()->getOffset(true));
*iPtr = TR_RISCV_STYPE (getOpCode().getMnemonic(), getMemoryBase(), getSource1Register(), getMemoryReference()->getOffset(true));

cursor += RISCV_INSTRUCTION_LENGTH;
setBinaryLength(RISCV_INSTRUCTION_LENGTH);
Expand All @@ -393,10 +364,7 @@ uint8_t *TR::BtypeInstruction::generateBinaryEncoding()

TR::LabelSymbol *label = getLabelSymbol();

*iPtr = TR_RISCV_SBTYPE ((uint32_t)(getOpCode().getOpCodeBinaryEncoding()),
toRealRegister(getSource1Register())->binaryRegCode(),
toRealRegister(getSource2Register())->binaryRegCode(),
0 /* to fix up in the future */ );
*iPtr = TR_RISCV_SBTYPE (getOpCode().getMnemonic(), getSource1Register(), getSource2Register(), 0 /* to fix up in the future */ );

if (label->getCodeLocation() != NULL) {
// we already know the address
Expand Down Expand Up @@ -498,9 +466,7 @@ uint8_t *TR::UtypeInstruction::generateBinaryEncoding() {
uint8_t *cursor = instructionStart;
uint32_t *iPtr = (uint32_t*)instructionStart;

*iPtr = TR_RISCV_UTYPE ((uint32_t)(getOpCode().getOpCodeBinaryEncoding()),
toRealRegister(getTargetRegister())->binaryRegCode(),
_imm);
*iPtr = TR_RISCV_UTYPE (getOpCode().getMnemonic(), getTargetRegister(), _imm);

cursor += RISCV_INSTRUCTION_LENGTH;
setBinaryLength(RISCV_INSTRUCTION_LENGTH);
Expand Down Expand Up @@ -546,9 +512,7 @@ uint8_t *TR::JtypeInstruction::generateBinaryEncoding() {
}

TR_ASSERT(VALID_UJTYPE_IMM(offset), "Jump offset out of range");
*iPtr = TR_RISCV_UJTYPE ((uint32_t)(getOpCode().getOpCodeBinaryEncoding()),
toRealRegister(getTargetRegister())->binaryRegCode(),
offset);
*iPtr = TR_RISCV_UJTYPE (getOpCode().getMnemonic(), getTargetRegister(), offset);

cursor += RISCV_INSTRUCTION_LENGTH;
setBinaryLength(RISCV_INSTRUCTION_LENGTH);
Expand Down
87 changes: 87 additions & 0 deletions compiler/riscv/codegen/RVInstruction.hpp
Expand Up @@ -24,8 +24,11 @@

#include <stddef.h>
#include <stdint.h>
#include <riscv.h>

#include "codegen/CodeGenerator.hpp"
#include "codegen/Register.hpp"
#include "codegen/InstOpCode.hpp"
#include "codegen/Instruction.hpp"
#include "codegen/MemoryReference.hpp"
#include "il/LabelSymbol.hpp"
Expand All @@ -35,6 +38,90 @@ namespace TR { class SymbolReference; }

#define RISCV_INSTRUCTION_LENGTH 4

static inline uint32_t
TR_RISCV_RTYPE(uint32_t insn, uint32_t rd, uint32_t rs1, uint32_t rs2)
{
return ((insn) | ((rd) << OP_SH_RD) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2));
}

static inline uint32_t
TR_RISCV_RTYPE(TR::InstOpCode::Mnemonic insn, TR::Register *rd, TR::Register *rs1, TR::Register *rs2)
{
return TR_RISCV_RTYPE(TR::InstOpCode::getOpCodeBinaryEncoding(insn), toRealRegister(rd)->binaryRegCode(), toRealRegister(rs1)->binaryRegCode(), toRealRegister(rs2)->binaryRegCode());
}


static inline uint32_t
TR_RISCV_ITYPE(uint32_t insn, uint32_t rd, uint32_t rs1, uint32_t imm)
{
return ((insn) | ((rd) << OP_SH_RD) | ((rs1) << OP_SH_RS1) | ENCODE_ITYPE_IMM(imm));
}

static inline uint32_t
TR_RISCV_ITYPE(TR::InstOpCode::Mnemonic insn, TR::Register *rd, TR::Register *rs1, uint32_t imm)
{
return TR_RISCV_ITYPE(TR::InstOpCode::getOpCodeBinaryEncoding(insn), toRealRegister(rd)->binaryRegCode(), toRealRegister(rs1)->binaryRegCode(), imm);
}


static inline uint32_t
TR_RISCV_STYPE(uint32_t insn, uint32_t rs1, uint32_t rs2, uint32_t imm)
{
return ((insn) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2) | ENCODE_STYPE_IMM(imm));
}

static inline uint32_t
TR_RISCV_STYPE(TR::InstOpCode::Mnemonic insn, TR::Register *rs1, TR::Register *rs2, uint32_t imm)
{
return TR_RISCV_STYPE(TR::InstOpCode::getOpCodeBinaryEncoding(insn), toRealRegister(rs1)->binaryRegCode(), toRealRegister(rs2)->binaryRegCode(), imm);
}


static inline uint32_t
TR_RISCV_SBTYPE(uint32_t insn, uint32_t rs1, uint32_t rs2, uint32_t imm)
{
return ((insn) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2) | ENCODE_SBTYPE_IMM(imm));
}

static inline uint32_t
TR_RISCV_SBTYPE(TR::InstOpCode::Mnemonic insn, TR::Register *rs1, TR::Register *rs2, uint32_t imm)
{
return TR_RISCV_SBTYPE(TR::InstOpCode::getOpCodeBinaryEncoding(insn), toRealRegister(rs1)->binaryRegCode(), toRealRegister(rs2)->binaryRegCode(), imm);
}


static inline uint32_t
TR_RISCV_UTYPE(uint32_t insn, uint32_t rd, uint32_t bigimm)
{
return ((insn) | ((rd) << OP_SH_RD) | ENCODE_UTYPE_IMM(bigimm));
}

static inline uint32_t
TR_RISCV_UTYPE(TR::InstOpCode::Mnemonic insn, TR::Register *rd, uint32_t bigimm)
{
return TR_RISCV_UTYPE(TR::InstOpCode::getOpCodeBinaryEncoding(insn), toRealRegister(rd)->binaryRegCode(), bigimm);
}


static inline uint32_t
TR_RISCV_UJTYPE(uint32_t insn, uint32_t rd, uint32_t target)
{
return ((insn) | ((rd) << OP_SH_RD) | ENCODE_UJTYPE_IMM(target));
}

static inline uint32_t
TR_RISCV_UJTYPE(TR::InstOpCode::Mnemonic insn, TR::Register *rd, uint32_t target)
{
return TR_RISCV_UJTYPE(TR::InstOpCode::getOpCodeBinaryEncoding(insn), toRealRegister(rd)->binaryRegCode(), target);
}

static inline uint32_t
TR_RISCV_UJTYPE(TR::InstOpCode &insn, TR::Register *rd, uint32_t target)
{
return TR_RISCV_UJTYPE(insn.getMnemonic(), rd, target);
}


namespace TR
{

Expand Down

0 comments on commit d5418ee

Please sign in to comment.