Skip to content
Open
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
51 changes: 39 additions & 12 deletions src/coreclr/jit/codegenriscv64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
//
// ins reg1, reg2, imm
//
// However the imm might not fit as a directly encodable immediate,
// when it doesn't fit we generate extra instruction(s) that sets up
// The immediate value may not fit as a directly encodable immediate.
// In that case, additional instruction(s) are generated to set up
// the 'regTmp' with the proper immediate value.
//
// mov regTmp, imm
Expand Down Expand Up @@ -60,7 +60,7 @@ bool CodeGen::genInstrWithConstant(instruction ins,

// reg1 is usually a dest register
// reg2 is always source register
assert(tmpReg != reg2); // tmpReg can not match any source register
assert(tmpReg != reg2); // tmpReg cannot match any source register

#ifdef DEBUG
switch (ins)
Expand Down Expand Up @@ -99,7 +99,7 @@ bool CodeGen::genInstrWithConstant(instruction ins,
}
else
{
// caller can specify REG_NA for tmpReg, when it "knows" that the immediate will always fit
// caller can specify REG_NA for tmpReg, when it "knows" that the immediate will always fit
assert(tmpReg != REG_NA);

// generate two or more instructions
Expand Down Expand Up @@ -133,8 +133,7 @@ bool CodeGen::genInstrWithConstant(instruction ins,
// genStackPointerAdjustment: add a specified constant value to the stack pointer in either the prolog
// or the epilog. The unwind codes for the generated instructions are produced. An available temporary
// register is required to be specified, in case the constant is too large to encode in an "add"
// instruction, such that we need to load the constant
// into a register first, before using it.
// instruction, such that we need to load the constant into a register first, before using it.
//
// Arguments:
// spDelta - the value to add to SP (can be negative)
Expand Down Expand Up @@ -184,7 +183,7 @@ void CodeGen::genStackPointerAdjustment(ssize_t spDelta, regNumber tmpReg, bool*
// we need to use (SD) are encodable with the stack-pointer immediate offsets we need to use.
//
// The caller can tell us to fold in a stack pointer adjustment, which we will do with the first instruction.
// Note that the stack pointer adjustment must be by a multiple of 16 to preserve the invariant that the
// Note that the stack pointer adjustment must be a multiple of 16 to preserve the invariant that the
// stack pointer is always 16 byte aligned. If we are saving an odd number of callee-saved
// registers, though, we will have an empty alignment slot somewhere. It turns out we will put
// it below (at a lower address) the callee-saved registers, as that is currently how we
Expand Down Expand Up @@ -912,6 +911,31 @@ void CodeGen::instGen_Set_Reg_To_Imm(emitAttr size,
regSet.verifyRegUsed(reg);
}

//------------------------------------------------------------------------
// genSetRegToConst: Generate code to load a constant value into a register.
//
// Arguments:
// targetReg - The destination register to receive the constant value.
// targetType - The type of the value being loaded.
// tree - The GenTree node representing the constant.
//
// Assumptions:
// - 'tree' is a constant node of type GT_CNS_INT or GT_CNS_DBL.
// - For floating-point constants, a temporary integer register is
// available when required.
//
// Notes:
// Integer constants are materialized using appropriate immediate load
// sequences, with the detailed instruction selection delegated to
// instGen_Set_Reg_To_Imm.
//
// Floating-point constants whose bit patterns can be materialized using
// a single integer immediate instruction are first constructed in a
// temporary integer register using `addi` or `lui`, and then transferred
// to the FP register via `fmv_w_x` or `fmv_d_x`. For all other floating-point
// constants, the value is emitted into the data section and loaded
// from memory.
//
void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTree* tree)
{
switch (tree->gtOper)
Expand Down Expand Up @@ -1010,7 +1034,8 @@ void CodeGen::genCodeForIncSaturate(GenTree* tree)
genProduceReg(tree);
}

// Generate code to get the high N bits of a N*N=2N bit multiplication result
// Generate code to get the upper N bits of a 2N-bit product
// Multiplying two N-bit operands yields a 2N-bit result; this method keeps the high half
void CodeGen::genCodeForMulHi(GenTreeOp* treeNode)
{
assert(!treeNode->gtOverflowEx());
Expand Down Expand Up @@ -1063,7 +1088,7 @@ void CodeGen::genCodeForMulHi(GenTreeOp* treeNode)
}

// Generate code for ADD, SUB, MUL, AND, AND_NOT, OR, OR_NOT, XOR, and XOR_NOT
// This method is expected to have called genConsumeOperands() before calling it.
// genConsumeOperands() is expected to have been called before this method is invoked.
void CodeGen::genCodeForBinary(GenTreeOp* treeNode)
{
const genTreeOps oper = treeNode->OperGet();
Expand Down Expand Up @@ -1718,12 +1743,14 @@ void CodeGen::genCodeForBswap(GenTree* tree)
}

//------------------------------------------------------------------------
// genCodeForDivMod: Produce code for a GT_DIV/GT_UDIV node.
// (1) float/double MOD is morphed into a helper call by front-end.
// genCodeForDivMod: Produce code for a GT_DIV/GT_UDIV/GT_MOD/GT_UMOD node.
//
// Arguments:
// tree - the node
//
// Notes:
// float/double MOD is morphed into a helper call by front-end.
//
void CodeGen::genCodeForDivMod(GenTreeOp* tree)
{
assert(tree->OperIs(GT_MOD, GT_UMOD, GT_DIV, GT_UDIV));
Expand Down Expand Up @@ -6087,7 +6114,7 @@ void CodeGen::genCodeForSlliUw(GenTreeOp* tree)
// Arguments:
// delta - the offset to add to the current stack pointer to establish the frame pointer
// reportUnwindData - true if establishing the frame pointer should be reported in the OS unwind data.

//
void CodeGen::genEstablishFramePointer(int delta, bool reportUnwindData)
{
assert(compiler->compGeneratingProlog);
Expand Down
Loading