@@ -710,7 +710,11 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
710
710
setExceptionSelectorRegister (ARM::R1);
711
711
}
712
712
713
- setOperationAction (ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand);
713
+ if (Subtarget->getTargetTriple ().isWindowsItaniumEnvironment ())
714
+ setOperationAction (ISD::DYNAMIC_STACKALLOC, MVT::i32, Custom);
715
+ else
716
+ setOperationAction (ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand);
717
+
714
718
// ARMv6 Thumb1 (except for CPUs that support dmb / dsb) and earlier use
715
719
// the default expansion.
716
720
if (Subtarget->hasAnyDataBarrier () && !Subtarget->isThumb1Only ()) {
@@ -983,6 +987,8 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
983
987
984
988
case ARMISD::PRELOAD: return " ARMISD::PRELOAD" ;
985
989
990
+ case ARMISD::WIN__CHKSTK: return " ARMISD:::WIN__CHKSTK" ;
991
+
986
992
case ARMISD::VCEQ: return " ARMISD::VCEQ" ;
987
993
case ARMISD::VCEQZ: return " ARMISD::VCEQZ" ;
988
994
case ARMISD::VCGE: return " ARMISD::VCGE" ;
@@ -6214,6 +6220,10 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
6214
6220
case ISD::FSINCOS: return LowerFSINCOS (Op, DAG);
6215
6221
case ISD::SDIVREM:
6216
6222
case ISD::UDIVREM: return LowerDivRem (Op, DAG);
6223
+ case ISD::DYNAMIC_STACKALLOC:
6224
+ if (Subtarget->getTargetTriple ().isWindowsItaniumEnvironment ())
6225
+ return LowerDYNAMIC_STACKALLOC (Op, DAG);
6226
+ llvm_unreachable (" Don't know how to custom lower this!" );
6217
6227
}
6218
6228
}
6219
6229
@@ -7112,6 +7122,73 @@ ARMTargetLowering::EmitStructByval(MachineInstr *MI,
7112
7122
return BB;
7113
7123
}
7114
7124
7125
+ MachineBasicBlock *
7126
+ ARMTargetLowering::EmitLowered__chkstk (MachineInstr *MI,
7127
+ MachineBasicBlock *MBB) const {
7128
+ const TargetMachine &TM = getTargetMachine ();
7129
+ const TargetInstrInfo &TII = *TM.getInstrInfo ();
7130
+ DebugLoc DL = MI->getDebugLoc ();
7131
+
7132
+ assert (Subtarget->isTargetWindows () &&
7133
+ " __chkstk is only supported on Windows" );
7134
+ assert (Subtarget->isThumb2 () && " Windows on ARM requires Thumb-2 mode" );
7135
+
7136
+ // __chkstk takes the number of words to allocate on the stack in R4, and
7137
+ // returns the stack adjustment in number of bytes in R4. This will not
7138
+ // clober any other registers (other than the obvious lr).
7139
+ //
7140
+ // Although, technically, IP should be considered a register which may be
7141
+ // clobbered, the call itself will not touch it. Windows on ARM is a pure
7142
+ // thumb-2 environment, so there is no interworking required. As a result, we
7143
+ // do not expect a veneer to be emitted by the linker, clobbering IP.
7144
+ //
7145
+ // Each module recieves its own copy of __chkstk, so no import thunk is
7146
+ // required, again, ensuring that IP is not clobbered.
7147
+ //
7148
+ // Finally, although some linkers may theoretically provide a trampoline for
7149
+ // out of range calls (which is quite common due to a 32M range limitation of
7150
+ // branches for Thumb), we can generate the long-call version via
7151
+ // -mcmodel=large, alleviating the need for the trampoline which may clobber
7152
+ // IP.
7153
+
7154
+ switch (TM.getCodeModel ()) {
7155
+ case CodeModel::Small:
7156
+ case CodeModel::Medium:
7157
+ case CodeModel::Default:
7158
+ case CodeModel::Kernel:
7159
+ BuildMI (*MBB, MI, DL, TII.get (ARM::tBL))
7160
+ .addImm ((unsigned )ARMCC::AL).addReg (0 )
7161
+ .addExternalSymbol (" __chkstk" )
7162
+ .addReg (ARM::R4, RegState::Implicit | RegState::Kill)
7163
+ .addReg (ARM::R4, RegState::Implicit | RegState::Define)
7164
+ .addReg (ARM::R12, RegState::Implicit | RegState::Define | RegState::Dead);
7165
+ break ;
7166
+ case CodeModel::Large:
7167
+ case CodeModel::JITDefault: {
7168
+ MachineRegisterInfo &MRI = MBB->getParent ()->getRegInfo ();
7169
+ unsigned Reg = MRI.createVirtualRegister (&ARM::rGPRRegClass);
7170
+
7171
+ BuildMI (*MBB, MI, DL, TII.get (ARM::t2MOVi32imm), Reg)
7172
+ .addExternalSymbol (" __chkstk" );
7173
+ BuildMI (*MBB, MI, DL, TII.get (ARM::tBLXr))
7174
+ .addImm ((unsigned )ARMCC::AL).addReg (0 )
7175
+ .addReg (Reg, RegState::Kill)
7176
+ .addReg (ARM::R4, RegState::Implicit | RegState::Kill)
7177
+ .addReg (ARM::R4, RegState::Implicit | RegState::Define)
7178
+ .addReg (ARM::R12, RegState::Implicit | RegState::Define | RegState::Dead);
7179
+ break ;
7180
+ }
7181
+ }
7182
+
7183
+ AddDefaultCC (AddDefaultPred (BuildMI (*MBB, MI, DL, TII.get (ARM::t2SUBrr),
7184
+ ARM::SP)
7185
+ .addReg (ARM::SP, RegState::Define)
7186
+ .addReg (ARM::R4, RegState::Kill)));
7187
+
7188
+ MI->eraseFromParent ();
7189
+ return MBB;
7190
+ }
7191
+
7115
7192
MachineBasicBlock *
7116
7193
ARMTargetLowering::EmitInstrWithCustomInserter (MachineInstr *MI,
7117
7194
MachineBasicBlock *BB) const {
@@ -7361,6 +7438,8 @@ ARMTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
7361
7438
case ARM::COPY_STRUCT_BYVAL_I32:
7362
7439
++NumLoopByVals;
7363
7440
return EmitStructByval (MI, BB);
7441
+ case ARM::WIN__CHKSTK:
7442
+ return EmitLowered__chkstk (MI, BB);
7364
7443
}
7365
7444
}
7366
7445
@@ -10481,6 +10560,32 @@ SDValue ARMTargetLowering::LowerDivRem(SDValue Op, SelectionDAG &DAG) const {
10481
10560
return CallInfo.first ;
10482
10561
}
10483
10562
10563
+ SDValue
10564
+ ARMTargetLowering::LowerDYNAMIC_STACKALLOC (SDValue Op, SelectionDAG &DAG) const {
10565
+ assert (Subtarget->isTargetWindows () && " unsupported target platform" );
10566
+ SDLoc DL (Op);
10567
+
10568
+ // Get the inputs.
10569
+ SDValue Chain = Op.getOperand (0 );
10570
+ SDValue Size = Op.getOperand (1 );
10571
+
10572
+ SDValue Words = DAG.getNode (ISD::SRL, DL, MVT::i32, Size ,
10573
+ DAG.getConstant (2 , MVT::i32));
10574
+
10575
+ SDValue Flag;
10576
+ Chain = DAG.getCopyToReg (Chain, DL, ARM::R4, Words, Flag);
10577
+ Flag = Chain.getValue (1 );
10578
+
10579
+ SDVTList NodeTys = DAG.getVTList (MVT::i32, MVT::Glue);
10580
+ Chain = DAG.getNode (ARMISD::WIN__CHKSTK, DL, NodeTys, Chain, Flag);
10581
+
10582
+ SDValue NewSP = DAG.getCopyFromReg (Chain, DL, ARM::SP, MVT::i32);
10583
+ Chain = NewSP.getValue (1 );
10584
+
10585
+ SDValue Ops[2 ] = { NewSP, Chain };
10586
+ return DAG.getMergeValues (Ops, DL);
10587
+ }
10588
+
10484
10589
bool
10485
10590
ARMTargetLowering::isOffsetFoldingLegal (const GlobalAddressSDNode *GA) const {
10486
10591
// The ARM target isn't yet aware of offsets.
0 commit comments