// TODO-Cleanup: Abstract out the part of this that finds the addressing mode, and
// move it to Lower
virtual bool genCreateAddrMode(GenTree* addr,
- int mode,
bool fold,
- regMaskTP regMask,
bool* revPtr,
GenTree** rv1Ptr,
GenTree** rv2Ptr,
#if SCALED_ADDR_MODES
unsigned* mulPtr,
-#endif
- unsigned* cnsPtr,
- bool nogen = false);
+#endif // SCALED_ADDR_MODES
+ ssize_t* cnsPtr);
private:
#if defined(_TARGET_XARCH_)
* #endif
* *cnsPtr ... integer constant [optional]
*
- * The 'mode' parameter may have one of the following values:
- *
- * #if LEA_AVAILABLE
- * +1 ... we're trying to compute a value via 'LEA'
- * #endif
- *
- * 0 ... we're trying to form an address mode
- *
- * -1 ... we're generating code for an address mode,
- * and thus the address must already form an
- * address mode (without any further work)
- *
* IMPORTANT NOTE: This routine doesn't generate any code, it merely
* identifies the components that might be used to
* form an address mode later on.
*/
bool CodeGen::genCreateAddrMode(GenTree* addr,
- int mode,
bool fold,
- regMaskTP regMask,
bool* revPtr,
GenTree** rv1Ptr,
GenTree** rv2Ptr,
#if SCALED_ADDR_MODES
unsigned* mulPtr,
-#endif
- unsigned* cnsPtr,
- bool nogen)
+#endif // SCALED_ADDR_MODES
+ ssize_t* cnsPtr)
{
- assert(nogen == true);
-
/*
The following indirections are valid address modes on x86/x64:
ssize_t cns;
#if SCALED_ADDR_MODES
unsigned mul;
-#endif
+#endif // SCALED_ADDR_MODES
GenTree* tmp;
cns = 0;
#if SCALED_ADDR_MODES
mul = 0;
-#endif
+#endif // SCALED_ADDR_MODES
AGAIN:
/* We come back to 'AGAIN' if we have an add of a constant, and we are folding that
#if SCALED_ADDR_MODES
assert(mul == 0);
-#endif
+#endif // SCALED_ADDR_MODES
/* Special case: keep constants as 'op2' */
goto FOUND_AM;
}
break;
-#endif
+#endif // SCALED_ADDR_MODES && !defined(_TARGET_ARMARCH_)
default:
break;
case GT_NOP:
- if (!nogen)
- {
- break;
- }
-
op1 = op1->gtOp.gtOp1;
goto AGAIN;
case GT_COMMA:
- if (!nogen)
- {
- break;
- }
-
op1 = op1->gtOp.gtOp2;
goto AGAIN;
case GT_NOP:
- if (!nogen)
- {
- break;
- }
-
op2 = op2->gtOp.gtOp1;
goto AGAIN;
case GT_COMMA:
- if (!nogen)
- {
- break;
- }
-
op2 = op2->gtOp.gtOp2;
goto AGAIN;
#if SCALED_ADDR_MODES
*mulPtr = mul;
#endif
- // TODO-Cleanup: The offset is signed and it should be returned as such. See also
- // GenTreeAddrMode::gtOffset and its associated cleanup note.
- *cnsPtr = (unsigned)cns;
+ *cnsPtr = cns;
return true;
}
// TODO-Cleanup: Abstract out the part of this that finds the addressing mode, and
// move it to Lower
virtual bool genCreateAddrMode(GenTree* addr,
- int mode,
bool fold,
- regMaskTP regMask,
bool* revPtr,
GenTree** rv1Ptr,
GenTree** rv2Ptr,
#if SCALED_ADDR_MODES
unsigned* mulPtr,
-#endif
- unsigned* cnsPtr,
- bool nogen = false) = 0;
+#endif // SCALED_ADDR_MODES
+ ssize_t* cnsPtr) = 0;
void genCalcFrameSize();
bool rev;
#if SCALED_ADDR_MODES
unsigned mul;
-#endif
- unsigned cns;
+#endif // SCALED_ADDR_MODES
+ ssize_t cns;
GenTree* base;
GenTree* idx;
}
}
if ((doAddrMode) &&
- codeGen->genCreateAddrMode(addr, // address
- 0, // mode
- false, // fold
- RBM_NONE, // reg mask
- &rev, // reverse ops
- &base, // base addr
- &idx, // index val
+ codeGen->genCreateAddrMode(addr, // address
+ false, // fold
+ &rev, // reverse ops
+ &base, // base addr
+ &idx, // index val
#if SCALED_ADDR_MODES
- &mul, // scaling
-#endif
- &cns, // displacement
- true)) // don't generate code
+ &mul, // scaling
+#endif // SCALED_ADDR_MODES
+ &cns)) // displacement
{
// We can form a complex addressing mode, so mark each of the interior
// nodes with GTF_ADDRMODE_NO_CSE and calculate a more accurate cost.
unsigned gtScale; // The scale factor
private:
- // TODO-Cleanup: gtOffset should be changed to 'int' to match the getter function and avoid accidental
- // zero extension to 64 bit. However, this is used by legacy code and initialized, via the offset
- // parameter of the constructor, by Lowering::TryCreateAddrMode & CodeGenInterface::genCreateAddrMode.
- // The later computes the offset as 'ssize_t' but returns it as 'unsigned'. We should change
- // genCreateAddrMode to return 'int' or 'ssize_t' and then update this as well.
- unsigned gtOffset; // The offset to add
+ ssize_t gtOffset; // The offset to add
public:
- GenTreeAddrMode(var_types type, GenTree* base, GenTree* index, unsigned scale, unsigned offset)
+ GenTreeAddrMode(var_types type, GenTree* base, GenTree* index, unsigned scale, ssize_t offset)
: GenTreeOp(GT_LEA, type, base, index)
{
assert(base != nullptr || index != nullptr);
GenTree* base = nullptr;
GenTree* index = nullptr;
unsigned scale = 0;
- unsigned offset = 0;
+ ssize_t offset = 0;
bool rev = false;
// TODO-1stClassStructs: This logic is here to preserve prior behavior. Note that previously
}
// Find out if an addressing mode can be constructed
- bool doAddrMode =
- comp->codeGen->genCreateAddrMode(addr, -1, true, 0, &rev, &base, &index, &scale, &offset, true /*nogen*/);
+ bool doAddrMode = comp->codeGen->genCreateAddrMode(addr, // address
+ true, // fold
+ &rev, // reverse ops
+ &base, // base addr
+ &index, // index val
+#if SCALED_ADDR_MODES
+ &scale, // scaling
+#endif // SCALED_ADDR_MODES
+ &offset); // displacement
if (scale == 0)
{
DISPNODE(base);
if (index != nullptr)
{
- JITDUMP(" + Index * %u + %u\n ", scale, offset);
+ JITDUMP(" + Index * %u + %d\n ", scale, offset);
DISPNODE(index);
}
else
{
- JITDUMP(" + %u\n", offset);
+ JITDUMP(" + %d\n", offset);
}
var_types addrModeType = addr->TypeGet();