@@ -6869,8 +6869,8 @@ GenTreeIntCon CodeGen::intForm(var_types type, ssize_t value)
68696869//
68706870void CodeGen::genLongReturn (GenTree* treeNode)
68716871{
6872- assert (treeNode->OperGet () == GT_RETURN || treeNode-> OperGet () == GT_RETFILT);
6873- assert (treeNode->TypeGet () == TYP_LONG);
6872+ assert (treeNode->OperIs ( GT_RETURN, GT_RETFILT) );
6873+ assert (treeNode->TypeIs ( TYP_LONG) );
68746874 GenTree* op1 = treeNode->gtGetOp1 ();
68756875 var_types targetType = treeNode->TypeGet ();
68766876
@@ -6894,16 +6894,16 @@ void CodeGen::genLongReturn(GenTree* treeNode)
68946894// In case of LONG return on 32-bit, delegates to the genLongReturn method.
68956895//
68966896// Arguments:
6897- // treeNode - The GT_RETURN or GT_RETFILT tree node.
6897+ // treeNode - The GT_RETURN/ GT_RETFILT/GT_SWIFT_ERROR_RET tree node.
68986898//
68996899// Return Value:
69006900// None
69016901//
69026902void CodeGen::genReturn (GenTree* treeNode)
69036903{
6904- assert (treeNode->OperIs (GT_RETURN, GT_RETFILT));
6904+ assert (treeNode->OperIs (GT_RETURN, GT_RETFILT, GT_SWIFT_ERROR_RET ));
69056905
6906- GenTree* op1 = treeNode->gtGetOp1 ();
6906+ GenTree* op1 = treeNode->AsOp ()-> GetReturnValue ();
69076907 var_types targetType = treeNode->TypeGet ();
69086908
69096909 // A void GT_RETFILT is the end of a finally. For non-void filter returns we need to load the result in the return
@@ -7005,7 +7005,7 @@ void CodeGen::genReturn(GenTree* treeNode)
70057005 //
70067006 // There should be a single GT_RETURN while generating profiler ELT callbacks.
70077007 //
7008- if (treeNode->OperIs (GT_RETURN) && compiler->compIsProfilerHookNeeded ())
7008+ if (treeNode->OperIs (GT_RETURN, GT_SWIFT_ERROR_RET ) && compiler->compIsProfilerHookNeeded ())
70097009 {
70107010 // !! NOTE !!
70117011 // Since we are invalidating the assumption that we would slip into the epilog
@@ -7075,18 +7075,28 @@ void CodeGen::genReturn(GenTree* treeNode)
70757075
70767076 genStackPointerCheck (doStackPointerCheck, compiler->lvaReturnSpCheck );
70777077#endif // defined(DEBUG) && defined(TARGET_XARCH)
7078+ }
70787079
70797080#ifdef SWIFT_SUPPORT
7080- // If this method has a SwiftError* out parameter, load the SwiftError pseudolocal value into the error register.
7081- // TODO-CQ: Introduce GenTree node that models returning a normal and Swift error value.
7082- if (compiler->lvaSwiftErrorArg != BAD_VAR_NUM)
7083- {
7084- assert (compiler->info .compCallConv == CorInfoCallConvExtension::Swift);
7085- assert (compiler->lvaSwiftErrorLocal != BAD_VAR_NUM);
7086- GetEmitter ()->emitIns_R_S (ins_Load (TYP_I_IMPL), EA_PTRSIZE, REG_SWIFT_ERROR, compiler->lvaSwiftErrorLocal , 0 );
7087- }
7088- #endif // SWIFT_SUPPORT
7081+ // ------------------------------------------------------------------------
7082+ // genSwiftErrorReturn: Generates code for returning the normal return value,
7083+ // and loading the SwiftError pseudolocal value in the error register.
7084+ //
7085+ // Arguments:
7086+ // treeNode - The GT_SWIFT_ERROR_RET tree node.
7087+ //
7088+ // Return Value:
7089+ // None
7090+ //
7091+ void CodeGen::genSwiftErrorReturn (GenTree* treeNode)
7092+ {
7093+ assert (treeNode->OperIs (GT_SWIFT_ERROR_RET));
7094+ GenTree* swiftErrorNode = treeNode->gtGetOp1 ();
7095+ const regNumber errorSrcReg = genConsumeReg (swiftErrorNode);
7096+ inst_Mov (swiftErrorNode->TypeGet (), REG_SWIFT_ERROR, errorSrcReg, true , EA_PTRSIZE);
7097+ genReturn (treeNode);
70897098}
7099+ #endif // SWIFT_SUPPORT
70907100
70917101// ------------------------------------------------------------------------
70927102// isStructReturn: Returns whether the 'treeNode' is returning a struct.
@@ -7095,15 +7105,15 @@ void CodeGen::genReturn(GenTree* treeNode)
70957105// treeNode - The tree node to evaluate whether is a struct return.
70967106//
70977107// Return Value:
7098- // Returns true if the 'treeNode" is a GT_RETURN node of type struct.
7108+ // Returns true if the 'treeNode' is a GT_RETURN/GT_SWIFT_ERROR_RET node of type struct.
70997109// Otherwise returns false.
71007110//
71017111bool CodeGen::isStructReturn (GenTree* treeNode)
71027112{
7103- // This method could be called for 'treeNode' of GT_RET_FILT or GT_RETURN.
7113+ // This method could be called for 'treeNode' of GT_RET_FILT/ GT_RETURN/GT_SWIFT_ERROR_RET .
71047114 // For the GT_RET_FILT, the return is always a bool or a void, for the end of a finally block.
7105- noway_assert (treeNode->OperGet () == GT_RETURN || treeNode-> OperGet () == GT_RETFILT );
7106- if (treeNode->OperGet () != GT_RETURN)
7115+ noway_assert (treeNode->OperIs ( GT_RETURN, GT_RETFILT, GT_SWIFT_ERROR_RET) );
7116+ if (! treeNode->OperIs ( GT_RETURN, GT_SWIFT_ERROR_RET) )
71077117 {
71087118 return false ;
71097119 }
@@ -7130,13 +7140,13 @@ bool CodeGen::isStructReturn(GenTree* treeNode)
71307140//
71317141void CodeGen::genStructReturn (GenTree* treeNode)
71327142{
7133- assert (treeNode->OperGet () == GT_RETURN);
7134-
7135- genConsumeRegs (treeNode->gtGetOp1 ());
7143+ assert (treeNode->OperIs (GT_RETURN, GT_SWIFT_ERROR_RET));
71367144
7137- GenTree* op1 = treeNode->gtGetOp1 ();
7145+ GenTree* op1 = treeNode->AsOp ()-> GetReturnValue ();
71387146 GenTree* actualOp1 = op1->gtSkipReloadOrCopy ();
71397147
7148+ genConsumeRegs (op1);
7149+
71407150 ReturnTypeDesc retTypeDesc = compiler->compRetTypeDesc ;
71417151 const unsigned regCount = retTypeDesc.GetReturnRegCount ();
71427152 assert (regCount <= MAX_RET_REG_COUNT);
0 commit comments