// So, after we save `A7` on the stack in prolog, it has to copy the stack slot of the split struct
// which was passed by the caller. Here we load the stack slot to `REG_SCRATCH`, and save it
// on the stack following the `A7` in prolog.
- GetEmitter()->emitIns_R_R_Imm(INS_ld_d, size, REG_SCRATCH, REG_SPBASE, genTotalFrameSize());
+ if (emitter::isValidSimm12(genTotalFrameSize()))
+ {
+ GetEmitter()->emitIns_R_R_I(INS_ld_d, size, REG_SCRATCH, REG_SPBASE, genTotalFrameSize());
+ }
+ else
+ {
+ assert(!EA_IS_RELOC(size));
+ GetEmitter()->emitIns_I_la(size, REG_SCRATCH, genTotalFrameSize());
+ GetEmitter()->emitIns_R_R_R(INS_ldx_d, size, REG_SCRATCH, REG_SPBASE, REG_SCRATCH);
+ }
+
if (emitter::isValidSimm12(baseOffset))
{
GetEmitter()->emitIns_S_R(INS_st_d, size, REG_SCRATCH, varNum, TARGET_POINTER_SIZE);
}
/*****************************************************************************
-*
-* Add an instruction referencing two registers and a constant.
-* Also checks for a large immediate that needs a second instruction
-* and will load it in reg1
-*
-*/
-void emitter::emitIns_R_R_Imm(instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, ssize_t imm)
-{
- assert(isGeneralRegister(reg1));
- assert(reg1 != reg2);
-
- bool immFits = true;
-
-#ifdef DEBUG
- switch (ins)
- {
- case INS_addi_w:
- case INS_addi_d:
- case INS_ld_d:
- immFits = isValidSimm12(imm);
- break;
-
- case INS_andi:
- case INS_ori:
- case INS_xori:
- immFits = (0 <= imm) && (imm <= 0xfff);
- break;
-
- default:
- assert(!"Unsupported instruction in emitIns_R_R_Imm");
- }
-#endif
-
- if (immFits)
- {
- emitIns_R_R_I(ins, attr, reg1, reg2, imm);
- }
- else
- {
- // Load 'imm' into the reg1 register
- // then issue: 'ins' reg1, reg2, reg1
- //
- assert(!EA_IS_RELOC(attr));
- emitIns_I_la(attr, reg1, imm);
- assert(ins == INS_ld_d);
- emitIns_R_R_R(INS_ldx_d, attr, reg1, reg2, reg1);
- }
-}
-
-/*****************************************************************************
*
* Add an instruction referencing three registers.
*/
void emitIns_R_R_I(
instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, ssize_t imm, insOpts opt = INS_OPTS_NONE);
-// Checks for a large immediate that needs a second instruction
-void emitIns_R_R_Imm(instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, ssize_t imm);
-
void emitIns_R_R_R(
instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, regNumber reg3, insOpts opt = INS_OPTS_NONE);