@@ -366,26 +366,50 @@ 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
+
372
+ const ARM::FPUName &InputFPU = ARM::FPUNames[InputFPUKind];
373
+
374
+ if (ARM::isDoublePrecision (InputFPU.Restriction ))
375
+ return InputFPUKind;
376
+
377
+ // Otherwise, look for an FPU entry with all the same fields, except
378
+ // that it supports double precision.
379
+ for (const ARM::FPUName &CandidateFPU : ARM::FPUNames) {
380
+ if (CandidateFPU.FPUVer == InputFPU.FPUVer &&
381
+ CandidateFPU.NeonSupport == InputFPU.NeonSupport &&
382
+ ARM::has32Regs (CandidateFPU.Restriction ) ==
383
+ ARM::has32Regs (InputFPU.Restriction ) &&
384
+ ARM::isDoublePrecision (CandidateFPU.Restriction )) {
385
+ return CandidateFPU.ID ;
386
+ }
387
+ }
388
+
389
+ // nothing found
390
+ return ARM::FK_INVALID;
391
+ }
392
+
393
+ static ARM::FPUKind findSinglePrecisionFPU (ARM::FPUKind InputFPUKind) {
394
+ if (InputFPUKind == ARM::FK_INVALID || InputFPUKind == ARM::FK_NONE)
395
+ return ARM::FK_INVALID;
396
+
369
397
const ARM::FPUName &InputFPU = ARM::FPUNames[InputFPUKind];
370
398
371
399
// If the input FPU already supports double-precision, then there
372
400
// isn't any different FPU we can return here.
373
401
//
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)
380
- return ARM::FK_INVALID;
402
+ if (!ARM::isDoublePrecision (InputFPU.Restriction ))
403
+ return InputFPUKind;
381
404
382
405
// 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.
406
+ // that it does not support double precision.
385
407
for (const ARM::FPUName &CandidateFPU : ARM::FPUNames) {
386
408
if (CandidateFPU.FPUVer == InputFPU.FPUVer &&
387
409
CandidateFPU.NeonSupport == InputFPU.NeonSupport &&
388
- CandidateFPU.Restriction == ARM::FPURestriction::D16) {
410
+ ARM::has32Regs (CandidateFPU.Restriction ) ==
411
+ ARM::has32Regs (InputFPU.Restriction ) &&
412
+ !ARM::isDoublePrecision (CandidateFPU.Restriction )) {
389
413
return CandidateFPU.ID ;
390
414
}
391
415
}
@@ -420,20 +444,35 @@ bool ARM::appendArchExtFeatures(StringRef CPU, ARM::ArchKind AK,
420
444
CPU = " generic" ;
421
445
422
446
if (ArchExt == " fp" || ArchExt == " fp.dp" ) {
447
+ const ARM::FPUKind DefaultFPU = getDefaultFPU (CPU, AK);
423
448
ARM::FPUKind FPUKind;
424
449
if (ArchExt == " fp.dp" ) {
450
+ const bool IsDP = ArgFPUKind != ARM::FK_INVALID &&
451
+ ArgFPUKind != ARM::FK_NONE &&
452
+ isDoublePrecision (getFPURestriction (ArgFPUKind));
425
453
if (Negated) {
426
- Features.push_back (" -fp64" );
427
- return true ;
454
+ /* If there is no FPU selected yet, we still need to set ArgFPUKind, as
455
+ * leaving it as FK_INVALID, would cause default FPU to be selected
456
+ * later and that could be double precision one. */
457
+ if (ArgFPUKind != ARM::FK_INVALID && !IsDP)
458
+ return true ;
459
+ FPUKind = findSinglePrecisionFPU (DefaultFPU);
460
+ if (FPUKind == ARM::FK_INVALID)
461
+ FPUKind = ARM::FK_NONE;
462
+ } else {
463
+ if (IsDP)
464
+ return true ;
465
+ FPUKind = findDoublePrecisionFPU (DefaultFPU);
466
+ if (FPUKind == ARM::FK_INVALID)
467
+ return false ;
428
468
}
429
- FPUKind = findDoublePrecisionFPU (getDefaultFPU (CPU, AK));
430
469
} else if (Negated) {
431
470
FPUKind = ARM::FK_NONE;
432
471
} else {
433
- FPUKind = getDefaultFPU (CPU, AK) ;
472
+ FPUKind = DefaultFPU ;
434
473
}
435
474
ArgFPUKind = FPUKind;
436
- return ARM::getFPUFeatures (FPUKind, Features) ;
475
+ return true ;
437
476
}
438
477
return StartingNumFeatures != Features.size ();
439
478
}
0 commit comments