@@ -165,6 +165,21 @@ void X86_64ABIInfo::classify(mlir::Type Ty, uint64_t OffsetBase, Class &Lo,
165165      Current = Class::SSE;
166166      return ;
167167
168+     } else  if  (mlir::isa<LongDoubleType>(Ty)) {
169+       const  llvm::fltSemantics *LDF =
170+           &getContext ().getTargetInfo ().getLongDoubleFormat ();
171+       if  (LDF == &llvm::APFloat::IEEEquad ()) {
172+         Lo = Class::SSE;
173+         Hi = Class::SSEUp;
174+       } else  if  (LDF == &llvm::APFloat::x87DoubleExtended ()) {
175+         Lo = Class::X87;
176+         Hi = Class::X87Up;
177+       } else  if  (LDF == &llvm::APFloat::IEEEdouble ()) {
178+         Current = Class::SSE;
179+       } else  {
180+         llvm_unreachable (" unexpected long double representation!" 
181+       }
182+       return ;
168183    } else  if  (mlir::isa<BoolType>(Ty)) {
169184      Current = Class::Integer;
170185    } else  if  (const  auto  RT = mlir::dyn_cast<StructType>(Ty)) {
@@ -267,6 +282,65 @@ void X86_64ABIInfo::classify(mlir::Type Ty, uint64_t OffsetBase, Class &Lo,
267282  cir_cconv_unreachable (" NYI" 
268283}
269284
285+ ABIArgInfo X86_64ABIInfo::getIndirectResult (mlir::Type ty,
286+                                             unsigned  freeIntRegs) const  {
287+   //  If this is a scalar LLVM value then assume LLVM will pass it in the right
288+   //  place naturally.
289+   // 
290+   //  This assumption is optimistic, as there could be free registers available
291+   //  when we need to pass this argument in memory, and LLVM could try to pass
292+   //  the argument in the free register. This does not seem to happen currently,
293+   //  but this code would be much safer if we could mark the argument with
294+   //  'onstack'. See PR12193.
295+   if  (!isAggregateTypeForABI (ty) /*  && IsIllegalVectorType(Ty) &&*/ 
296+       /* !Ty->isBitIntType()*/ 
297+     //  FIXME: Handling enum type?
298+ 
299+     return  (isPromotableIntegerTypeForABI (ty) ? ABIArgInfo::getExtend (ty)
300+                                               : ABIArgInfo::getDirect ());
301+   }
302+ 
303+   if  (CIRCXXABI::RecordArgABI RAA = getRecordArgABI (ty, getCXXABI ()))
304+     return  getNaturalAlignIndirect (ty, RAA == CIRCXXABI::RAA_DirectInMemory);
305+ 
306+   //  Compute the byval alignment. We specify the alignment of the byval in all
307+   //  cases so that the mid-level optimizer knows the alignment of the byval.
308+   unsigned  align = std::max (getContext ().getTypeAlign (ty) / 8 , 8U );
309+ 
310+   //  Attempt to avoid passing indirect results using byval when possible. This
311+   //  is important for good codegen.
312+   // 
313+   //  We do this by coercing the value into a scalar type which the backend can
314+   //  handle naturally (i.e., without using byval).
315+   // 
316+   //  For simplicity, we currently only do this when we have exhausted all of the
317+   //  free integer registers. Doing this when there are free integer registers
318+   //  would require more care, as we would have to ensure that the coerced value
319+   //  did not claim the unused register. That would require either reording the
320+   //  arguments to the function (so that any subsequent inreg values came first),
321+   //  or only doing this optimization when there were no following arguments that
322+   //  might be inreg.
323+   // 
324+   //  We currently expect it to be rare (particularly in well written code) for
325+   //  arguments to be passed on the stack when there are still free integer
326+   //  registers available (this would typically imply large structs being passed
327+   //  by value), so this seems like a fair tradeoff for now.
328+   // 
329+   //  We can revisit this if the backend grows support for 'onstack' parameter
330+   //  attributes. See PR12193.
331+   if  (freeIntRegs == 0 ) {
332+     uint64_t  size = getContext ().getTypeSize (ty);
333+ 
334+     //  If this type fits in an eightbyte, coerce it into the matching integral
335+     //  type, which will end up on the stack (with alignment 8).
336+     if  (align == 8  && size <= 64 )
337+       return  ABIArgInfo::getDirect (
338+           cir::IntType::get (LT.getMLIRContext (), size, false ));
339+   }
340+ 
341+   return  ABIArgInfo::getIndirect (align);
342+ }
343+ 
270344// / Return a type that will be passed by the backend in the low 8 bytes of an
271345// / XMM register, corresponding to the SSE class.
272346mlir::Type X86_64ABIInfo::GetSSETypeAtOffset (mlir::Type IRType,
@@ -278,7 +352,7 @@ mlir::Type X86_64ABIInfo::GetSSETypeAtOffset(mlir::Type IRType,
278352      (unsigned )getContext ().getTypeSize (SourceTy) / 8  - SourceOffset;
279353  mlir::Type T0 = getFPTypeAtOffset (IRType, IROffset, TD);
280354  if  (!T0 || mlir::isa<mlir::Float64Type>(T0))
281-     return  T0;  //  NOTE( cir): Not sure if this is correct. 
355+     return  cir::DoubleType::get  (LT. getMLIRContext ()); 
282356
283357  mlir::Type T1 = {};
284358  unsigned  T0Size = TD.getTypeAllocSize (T0);
@@ -296,6 +370,8 @@ mlir::Type X86_64ABIInfo::GetSSETypeAtOffset(mlir::Type IRType,
296370      return  T0;
297371  }
298372
373+   return  cir::DoubleType::get (LT.getMLIRContext ());
374+ 
299375  cir_cconv_unreachable (" NYI" 
300376}
301377
@@ -539,13 +615,34 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(
539615    ++neededSSE;
540616    break ;
541617  }
618+   //  AMD64-ABI 3.2.3p3: Rule 1. If the class is MEMORY, pass the argument
619+   //  on the stack.
620+   case  Class::Memory:
621+ 
622+   //  AMD64-ABI 3.2.3p3: Rule 5. If the class is X87, X87UP or
623+   //  COMPLEX_X87, it is passed in memory.
624+   case  Class::X87:
625+   case  Class::ComplexX87:
626+     if  (getRecordArgABI (Ty, getCXXABI ()) == CIRCXXABI::RAA_Indirect)
627+       ++neededInt;
628+     return  getIndirectResult (Ty, freeIntRegs);
629+ 
630+   case  Class::SSEUp:
631+   case  Class::X87Up:
632+     llvm_unreachable (" Invalid classification for lo word." 
633+ 
542634  default :
543635    cir_cconv_assert_or_abort (!cir::MissingFeatures::X86ArgTypeClassification (),
544636                              " NYI" 
545637  }
546638
547639  mlir::Type HighPart = {};
548640  switch  (Hi) {
641+   case  Class::Memory:
642+   case  Class::X87:
643+   case  Class::ComplexX87:
644+     llvm_unreachable (" Invalid classification for hi word." 
645+ 
549646  case  Class::NoClass:
550647    break ;
551648
@@ -558,8 +655,23 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(
558655      return  ABIArgInfo::getDirect (HighPart, 8 );
559656    break ;
560657
561-   default :
562-     cir_cconv_unreachable (" NYI" 
658+   //  X87Up generally doesn't occur here (long double is passed in
659+   //  memory), except in situations involving unions.
660+   case  Class::X87Up:
661+   case  Class::SSE:
662+     ++neededSSE;
663+     HighPart = GetSSETypeAtOffset (Ty, 8 , Ty, 8 );
664+ 
665+     if  (Lo == Class::NoClass) //  Pass HighPart at offset 8 in memory.
666+       return  ABIArgInfo::getDirect (HighPart, 8 );
667+     break ;
668+ 
669+   //  AMD64-ABI 3.2.3p3: Rule 4. If the class is SSEUP, the
670+   //  eightbyte is passed in the upper half of the last used SSE
671+   //  register.  This only happens when 128-bit vectors are passed.
672+   case  Class::SSEUp:
673+     llvm_unreachable (" NYI && We need to implement GetByteVectorType" 
674+     break ;
563675  }
564676
565677  //  If a high part was specified, merge it together with the low part.  It is
0 commit comments