@@ -156,6 +156,17 @@ static const MCPhysReg GPRArgRegs[] = {
156
156
ARM::R0, ARM::R1, ARM::R2, ARM::R3
157
157
};
158
158
159
+ static SDValue handleCMSEValue(const SDValue &Value, const ISD::InputArg &Arg,
160
+ SelectionDAG &DAG, const SDLoc &DL) {
161
+ assert(Arg.ArgVT.isScalarInteger());
162
+ assert(Arg.ArgVT.bitsLT(MVT::i32));
163
+ SDValue Trunc = DAG.getNode(ISD::TRUNCATE, DL, Arg.ArgVT, Value);
164
+ SDValue Ext =
165
+ DAG.getNode(Arg.Flags.isSExt() ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, DL,
166
+ MVT::i32, Trunc);
167
+ return Ext;
168
+ }
169
+
159
170
void ARMTargetLowering::addTypeForNEON(MVT VT, MVT PromotedLdStVT) {
160
171
if (VT != PromotedLdStVT) {
161
172
setOperationAction(ISD::LOAD, VT, Promote);
@@ -2193,7 +2204,7 @@ SDValue ARMTargetLowering::LowerCallResult(
2193
2204
SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool isVarArg,
2194
2205
const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
2195
2206
SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals, bool isThisReturn,
2196
- SDValue ThisVal) const {
2207
+ SDValue ThisVal, bool isCmseNSCall ) const {
2197
2208
// Assign locations to each value returned by this call.
2198
2209
SmallVector<CCValAssign, 16> RVLocs;
2199
2210
CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
@@ -2271,6 +2282,15 @@ SDValue ARMTargetLowering::LowerCallResult(
2271
2282
(VA.getValVT() == MVT::f16 || VA.getValVT() == MVT::bf16))
2272
2283
Val = MoveToHPR(dl, DAG, VA.getLocVT(), VA.getValVT(), Val);
2273
2284
2285
+ // On CMSE Non-secure Calls, call results (returned values) whose bitwidth
2286
+ // is less than 32 bits must be sign- or zero-extended after the call for
2287
+ // security reasons. Although the ABI mandates an extension done by the
2288
+ // callee, the latter cannot be trusted to follow the rules of the ABI.
2289
+ const ISD::InputArg &Arg = Ins[VA.getValNo()];
2290
+ if (isCmseNSCall && Arg.ArgVT.isScalarInteger() &&
2291
+ VA.getLocVT().isScalarInteger() && Arg.ArgVT.bitsLT(MVT::i32))
2292
+ Val = handleCMSEValue(Val, Arg, DAG, dl);
2293
+
2274
2294
InVals.push_back(Val);
2275
2295
}
2276
2296
@@ -2882,7 +2902,7 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
2882
2902
// return.
2883
2903
return LowerCallResult(Chain, InGlue, CallConv, isVarArg, Ins, dl, DAG,
2884
2904
InVals, isThisReturn,
2885
- isThisReturn ? OutVals[0] : SDValue());
2905
+ isThisReturn ? OutVals[0] : SDValue(), isCmseNSCall );
2886
2906
}
2887
2907
2888
2908
/// HandleByVal - Every parameter *after* a byval parameter is passed
@@ -4485,8 +4505,6 @@ SDValue ARMTargetLowering::LowerFormalArguments(
4485
4505
*DAG.getContext());
4486
4506
CCInfo.AnalyzeFormalArguments(Ins, CCAssignFnForCall(CallConv, isVarArg));
4487
4507
4488
- SmallVector<SDValue, 16> ArgValues;
4489
- SDValue ArgValue;
4490
4508
Function::const_arg_iterator CurOrigArg = MF.getFunction().arg_begin();
4491
4509
unsigned CurArgIdx = 0;
4492
4510
@@ -4541,6 +4559,7 @@ SDValue ARMTargetLowering::LowerFormalArguments(
4541
4559
// Arguments stored in registers.
4542
4560
if (VA.isRegLoc()) {
4543
4561
EVT RegVT = VA.getLocVT();
4562
+ SDValue ArgValue;
4544
4563
4545
4564
if (VA.needsCustom() && VA.getLocVT() == MVT::v2f64) {
4546
4565
// f64 and vector types are split up into multiple registers or
@@ -4604,16 +4623,6 @@ SDValue ARMTargetLowering::LowerFormalArguments(
4604
4623
case CCValAssign::BCvt:
4605
4624
ArgValue = DAG.getNode(ISD::BITCAST, dl, VA.getValVT(), ArgValue);
4606
4625
break;
4607
- case CCValAssign::SExt:
4608
- ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue,
4609
- DAG.getValueType(VA.getValVT()));
4610
- ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
4611
- break;
4612
- case CCValAssign::ZExt:
4613
- ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue,
4614
- DAG.getValueType(VA.getValVT()));
4615
- ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
4616
- break;
4617
4626
}
4618
4627
4619
4628
// f16 arguments have their size extended to 4 bytes and passed as if they
@@ -4623,6 +4632,15 @@ SDValue ARMTargetLowering::LowerFormalArguments(
4623
4632
(VA.getValVT() == MVT::f16 || VA.getValVT() == MVT::bf16))
4624
4633
ArgValue = MoveToHPR(dl, DAG, VA.getLocVT(), VA.getValVT(), ArgValue);
4625
4634
4635
+ // On CMSE Entry Functions, formal integer arguments whose bitwidth is
4636
+ // less than 32 bits must be sign- or zero-extended in the callee for
4637
+ // security reasons. Although the ABI mandates an extension done by the
4638
+ // caller, the latter cannot be trusted to follow the rules of the ABI.
4639
+ const ISD::InputArg &Arg = Ins[VA.getValNo()];
4640
+ if (AFI->isCmseNSEntryFunction() && Arg.ArgVT.isScalarInteger() &&
4641
+ RegVT.isScalarInteger() && Arg.ArgVT.bitsLT(MVT::i32))
4642
+ ArgValue = handleCMSEValue(ArgValue, Arg, DAG, dl);
4643
+
4626
4644
InVals.push_back(ArgValue);
4627
4645
} else { // VA.isRegLoc()
4628
4646
// Only arguments passed on the stack should make it here.
0 commit comments