@@ -366,26 +366,51 @@ StringRef ARM::getArchExtFeature(StringRef ArchExt) {
366366}
367367
368368static ARM::FPUKind findDoublePrecisionFPU (ARM::FPUKind InputFPUKind) {
369+ if (InputFPUKind == ARM::FK_INVALID || InputFPUKind == ARM::FK_NONE)
370+ return ARM::FK_INVALID;
371+
369372 const ARM::FPUName &InputFPU = ARM::FPUNames[InputFPUKind];
370373
371374 // If the input FPU already supports double-precision, then there
372375 // isn't any different FPU we can return here.
373- //
374- // The current available FPURestriction values are None (no
375- // restriction), D16 (only 16 d-regs) and SP_D16 (16 d-regs
376- // and single precision only); there's no value representing
377- // SP restriction without D16. So this test just means 'is it
378- // SP only?'.
379- if (InputFPU.Restriction != ARM::FPURestriction::SP_D16)
376+ if (ARM::isDoublePrecision (InputFPU.Restriction ))
377+ return InputFPUKind;
378+
379+ // Otherwise, look for an FPU entry with all the same fields, except
380+ // that it supports double precision.
381+ for (const ARM::FPUName &CandidateFPU : ARM::FPUNames) {
382+ if (CandidateFPU.FPUVer == InputFPU.FPUVer &&
383+ CandidateFPU.NeonSupport == InputFPU.NeonSupport &&
384+ ARM::has32Regs (CandidateFPU.Restriction ) ==
385+ ARM::has32Regs (InputFPU.Restriction ) &&
386+ ARM::isDoublePrecision (CandidateFPU.Restriction )) {
387+ return CandidateFPU.ID ;
388+ }
389+ }
390+
391+ // nothing found
392+ return ARM::FK_INVALID;
393+ }
394+
395+ static ARM::FPUKind findSinglePrecisionFPU (ARM::FPUKind InputFPUKind) {
396+ if (InputFPUKind == ARM::FK_INVALID || InputFPUKind == ARM::FK_NONE)
380397 return ARM::FK_INVALID;
381398
399+ const ARM::FPUName &InputFPU = ARM::FPUNames[InputFPUKind];
400+
401+ // If the input FPU already is single-precision only, then there
402+ // isn't any different FPU we can return here.
403+ if (!ARM::isDoublePrecision (InputFPU.Restriction ))
404+ return InputFPUKind;
405+
382406 // Otherwise, look for an FPU entry with all the same fields, except
383- // that SP_D16 has been replaced with just D16, representing adding
384- // double precision and not changing anything else.
407+ // that it does not support double precision.
385408 for (const ARM::FPUName &CandidateFPU : ARM::FPUNames) {
386409 if (CandidateFPU.FPUVer == InputFPU.FPUVer &&
387410 CandidateFPU.NeonSupport == InputFPU.NeonSupport &&
388- CandidateFPU.Restriction == ARM::FPURestriction::D16) {
411+ ARM::has32Regs (CandidateFPU.Restriction ) ==
412+ ARM::has32Regs (InputFPU.Restriction ) &&
413+ !ARM::isDoublePrecision (CandidateFPU.Restriction )) {
389414 return CandidateFPU.ID ;
390415 }
391416 }
@@ -420,20 +445,35 @@ bool ARM::appendArchExtFeatures(StringRef CPU, ARM::ArchKind AK,
420445 CPU = " generic" ;
421446
422447 if (ArchExt == " fp" || ArchExt == " fp.dp" ) {
448+ const ARM::FPUKind DefaultFPU = getDefaultFPU (CPU, AK);
423449 ARM::FPUKind FPUKind;
424450 if (ArchExt == " fp.dp" ) {
451+ const bool IsDP = ArgFPUKind != ARM::FK_INVALID &&
452+ ArgFPUKind != ARM::FK_NONE &&
453+ isDoublePrecision (getFPURestriction (ArgFPUKind));
425454 if (Negated) {
426- Features.push_back (" -fp64" );
427- return true ;
455+ /* If there is no FPU selected yet, we still need to set ArgFPUKind, as
456+ * leaving it as FK_INVALID, would cause default FPU to be selected
457+ * later and that could be double precision one. */
458+ if (ArgFPUKind != ARM::FK_INVALID && !IsDP)
459+ return true ;
460+ FPUKind = findSinglePrecisionFPU (DefaultFPU);
461+ if (FPUKind == ARM::FK_INVALID)
462+ FPUKind = ARM::FK_NONE;
463+ } else {
464+ if (IsDP)
465+ return true ;
466+ FPUKind = findDoublePrecisionFPU (DefaultFPU);
467+ if (FPUKind == ARM::FK_INVALID)
468+ return false ;
428469 }
429- FPUKind = findDoublePrecisionFPU (getDefaultFPU (CPU, AK));
430470 } else if (Negated) {
431471 FPUKind = ARM::FK_NONE;
432472 } else {
433- FPUKind = getDefaultFPU (CPU, AK) ;
473+ FPUKind = DefaultFPU ;
434474 }
435475 ArgFPUKind = FPUKind;
436- return ARM::getFPUFeatures (FPUKind, Features) ;
476+ return true ;
437477 }
438478 return StartingNumFeatures != Features.size ();
439479}
0 commit comments