@@ -366,26 +366,51 @@ StringRef ARM::getArchExtFeature(StringRef ArchExt) {
366
366
}
367
367
368
368
static ARM::FPUKind findDoublePrecisionFPU (ARM::FPUKind InputFPUKind) {
369
+ if (InputFPUKind == ARM::FK_INVALID || InputFPUKind == ARM::FK_NONE)
370
+ return ARM::FK_INVALID;
371
+
369
372
const ARM::FPUName &InputFPU = ARM::FPUNames[InputFPUKind];
370
373
371
374
// If the input FPU already supports double-precision, then there
372
375
// 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)
380
397
return ARM::FK_INVALID;
381
398
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
+
382
406
// 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.
385
408
for (const ARM::FPUName &CandidateFPU : ARM::FPUNames) {
386
409
if (CandidateFPU.FPUVer == InputFPU.FPUVer &&
387
410
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 )) {
389
414
return CandidateFPU.ID ;
390
415
}
391
416
}
@@ -420,20 +445,35 @@ bool ARM::appendArchExtFeatures(StringRef CPU, ARM::ArchKind AK,
420
445
CPU = " generic" ;
421
446
422
447
if (ArchExt == " fp" || ArchExt == " fp.dp" ) {
448
+ const ARM::FPUKind DefaultFPU = getDefaultFPU (CPU, AK);
423
449
ARM::FPUKind FPUKind;
424
450
if (ArchExt == " fp.dp" ) {
451
+ const bool IsDP = ArgFPUKind != ARM::FK_INVALID &&
452
+ ArgFPUKind != ARM::FK_NONE &&
453
+ isDoublePrecision (getFPURestriction (ArgFPUKind));
425
454
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 ;
428
469
}
429
- FPUKind = findDoublePrecisionFPU (getDefaultFPU (CPU, AK));
430
470
} else if (Negated) {
431
471
FPUKind = ARM::FK_NONE;
432
472
} else {
433
- FPUKind = getDefaultFPU (CPU, AK) ;
473
+ FPUKind = DefaultFPU ;
434
474
}
435
475
ArgFPUKind = FPUKind;
436
- return ARM::getFPUFeatures (FPUKind, Features) ;
476
+ return true ;
437
477
}
438
478
return StartingNumFeatures != Features.size ();
439
479
}
0 commit comments