mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-04-03 18:32:50 +00:00
[AArch64] Make the use of FP instructions optional, but enabled by default.
This adds a new subtarget feature called FPARMv8 (implied by NEON), and predicates the support of the FP instructions and registers on this feature. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193739 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0f5e68e3dc
commit
c2884320fe
@ -21,8 +21,11 @@ include "llvm/Target/Target.td"
|
||||
// AArch64 Subtarget features.
|
||||
//
|
||||
|
||||
def FeatureFPARMv8 : SubtargetFeature<"fp-armv8", "HasFPARMv8", "true",
|
||||
"Enable ARMv8 FP">;
|
||||
|
||||
def FeatureNEON : SubtargetFeature<"neon", "HasNEON", "true",
|
||||
"Enable Advanced SIMD instructions">;
|
||||
"Enable Advanced SIMD instructions", [FeatureFPARMv8]>;
|
||||
|
||||
def FeatureCrypto : SubtargetFeature<"crypto", "HasCrypto", "true",
|
||||
"Enable cryptographic instructions">;
|
||||
@ -33,7 +36,8 @@ def FeatureCrypto : SubtargetFeature<"crypto", "HasCrypto", "true",
|
||||
|
||||
include "AArch64Schedule.td"
|
||||
|
||||
def : Processor<"generic", GenericItineraries, [FeatureNEON, FeatureCrypto]>;
|
||||
def : Processor<"generic", GenericItineraries,
|
||||
[FeatureFPARMv8, FeatureNEON, FeatureCrypto]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Register File Description
|
||||
|
@ -50,10 +50,13 @@ AArch64TargetLowering::AArch64TargetLowering(AArch64TargetMachine &TM)
|
||||
// Scalar register <-> type mapping
|
||||
addRegisterClass(MVT::i32, &AArch64::GPR32RegClass);
|
||||
addRegisterClass(MVT::i64, &AArch64::GPR64RegClass);
|
||||
addRegisterClass(MVT::f16, &AArch64::FPR16RegClass);
|
||||
addRegisterClass(MVT::f32, &AArch64::FPR32RegClass);
|
||||
addRegisterClass(MVT::f64, &AArch64::FPR64RegClass);
|
||||
addRegisterClass(MVT::f128, &AArch64::FPR128RegClass);
|
||||
|
||||
if (Subtarget->hasFPARMv8()) {
|
||||
addRegisterClass(MVT::f16, &AArch64::FPR16RegClass);
|
||||
addRegisterClass(MVT::f32, &AArch64::FPR32RegClass);
|
||||
addRegisterClass(MVT::f64, &AArch64::FPR64RegClass);
|
||||
addRegisterClass(MVT::f128, &AArch64::FPR128RegClass);
|
||||
}
|
||||
|
||||
if (Subtarget->hasNEON()) {
|
||||
// And the vectors
|
||||
@ -961,24 +964,31 @@ AArch64TargetLowering::SaveVarArgRegisters(CCState &CCInfo, SelectionDAG &DAG,
|
||||
}
|
||||
}
|
||||
|
||||
if (getSubtarget()->hasFPARMv8()) {
|
||||
unsigned FPRSaveSize = 16 * (NumFPRArgRegs - FirstVariadicFPR);
|
||||
int FPRIdx = 0;
|
||||
if (FPRSaveSize != 0) {
|
||||
FPRIdx = MFI->CreateStackObject(FPRSaveSize, 16, false);
|
||||
// According to the AArch64 Procedure Call Standard, section B.1/B.3, we
|
||||
// can omit a register save area if we know we'll never use registers of
|
||||
// that class.
|
||||
if (FPRSaveSize != 0) {
|
||||
FPRIdx = MFI->CreateStackObject(FPRSaveSize, 16, false);
|
||||
|
||||
SDValue FIN = DAG.getFrameIndex(FPRIdx, getPointerTy());
|
||||
SDValue FIN = DAG.getFrameIndex(FPRIdx, getPointerTy());
|
||||
|
||||
for (unsigned i = FirstVariadicFPR; i < NumFPRArgRegs; ++i) {
|
||||
unsigned VReg = MF.addLiveIn(AArch64FPRArgRegs[i],
|
||||
&AArch64::FPR128RegClass);
|
||||
SDValue Val = DAG.getCopyFromReg(Chain, DL, VReg, MVT::f128);
|
||||
SDValue Store = DAG.getStore(Val.getValue(1), DL, Val, FIN,
|
||||
MachinePointerInfo::getStack(i * 16),
|
||||
false, false, 0);
|
||||
MemOps.push_back(Store);
|
||||
FIN = DAG.getNode(ISD::ADD, DL, getPointerTy(), FIN,
|
||||
DAG.getConstant(16, getPointerTy()));
|
||||
for (unsigned i = FirstVariadicFPR; i < NumFPRArgRegs; ++i) {
|
||||
unsigned VReg = MF.addLiveIn(AArch64FPRArgRegs[i],
|
||||
&AArch64::FPR128RegClass);
|
||||
SDValue Val = DAG.getCopyFromReg(Chain, DL, VReg, MVT::f128);
|
||||
SDValue Store = DAG.getStore(Val.getValue(1), DL, Val, FIN,
|
||||
MachinePointerInfo::getStack(i * 16),
|
||||
false, false, 0);
|
||||
MemOps.push_back(Store);
|
||||
FIN = DAG.getNode(ISD::ADD, DL, getPointerTy(), FIN,
|
||||
DAG.getConstant(16, getPointerTy()));
|
||||
}
|
||||
}
|
||||
FuncInfo->setVariadicFPRIdx(FPRIdx);
|
||||
FuncInfo->setVariadicFPRSize(FPRSaveSize);
|
||||
}
|
||||
|
||||
int StackIdx = MFI->CreateFixedObject(8, CCInfo.getNextStackOffset(), true);
|
||||
@ -986,8 +996,6 @@ AArch64TargetLowering::SaveVarArgRegisters(CCState &CCInfo, SelectionDAG &DAG,
|
||||
FuncInfo->setVariadicStackIdx(StackIdx);
|
||||
FuncInfo->setVariadicGPRIdx(GPRIdx);
|
||||
FuncInfo->setVariadicGPRSize(GPRSaveSize);
|
||||
FuncInfo->setVariadicFPRIdx(FPRIdx);
|
||||
FuncInfo->setVariadicFPRSize(FPRSaveSize);
|
||||
|
||||
if (!MemOps.empty()) {
|
||||
Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, &MemOps[0],
|
||||
|
@ -383,6 +383,8 @@ class A64I_extract<bit sf, bits<3> op, bit n,
|
||||
// Inherits Rd in 4-0
|
||||
}
|
||||
|
||||
let Predicates = [HasFPARMv8] in {
|
||||
|
||||
// Format for floating-point compare instructions.
|
||||
class A64I_fpcmp<bit m, bit s, bits<2> type, bits<2> op, bits<5> opcode2,
|
||||
dag outs, dag ins, string asmstr,
|
||||
@ -562,6 +564,8 @@ class A64I_fpimm<bit m, bit s, bits<2> type, bits<5> imm5,
|
||||
// Inherit Rd in 4-0
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Format for load-register (literal) instructions.
|
||||
class A64I_LDRlit<bits<2> opc, bit v,
|
||||
dag outs, dag ins, string asmstr,
|
||||
|
@ -14,6 +14,8 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ARM Instruction Predicate Definitions.
|
||||
//
|
||||
def HasFPARMv8 : Predicate<"Subtarget->hasFPARMv8()">,
|
||||
AssemblerPredicate<"FeatureFPARMv8", "fp-armv8">;
|
||||
def HasNEON : Predicate<"Subtarget->hasNEON()">,
|
||||
AssemblerPredicate<"FeatureNEON", "neon">;
|
||||
def HasCrypto : Predicate<"Subtarget->hasCrypto()">,
|
||||
@ -2195,7 +2197,7 @@ def FNMSUBdddd : A64I_fpdp3Impl<"fnmsub", FPR64, f64, 0b01, 0b1, 0b1, fnmsub>;
|
||||
|
||||
// Extra patterns for when we're allowed to optimise separate multiplication and
|
||||
// addition.
|
||||
let Predicates = [UseFusedMAC] in {
|
||||
let Predicates = [HasFPARMv8, UseFusedMAC] in {
|
||||
def : Pat<(f32 (fadd FPR32:$Ra, (f32 (fmul FPR32:$Rn, FPR32:$Rm)))),
|
||||
(FMADDssss FPR32:$Rn, FPR32:$Rm, FPR32:$Ra)>;
|
||||
def : Pat<(f32 (fsub FPR32:$Ra, (f32 (fmul FPR32:$Rn, FPR32:$Rm)))),
|
||||
@ -2351,6 +2353,7 @@ defm FCVTM : A64I_fptointRM<0b10, 0b0, "fcvtm">;
|
||||
defm FCVTZ : A64I_fptointRM<0b11, 0b0, "fcvtz">;
|
||||
defm FCVTA : A64I_fptointRM<0b00, 0b1, "fcvta">;
|
||||
|
||||
let Predicates = [HasFPARMv8] in {
|
||||
def : Pat<(i32 (fp_to_sint f32:$Rn)), (FCVTZSws $Rn)>;
|
||||
def : Pat<(i64 (fp_to_sint f32:$Rn)), (FCVTZSxs $Rn)>;
|
||||
def : Pat<(i32 (fp_to_uint f32:$Rn)), (FCVTZUws $Rn)>;
|
||||
@ -2359,6 +2362,7 @@ def : Pat<(i32 (fp_to_sint f64:$Rn)), (FCVTZSwd $Rn)>;
|
||||
def : Pat<(i64 (fp_to_sint f64:$Rn)), (FCVTZSxd $Rn)>;
|
||||
def : Pat<(i32 (fp_to_uint f64:$Rn)), (FCVTZUwd $Rn)>;
|
||||
def : Pat<(i64 (fp_to_uint f64:$Rn)), (FCVTZUxd $Rn)>;
|
||||
}
|
||||
|
||||
multiclass A64I_inttofp<bit o0, string asmop> {
|
||||
def CVTFsw : A64I_fpintI<0b0, 0b00, 0b00, {0, 1, o0}, FPR32, GPR32, asmop>;
|
||||
@ -2370,6 +2374,7 @@ multiclass A64I_inttofp<bit o0, string asmop> {
|
||||
defm S : A64I_inttofp<0b0, "scvtf">;
|
||||
defm U : A64I_inttofp<0b1, "ucvtf">;
|
||||
|
||||
let Predicates = [HasFPARMv8] in {
|
||||
def : Pat<(f32 (sint_to_fp i32:$Rn)), (SCVTFsw $Rn)>;
|
||||
def : Pat<(f32 (sint_to_fp i64:$Rn)), (SCVTFsx $Rn)>;
|
||||
def : Pat<(f64 (sint_to_fp i32:$Rn)), (SCVTFdw $Rn)>;
|
||||
@ -2378,16 +2383,19 @@ def : Pat<(f32 (uint_to_fp i32:$Rn)), (UCVTFsw $Rn)>;
|
||||
def : Pat<(f32 (uint_to_fp i64:$Rn)), (UCVTFsx $Rn)>;
|
||||
def : Pat<(f64 (uint_to_fp i32:$Rn)), (UCVTFdw $Rn)>;
|
||||
def : Pat<(f64 (uint_to_fp i64:$Rn)), (UCVTFdx $Rn)>;
|
||||
}
|
||||
|
||||
def FMOVws : A64I_fpintI<0b0, 0b00, 0b00, 0b110, GPR32, FPR32, "fmov">;
|
||||
def FMOVsw : A64I_fpintI<0b0, 0b00, 0b00, 0b111, FPR32, GPR32, "fmov">;
|
||||
def FMOVxd : A64I_fpintI<0b1, 0b01, 0b00, 0b110, GPR64, FPR64, "fmov">;
|
||||
def FMOVdx : A64I_fpintI<0b1, 0b01, 0b00, 0b111, FPR64, GPR64, "fmov">;
|
||||
|
||||
let Predicates = [HasFPARMv8] in {
|
||||
def : Pat<(i32 (bitconvert f32:$Rn)), (FMOVws $Rn)>;
|
||||
def : Pat<(f32 (bitconvert i32:$Rn)), (FMOVsw $Rn)>;
|
||||
def : Pat<(i64 (bitconvert f64:$Rn)), (FMOVxd $Rn)>;
|
||||
def : Pat<(f64 (bitconvert i64:$Rn)), (FMOVdx $Rn)>;
|
||||
}
|
||||
|
||||
def lane1_asmoperand : AsmOperandClass {
|
||||
let Name = "Lane1";
|
||||
@ -2410,11 +2418,13 @@ let DecoderMethod = "DecodeFMOVLaneInstruction" in {
|
||||
"fmov\t$Rd.d[$Lane], $Rn", [], NoItinerary>;
|
||||
}
|
||||
|
||||
let Predicates = [HasFPARMv8] in {
|
||||
def : InstAlias<"fmov $Rd, $Rn.2d[$Lane]",
|
||||
(FMOVxv GPR64:$Rd, VPR128:$Rn, lane1:$Lane), 0b0>;
|
||||
|
||||
def : InstAlias<"fmov $Rd.2d[$Lane], $Rn",
|
||||
(FMOVvx VPR128:$Rd, GPR64:$Rn, lane1:$Lane), 0b0>;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Floating-point immediate instructions
|
||||
@ -2508,11 +2518,15 @@ let mayLoad = 1 in {
|
||||
def LDRx_lit : A64I_LDRlitSimple<0b01, 0b0, GPR64>;
|
||||
}
|
||||
|
||||
let Predicates = [HasFPARMv8] in {
|
||||
def LDRs_lit : A64I_LDRlitSimple<0b00, 0b1, FPR32>;
|
||||
def LDRd_lit : A64I_LDRlitSimple<0b01, 0b1, FPR64>;
|
||||
}
|
||||
|
||||
let mayLoad = 1 in {
|
||||
let Predicates = [HasFPARMv8] in {
|
||||
def LDRq_lit : A64I_LDRlitSimple<0b10, 0b1, FPR128>;
|
||||
}
|
||||
|
||||
|
||||
def LDRSWx_lit : A64I_LDRlit<0b10, 0b0,
|
||||
@ -3106,6 +3120,7 @@ defm LS32
|
||||
defm LS64
|
||||
: A64I_LDRSTR_unsigned<"LS64", 0b11, 0b0, 0b0, "", GPR64, dword_addrparams>;
|
||||
|
||||
let Predicates = [HasFPARMv8] in {
|
||||
// STR/LDR to/from a B register
|
||||
defm LSFP8
|
||||
: A64I_LDRSTR_unsigned<"LSFP8", 0b00, 0b1, 0b0, "", FPR8, byte_addrparams>;
|
||||
@ -3124,6 +3139,7 @@ defm LSFP64
|
||||
defm LSFP128
|
||||
: A64I_LDRSTR_unsigned<"LSFP128", 0b00, 0b1, 0b1, "", FPR128,
|
||||
qword_addrparams>;
|
||||
}
|
||||
|
||||
//===------------------------------
|
||||
// 2.3 Signed loads
|
||||
@ -3579,10 +3595,13 @@ multiclass A64I_LSPsimple<bits<2> opc, bit v, RegisterClass SomeReg,
|
||||
|
||||
defm LSPair32 : A64I_LSPsimple<0b00, 0b0, GPR32, word_simm7, "LSPair32">;
|
||||
defm LSPair64 : A64I_LSPsimple<0b10, 0b0, GPR64, dword_simm7, "LSPair64">;
|
||||
|
||||
let Predicates = [HasFPARMv8] in {
|
||||
defm LSFPPair32 : A64I_LSPsimple<0b00, 0b1, FPR32, word_simm7, "LSFPPair32">;
|
||||
defm LSFPPair64 : A64I_LSPsimple<0b01, 0b1, FPR64, dword_simm7, "LSFPPair64">;
|
||||
defm LSFPPair128 : A64I_LSPsimple<0b10, 0b1, FPR128, qword_simm7,
|
||||
"LSFPPair128">;
|
||||
}
|
||||
|
||||
|
||||
def LDPSWx : A64I_LSPoffset<0b01, 0b0, 0b1,
|
||||
|
@ -26,10 +26,27 @@
|
||||
using namespace llvm;
|
||||
|
||||
AArch64Subtarget::AArch64Subtarget(StringRef TT, StringRef CPU, StringRef FS)
|
||||
: AArch64GenSubtargetInfo(TT, CPU, FS), HasNEON(false), HasCrypto(false),
|
||||
TargetTriple(TT) {
|
||||
: AArch64GenSubtargetInfo(TT, CPU, FS), HasFPARMv8(false), HasNEON(false),
|
||||
HasCrypto(false), TargetTriple(TT), CPUString(CPU) {
|
||||
|
||||
ParseSubtargetFeatures(CPU, FS);
|
||||
initializeSubtargetFeatures(CPU, FS);
|
||||
}
|
||||
|
||||
void AArch64Subtarget::initializeSubtargetFeatures(StringRef CPU,
|
||||
StringRef FS) {
|
||||
if (CPU.empty())
|
||||
CPUString = "generic";
|
||||
|
||||
std::string FullFS = FS;
|
||||
if (CPUString == "generic") {
|
||||
// Enable FP by default.
|
||||
if (FullFS.empty())
|
||||
FullFS = "+fp-armv8";
|
||||
else
|
||||
FullFS = "+fp-armv8," + FullFS;
|
||||
}
|
||||
|
||||
ParseSubtargetFeatures(CPU, FullFS);
|
||||
}
|
||||
|
||||
bool AArch64Subtarget::GVIsIndirectSymbol(const GlobalValue *GV,
|
||||
|
@ -28,11 +28,19 @@ class GlobalValue;
|
||||
|
||||
class AArch64Subtarget : public AArch64GenSubtargetInfo {
|
||||
protected:
|
||||
bool HasFPARMv8;
|
||||
bool HasNEON;
|
||||
bool HasCrypto;
|
||||
|
||||
/// TargetTriple - What processor and OS we're targeting.
|
||||
Triple TargetTriple;
|
||||
|
||||
/// CPUString - String name of used CPU.
|
||||
std::string CPUString;
|
||||
|
||||
private:
|
||||
void initializeSubtargetFeatures(StringRef CPU, StringRef FS);
|
||||
|
||||
public:
|
||||
/// This constructor initializes the data members to match that
|
||||
/// of the specified triple.
|
||||
@ -52,9 +60,11 @@ public:
|
||||
bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
|
||||
bool isTargetLinux() const { return TargetTriple.isOSLinux(); }
|
||||
|
||||
bool hasFPARMv8() const { return HasFPARMv8; }
|
||||
bool hasNEON() const { return HasNEON; }
|
||||
|
||||
bool hasCrypto() const { return HasCrypto; }
|
||||
|
||||
const std::string & getCPUString() const { return CPUString; }
|
||||
};
|
||||
} // End llvm namespace
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s
|
||||
; RUN: llc -mtriple=aarch64-none-linux-gnu -mattr=-fp-armv8 -verify-machineinstrs < %s | FileCheck --check-prefix=CHECK-NOFP %s
|
||||
|
||||
declare void @use_addr(i8*)
|
||||
|
||||
@ -66,16 +67,22 @@ define i64 @test_alloca_with_local(i64 %n) {
|
||||
}
|
||||
|
||||
define void @test_variadic_alloca(i64 %n, ...) {
|
||||
; CHECK-LABEL: test_variadic_alloca:
|
||||
; CHECK: test_variadic_alloca:
|
||||
|
||||
; CHECK: sub sp, sp, #208
|
||||
; CHECK: stp x29, x30, [sp, #192]
|
||||
; CHECK: add x29, sp, #192
|
||||
; CHECK: sub [[TMP:x[0-9]+]], x29, #192
|
||||
; CHECK: add x8, [[TMP]], #0
|
||||
; CHECK: str q7, [x8, #112]
|
||||
; CHECK-FP: str q7, [x8, #112]
|
||||
; [...]
|
||||
; CHECK: str q1, [x8, #16]
|
||||
; CHECK-FP: str q1, [x8, #16]
|
||||
|
||||
; CHECK-NOFP: sub sp, sp, #80
|
||||
; CHECK-NOFP: stp x29, x30, [sp, #64]
|
||||
; CHECK-NOFP: add x29, sp, #64
|
||||
; CHECK-NOFP: sub [[TMP:x[0-9]+]], x29, #64
|
||||
; CHECK-NOFP: add x8, [[TMP]], #0
|
||||
|
||||
%addr = alloca i8, i64 %n
|
||||
|
||||
@ -86,6 +93,10 @@ define void @test_variadic_alloca(i64 %n, ...) {
|
||||
; CHECK: sub sp, x29, #192
|
||||
; CHECK: ldp x29, x30, [sp, #192]
|
||||
; CHECK: add sp, sp, #208
|
||||
|
||||
; CHECK-NOFP: sub sp, x29, #64
|
||||
; CHECK-NOFP: ldp x29, x30, [sp, #64]
|
||||
; CHECK-NOFP: add sp, sp, #80
|
||||
}
|
||||
|
||||
define void @test_alloca_large_frame(i64 %n) {
|
||||
|
@ -1,4 +1,5 @@
|
||||
; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s
|
||||
; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -mattr=-fp-armv8 | FileCheck --check-prefix=CHECK-NOFP %s
|
||||
|
||||
@var32 = global i32 0
|
||||
@var64 = global i64 0
|
||||
@ -30,6 +31,7 @@ define void @test_floatcsel(float %lhs32, float %rhs32, double %lhs64, double %r
|
||||
|
||||
%tst1 = fcmp one float %lhs32, %rhs32
|
||||
; CHECK: fcmp {{s[0-9]+}}, {{s[0-9]+}}
|
||||
; CHECK-NOFP-NOT: fcmp
|
||||
%val1 = select i1 %tst1, i32 42, i32 52
|
||||
store i32 %val1, i32* @var32
|
||||
; CHECK: movz [[W52:w[0-9]+]], #52
|
||||
@ -40,6 +42,7 @@ define void @test_floatcsel(float %lhs32, float %rhs32, double %lhs64, double %r
|
||||
|
||||
%tst2 = fcmp ueq double %lhs64, %rhs64
|
||||
; CHECK: fcmp {{d[0-9]+}}, {{d[0-9]+}}
|
||||
; CHECK-NOFP-NOT: fcmp
|
||||
%val2 = select i1 %tst2, i64 9, i64 15
|
||||
store i64 %val2, i64* @var64
|
||||
; CHECK: movz [[CONST15:x[0-9]+]], #15
|
||||
|
@ -1,4 +1,5 @@
|
||||
; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s
|
||||
; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -mattr=-fp-armv8 | FileCheck --check-prefix=CHECK-NOFP %s
|
||||
|
||||
define i32 @test_select_i32(i1 %bit, i32 %a, i32 %b) {
|
||||
; CHECK-LABEL: test_select_i32:
|
||||
@ -26,7 +27,7 @@ define float @test_select_float(i1 %bit, float %a, float %b) {
|
||||
; CHECK: movz [[ONE:w[0-9]+]], #1
|
||||
; CHECK: tst w0, [[ONE]]
|
||||
; CHECK-NEXT: fcsel s0, s0, s1, ne
|
||||
|
||||
; CHECK-NOFP-NOT: fcsel
|
||||
ret float %val
|
||||
}
|
||||
|
||||
@ -36,6 +37,7 @@ define double @test_select_double(i1 %bit, double %a, double %b) {
|
||||
; CHECK: movz [[ONE:w[0-9]+]], #1
|
||||
; CHECK: tst w0, [[ONE]]
|
||||
; CHECK-NEXT: fcsel d0, d0, d1, ne
|
||||
; CHECK-NOFP-NOT: fcsel
|
||||
|
||||
ret double %val
|
||||
}
|
||||
@ -56,6 +58,7 @@ define i1 @test_setcc_float(float %lhs, float %rhs) {
|
||||
%val = fcmp oeq float %lhs, %rhs
|
||||
; CHECK: fcmp s0, s1
|
||||
; CHECK: csinc w0, wzr, wzr, ne
|
||||
; CHECK-NOFP-NOT: fcmp
|
||||
ret i1 %val
|
||||
}
|
||||
|
||||
@ -64,6 +67,7 @@ define i1 @test_setcc_double(double %lhs, double %rhs) {
|
||||
%val = fcmp oeq double %lhs, %rhs
|
||||
; CHECK: fcmp d0, d1
|
||||
; CHECK: csinc w0, wzr, wzr, ne
|
||||
; CHECK-NOFP-NOT: fcmp
|
||||
ret i1 %val
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s
|
||||
; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -mattr=-fp-armv8 | FileCheck --check-prefix=CHECK-NOFP %s
|
||||
|
||||
%myStruct = type { i64 , i8, i32 }
|
||||
|
||||
@ -23,6 +24,7 @@ define void @add_floats(float %val1, float %val2) {
|
||||
; CHECK-LABEL: add_floats:
|
||||
%newval = fadd float %val1, %val2
|
||||
; CHECK: fadd [[ADDRES:s[0-9]+]], s0, s1
|
||||
; CHECK-NOFP-NOT: fadd
|
||||
store float %newval, float* @varfloat
|
||||
; CHECK: str [[ADDRES]], [{{x[0-9]+}}, #:lo12:varfloat]
|
||||
ret void
|
||||
@ -84,6 +86,7 @@ define double @return_double() {
|
||||
; CHECK-LABEL: return_double:
|
||||
ret double 3.14
|
||||
; CHECK: ldr d0, [{{x[0-9]+}}, #:lo12:.LCPI
|
||||
; CHECK-NOFP-NOT: ldr d0,
|
||||
}
|
||||
|
||||
; This is the kind of IR clang will produce for returning a struct
|
||||
@ -139,6 +142,7 @@ define i32 @struct_on_stack(i8 %var0, i16 %var1, i32 %var2, i64 %var3, i128 %var
|
||||
store volatile double %notstacked, double* @vardouble
|
||||
; CHECK-NOT: ldr d0
|
||||
; CHECK: str d0, [{{x[0-9]+}}, #:lo12:vardouble
|
||||
; CHECK-NOFP-NOT: str d0,
|
||||
|
||||
%retval = load volatile i32* %stacked
|
||||
ret i32 %retval
|
||||
|
@ -1,4 +1,5 @@
|
||||
; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s
|
||||
; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -mattr=-fp-armv8 | FileCheck --check-prefix=CHECK-NOFP %s
|
||||
|
||||
%myStruct = type { i64 , i8, i32 }
|
||||
|
||||
@ -31,6 +32,8 @@ define void @simple_args() {
|
||||
; CHECK-DAG: ldr s1, [{{x[0-9]+}}, #:lo12:varfloat_2]
|
||||
; CHECK-DAG: ldr s0, [{{x[0-9]+}}, #:lo12:varfloat]
|
||||
; CHECK: bl take_floats
|
||||
; CHECK-NOFP-NOT: ldr s1,
|
||||
; CHECK-NOFP-NOT: ldr s0,
|
||||
|
||||
ret void
|
||||
}
|
||||
@ -52,6 +55,7 @@ define void @simple_rets() {
|
||||
store double %dbl, double* @vardouble
|
||||
; CHECK: bl return_double
|
||||
; CHECK: str d0, [{{x[0-9]+}}, #:lo12:vardouble]
|
||||
; CHECK-NOFP-NOT: str d0,
|
||||
|
||||
%arr = call [2 x i64] @return_smallstruct()
|
||||
store [2 x i64] %arr, [2 x i64]* @varsmallstruct
|
||||
@ -87,6 +91,7 @@ define void @check_stack_args() {
|
||||
; CHECK-DAG: str {{w[0-9]+}}, [x[[SPREG]], #12]
|
||||
; CHECK-DAG: fmov d0,
|
||||
; CHECK: bl struct_on_stack
|
||||
; CHECK-NOFP-NOT: fmov
|
||||
|
||||
call void @stacked_fpu(float -1.0, double 1.0, float 4.0, float 2.0,
|
||||
float -2.0, float -8.0, float 16.0, float 1.0,
|
||||
|
@ -1,4 +1,5 @@
|
||||
; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s
|
||||
; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -mattr=-fp-armv8 | FileCheck --check-prefix=CHECK-NOFP %s
|
||||
|
||||
@var_8bit = global i8 0
|
||||
@var_16bit = global i16 0
|
||||
@ -197,11 +198,13 @@ define void @ldst_float(float* %base, i32 %off32, i64 %off64) {
|
||||
%val_sxtwN = load volatile float* %addr_sxtwN
|
||||
store volatile float %val_sxtwN, float* @var_float
|
||||
; CHECK: ldr {{s[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw #2]
|
||||
; CHECK-NOFP-NOT: ldr {{s[0-9]+}},
|
||||
|
||||
%addr_lslN = getelementptr float* %base, i64 %off64
|
||||
%val_lslN = load volatile float* %addr_lslN
|
||||
store volatile float %val_lslN, float* @var_float
|
||||
; CHECK: ldr {{s[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}, lsl #2]
|
||||
; CHECK-NOFP-NOT: ldr {{s[0-9]+}},
|
||||
|
||||
%addrint_uxtw = ptrtoint float* %base to i64
|
||||
%offset_uxtw = zext i32 %off32 to i64
|
||||
@ -210,6 +213,7 @@ define void @ldst_float(float* %base, i32 %off32, i64 %off64) {
|
||||
%val_uxtw = load volatile float* %addr_uxtw
|
||||
store volatile float %val_uxtw, float* @var_float
|
||||
; CHECK: ldr {{s[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw]
|
||||
; CHECK-NOFP-NOT: ldr {{s[0-9]+}},
|
||||
|
||||
%base_sxtw = ptrtoint float* %base to i64
|
||||
%offset_sxtw = sext i32 %off32 to i64
|
||||
@ -218,6 +222,7 @@ define void @ldst_float(float* %base, i32 %off32, i64 %off64) {
|
||||
%val64_sxtw = load volatile float* %addr_sxtw
|
||||
store volatile float %val64_sxtw, float* @var_float
|
||||
; CHECK: ldr {{s[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw]
|
||||
; CHECK-NOFP-NOT: ldr {{s[0-9]+}},
|
||||
|
||||
%base_lsl = ptrtoint float* %base to i64
|
||||
%addrint_lsl = add i64 %base_lsl, %off64
|
||||
@ -225,6 +230,7 @@ define void @ldst_float(float* %base, i32 %off32, i64 %off64) {
|
||||
%val64_lsl = load volatile float* %addr_lsl
|
||||
store volatile float %val64_lsl, float* @var_float
|
||||
; CHECK: ldr {{s[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}]
|
||||
; CHECK-NOFP-NOT: ldr {{s[0-9]+}},
|
||||
|
||||
%base_uxtwN = ptrtoint float* %base to i64
|
||||
%offset_uxtwN = zext i32 %off32 to i64
|
||||
@ -234,6 +240,7 @@ define void @ldst_float(float* %base, i32 %off32, i64 %off64) {
|
||||
%val64 = load volatile float* @var_float
|
||||
store volatile float %val64, float* %addr_uxtwN
|
||||
; CHECK: str {{s[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw #2]
|
||||
; CHECK-NOFP-NOT: ldr {{s[0-9]+}},
|
||||
ret void
|
||||
}
|
||||
|
||||
@ -244,11 +251,13 @@ define void @ldst_double(double* %base, i32 %off32, i64 %off64) {
|
||||
%val_sxtwN = load volatile double* %addr_sxtwN
|
||||
store volatile double %val_sxtwN, double* @var_double
|
||||
; CHECK: ldr {{d[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw #3]
|
||||
; CHECK-NOFP-NOT: ldr {{d[0-9]+}},
|
||||
|
||||
%addr_lslN = getelementptr double* %base, i64 %off64
|
||||
%val_lslN = load volatile double* %addr_lslN
|
||||
store volatile double %val_lslN, double* @var_double
|
||||
; CHECK: ldr {{d[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}, lsl #3]
|
||||
; CHECK-NOFP-NOT: ldr {{d[0-9]+}},
|
||||
|
||||
%addrint_uxtw = ptrtoint double* %base to i64
|
||||
%offset_uxtw = zext i32 %off32 to i64
|
||||
@ -257,6 +266,7 @@ define void @ldst_double(double* %base, i32 %off32, i64 %off64) {
|
||||
%val_uxtw = load volatile double* %addr_uxtw
|
||||
store volatile double %val_uxtw, double* @var_double
|
||||
; CHECK: ldr {{d[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw]
|
||||
; CHECK-NOFP-NOT: ldr {{d[0-9]+}},
|
||||
|
||||
%base_sxtw = ptrtoint double* %base to i64
|
||||
%offset_sxtw = sext i32 %off32 to i64
|
||||
@ -265,6 +275,7 @@ define void @ldst_double(double* %base, i32 %off32, i64 %off64) {
|
||||
%val64_sxtw = load volatile double* %addr_sxtw
|
||||
store volatile double %val64_sxtw, double* @var_double
|
||||
; CHECK: ldr {{d[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw]
|
||||
; CHECK-NOFP-NOT: ldr {{d[0-9]+}},
|
||||
|
||||
%base_lsl = ptrtoint double* %base to i64
|
||||
%addrint_lsl = add i64 %base_lsl, %off64
|
||||
@ -272,6 +283,7 @@ define void @ldst_double(double* %base, i32 %off32, i64 %off64) {
|
||||
%val64_lsl = load volatile double* %addr_lsl
|
||||
store volatile double %val64_lsl, double* @var_double
|
||||
; CHECK: ldr {{d[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}]
|
||||
; CHECK-NOFP-NOT: ldr {{d[0-9]+}},
|
||||
|
||||
%base_uxtwN = ptrtoint double* %base to i64
|
||||
%offset_uxtwN = zext i32 %off32 to i64
|
||||
@ -281,6 +293,7 @@ define void @ldst_double(double* %base, i32 %off32, i64 %off64) {
|
||||
%val64 = load volatile double* @var_double
|
||||
store volatile double %val64, double* %addr_uxtwN
|
||||
; CHECK: str {{d[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw #3]
|
||||
; CHECK-NOFP-NOT: ldr {{d[0-9]+}},
|
||||
ret void
|
||||
}
|
||||
|
||||
@ -292,11 +305,13 @@ define void @ldst_128bit(fp128* %base, i32 %off32, i64 %off64) {
|
||||
%val_sxtwN = load volatile fp128* %addr_sxtwN
|
||||
store volatile fp128 %val_sxtwN, fp128* %base
|
||||
; CHECK: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw #4]
|
||||
; CHECK-NOFP-NOT: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw #4]
|
||||
|
||||
%addr_lslN = getelementptr fp128* %base, i64 %off64
|
||||
%val_lslN = load volatile fp128* %addr_lslN
|
||||
store volatile fp128 %val_lslN, fp128* %base
|
||||
; CHECK: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}, lsl #4]
|
||||
; CHECK-NOFP-NOT: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw #4]
|
||||
|
||||
%addrint_uxtw = ptrtoint fp128* %base to i64
|
||||
%offset_uxtw = zext i32 %off32 to i64
|
||||
@ -305,6 +320,7 @@ define void @ldst_128bit(fp128* %base, i32 %off32, i64 %off64) {
|
||||
%val_uxtw = load volatile fp128* %addr_uxtw
|
||||
store volatile fp128 %val_uxtw, fp128* %base
|
||||
; CHECK: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw]
|
||||
; CHECK-NOFP-NOT: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw #4]
|
||||
|
||||
%base_sxtw = ptrtoint fp128* %base to i64
|
||||
%offset_sxtw = sext i32 %off32 to i64
|
||||
@ -313,6 +329,7 @@ define void @ldst_128bit(fp128* %base, i32 %off32, i64 %off64) {
|
||||
%val64_sxtw = load volatile fp128* %addr_sxtw
|
||||
store volatile fp128 %val64_sxtw, fp128* %base
|
||||
; CHECK: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw]
|
||||
; CHECK-NOFP-NOT: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw #4]
|
||||
|
||||
%base_lsl = ptrtoint fp128* %base to i64
|
||||
%addrint_lsl = add i64 %base_lsl, %off64
|
||||
@ -320,6 +337,7 @@ define void @ldst_128bit(fp128* %base, i32 %off32, i64 %off64) {
|
||||
%val64_lsl = load volatile fp128* %addr_lsl
|
||||
store volatile fp128 %val64_lsl, fp128* %base
|
||||
; CHECK: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}]
|
||||
; CHECK-NOFP-NOT: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw #4]
|
||||
|
||||
%base_uxtwN = ptrtoint fp128* %base to i64
|
||||
%offset_uxtwN = zext i32 %off32 to i64
|
||||
@ -329,5 +347,6 @@ define void @ldst_128bit(fp128* %base, i32 %off32, i64 %off64) {
|
||||
%val64 = load volatile fp128* %base
|
||||
store volatile fp128 %val64, fp128* %addr_uxtwN
|
||||
; CHECK: str {{q[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, uxtw #4]
|
||||
; CHECK-NOFP-NOT: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{w[0-9]+}}, sxtw #4]
|
||||
ret void
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s
|
||||
; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -mattr=-fp-armv8 | FileCheck --check-prefix=CHECK-NOFP %s
|
||||
|
||||
@var_8bit = global i8 0
|
||||
@var_16bit = global i16 0
|
||||
@ -194,9 +195,11 @@ define void @ldst_float() {
|
||||
|
||||
%valfp = load volatile float* %addrfp
|
||||
; CHECK: ldur {{s[0-9]+}}, [{{x[0-9]+}}, #-5]
|
||||
; CHECK-NOFP-NOT: ldur {{s[0-9]+}},
|
||||
|
||||
store volatile float %valfp, float* %addrfp
|
||||
; CHECK: stur {{s[0-9]+}}, [{{x[0-9]+}}, #-5]
|
||||
; CHECK-NOFP-NOT: stur {{s[0-9]+}},
|
||||
|
||||
ret void
|
||||
}
|
||||
@ -210,9 +213,11 @@ define void @ldst_double() {
|
||||
|
||||
%valfp = load volatile double* %addrfp
|
||||
; CHECK: ldur {{d[0-9]+}}, [{{x[0-9]+}}, #4]
|
||||
; CHECK-NOFP-NOT: ldur {{d[0-9]+}},
|
||||
|
||||
store volatile double %valfp, double* %addrfp
|
||||
; CHECK: stur {{d[0-9]+}}, [{{x[0-9]+}}, #4]
|
||||
; CHECK-NOFP-NOT: stur {{d[0-9]+}},
|
||||
|
||||
ret void
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s
|
||||
; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -mattr=-fp-armv8 | FileCheck --check-prefix=CHECK-NOFP %s
|
||||
|
||||
@var_8bit = global i8 0
|
||||
@var_16bit = global i16 0
|
||||
@ -230,9 +231,11 @@ define void @ldst_float() {
|
||||
%valfp = load volatile float* @var_float
|
||||
; CHECK: adrp {{x[0-9]+}}, var_float
|
||||
; CHECK: ldr {{s[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_float]
|
||||
; CHECK-NOFP-NOT: ldr {{s[0-9]+}},
|
||||
|
||||
store volatile float %valfp, float* @var_float
|
||||
; CHECK: str {{s[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_float]
|
||||
; CHECK-NOFP-NOT: str {{s[0-9]+}},
|
||||
|
||||
ret void
|
||||
}
|
||||
@ -243,9 +246,11 @@ define void @ldst_double() {
|
||||
%valfp = load volatile double* @var_double
|
||||
; CHECK: adrp {{x[0-9]+}}, var_double
|
||||
; CHECK: ldr {{d[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_double]
|
||||
; CHECK-NOFP-NOT: ldr {{d[0-9]+}},
|
||||
|
||||
store volatile double %valfp, double* @var_double
|
||||
; CHECK: str {{d[0-9]+}}, [{{x[0-9]+}}, #:lo12:var_double]
|
||||
; CHECK-NOFP-NOT: str {{d[0-9]+}},
|
||||
|
||||
ret void
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s
|
||||
; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -code-model=large | FileCheck --check-prefix=CHECK-LARGE %s
|
||||
; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -mattr=-fp-armv8 | FileCheck --check-prefix=CHECK-NOFP %s
|
||||
; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -code-model=large -mattr=-fp-armv8 | FileCheck --check-prefix=CHECK-NOFP-LARGE %s
|
||||
|
||||
@var32 = global i32 0
|
||||
@var64 = global i64 0
|
||||
@ -66,6 +68,7 @@ define void @floating_lits() {
|
||||
%newfloat = fadd float %floatval, 128.0
|
||||
; CHECK: adrp x[[LITBASE:[0-9]+]], [[CURLIT:.LCPI1_[0-9]+]]
|
||||
; CHECK: ldr [[LIT128:s[0-9]+]], [x[[LITBASE]], #:lo12:[[CURLIT]]]
|
||||
; CHECK-NOFP-NOT: ldr {{s[0-9]+}},
|
||||
|
||||
; CHECK-LARGE: movz x[[LITADDR:[0-9]+]], #:abs_g3:[[CURLIT:.LCPI1_[0-9]+]]
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g2_nc:[[CURLIT]]
|
||||
@ -73,6 +76,8 @@ define void @floating_lits() {
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g0_nc:[[CURLIT]]
|
||||
; CHECK-LARGE: ldr {{s[0-9]+}}, [x[[LITADDR]]]
|
||||
; CHECK-LARGE: fadd
|
||||
; CHECK-NOFP-LARGE-NOT: ldr {{s[0-9]+}},
|
||||
; CHECK-NOFP-LARGE-NOT: fadd
|
||||
|
||||
store float %newfloat, float* @varfloat
|
||||
|
||||
@ -82,12 +87,15 @@ define void @floating_lits() {
|
||||
; CHECK: ldr [[LIT129:d[0-9]+]], [x[[LITBASE]], #:lo12:[[CURLIT]]]
|
||||
; CHECK: fadd {{s[0-9]+}}, {{s[0-9]+}}, [[LIT128]]
|
||||
; CHECK: fadd {{d[0-9]+}}, {{d[0-9]+}}, [[LIT129]]
|
||||
; CHECK-NOFP-NOT: ldr {{d[0-9]+}},
|
||||
; CHECK-NOFP-NOT: fadd
|
||||
|
||||
; CHECK-LARGE: movz x[[LITADDR:[0-9]+]], #:abs_g3:[[CURLIT:.LCPI1_[0-9]+]]
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g2_nc:[[CURLIT]]
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g1_nc:[[CURLIT]]
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g0_nc:[[CURLIT]]
|
||||
; CHECK-LARGE: ldr {{d[0-9]+}}, [x[[LITADDR]]]
|
||||
; CHECK-NOFP-LARGE-NOT: ldr {{d[0-9]+}},
|
||||
|
||||
store double %newdouble, double* @vardouble
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
; RUN: llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s
|
||||
; RUN: llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu -mattr=-fp-armv8 < %s | FileCheck --check-prefix=CHECK-NOFP %s
|
||||
|
||||
%va_list = type {i8*, i8*, i8*, i32, i32}
|
||||
|
||||
@ -15,11 +16,20 @@ define void @test_simple(i32 %n, ...) {
|
||||
; CHECK: add x[[GPRBASE:[0-9]+]], sp, #[[GPRFROMSP:[0-9]+]]
|
||||
; CHECK: str x7, [x[[GPRBASE]], #48]
|
||||
|
||||
; CHECK-NOFP: sub sp, sp, #[[STACKSIZE:[0-9]+]]
|
||||
; CHECK-NOFP: add x[[VA_LIST:[0-9]+]], {{x[0-9]+}}, #:lo12:var
|
||||
; CHECK-NOFP: add x[[GPRBASE:[0-9]+]], sp, #[[GPRFROMSP:[0-9]+]]
|
||||
; CHECK-NOFP: str x7, [x[[GPRBASE]], #48]
|
||||
; CHECK-NOFP-NOT: str q7,
|
||||
; CHECK-NOFP: str x1, [sp, #[[GPRFROMSP]]]
|
||||
|
||||
; Omit the middle ones
|
||||
|
||||
; CHECK: str q0, [sp]
|
||||
; CHECK: str x1, [sp, #[[GPRFROMSP]]]
|
||||
|
||||
; CHECK-NOFP-NOT: str q0, [sp]
|
||||
|
||||
%addr = bitcast %va_list* @var to i8*
|
||||
call void @llvm.va_start(i8* %addr)
|
||||
; CHECK: movn [[VR_OFFS:w[0-9]+]], #127
|
||||
@ -33,6 +43,14 @@ define void @test_simple(i32 %n, ...) {
|
||||
; CHECK: add [[STACK:x[0-9]+]], sp, #[[STACKSIZE]]
|
||||
; CHECK: str [[STACK]], [{{x[0-9]+}}, #:lo12:var]
|
||||
|
||||
; CHECK-NOFP: str wzr, [x[[VA_LIST]], #28]
|
||||
; CHECK-NOFP: movn [[GR_OFFS:w[0-9]+]], #55
|
||||
; CHECK-NOFP: str [[GR_OFFS]], [x[[VA_LIST]], #24]
|
||||
; CHECK-NOFP: add [[GR_TOP:x[0-9]+]], x[[GPRBASE]], #56
|
||||
; CHECK-NOFP: str [[GR_TOP]], [x[[VA_LIST]], #8]
|
||||
; CHECK-NOFP: add [[STACK:x[0-9]+]], sp, #[[STACKSIZE]]
|
||||
; CHECK-NOFP: str [[STACK]], [{{x[0-9]+}}, #:lo12:var]
|
||||
|
||||
ret void
|
||||
}
|
||||
|
||||
@ -44,11 +62,19 @@ define void @test_fewargs(i32 %n, i32 %n1, i32 %n2, float %m, ...) {
|
||||
; CHECK: add x[[GPRBASE:[0-9]+]], sp, #[[GPRFROMSP:[0-9]+]]
|
||||
; CHECK: str x7, [x[[GPRBASE]], #32]
|
||||
|
||||
; CHECK-NOFP: sub sp, sp, #[[STACKSIZE:[0-9]+]]
|
||||
; CHECK-NOFP-NOT: str q7,
|
||||
; CHECK-NOFP: mov x[[GPRBASE:[0-9]+]], sp
|
||||
; CHECK-NOFP: str x7, [x[[GPRBASE]], #24]
|
||||
|
||||
; Omit the middle ones
|
||||
|
||||
; CHECK: str q1, [sp]
|
||||
; CHECK: str x3, [sp, #[[GPRFROMSP]]]
|
||||
|
||||
; CHECK-NOFP-NOT: str q1, [sp]
|
||||
; CHECK-NOFP: str x4, [sp]
|
||||
|
||||
%addr = bitcast %va_list* @var to i8*
|
||||
call void @llvm.va_start(i8* %addr)
|
||||
; CHECK: add x[[VA_LIST:[0-9]+]], {{x[0-9]+}}, #:lo12:var
|
||||
@ -63,6 +89,15 @@ define void @test_fewargs(i32 %n, i32 %n1, i32 %n2, float %m, ...) {
|
||||
; CHECK: add [[STACK:x[0-9]+]], sp, #[[STACKSIZE]]
|
||||
; CHECK: str [[STACK]], [{{x[0-9]+}}, #:lo12:var]
|
||||
|
||||
; CHECK-NOFP: add x[[VA_LIST:[0-9]+]], {{x[0-9]+}}, #:lo12:var
|
||||
; CHECK-NOFP: str wzr, [x[[VA_LIST]], #28]
|
||||
; CHECK-NOFP: movn [[GR_OFFS:w[0-9]+]], #31
|
||||
; CHECK-NOFP: str [[GR_OFFS]], [x[[VA_LIST]], #24]
|
||||
; CHECK-NOFP: add [[GR_TOP:x[0-9]+]], x[[GPRBASE]], #32
|
||||
; CHECK-NOFP: str [[GR_TOP]], [x[[VA_LIST]], #8]
|
||||
; CHECK-NOFP: add [[STACK:x[0-9]+]], sp, #[[STACKSIZE]]
|
||||
; CHECK-NOFP: str [[STACK]], [{{x[0-9]+}}, #:lo12:var]
|
||||
|
||||
ret void
|
||||
}
|
||||
|
||||
@ -75,6 +110,9 @@ define void @test_nospare([8 x i64], [8 x float], ...) {
|
||||
; CHECK: mov [[STACK:x[0-9]+]], sp
|
||||
; CHECK: str [[STACK]], [{{x[0-9]+}}, #:lo12:var]
|
||||
|
||||
; CHECK-NOFP-NOT: sub sp, sp
|
||||
; CHECK-NOFP: add [[STACK:x[0-9]+]], sp, #64
|
||||
; CHECK-NOFP: str [[STACK]], [{{x[0-9]+}}, #:lo12:var]
|
||||
ret void
|
||||
}
|
||||
|
||||
@ -87,6 +125,10 @@ define void @test_offsetstack([10 x i64], [3 x float], ...) {
|
||||
; CHECK: str q7, [x[[FPRBASE]], #64]
|
||||
|
||||
; CHECK-NOT: str x{{[0-9]+}},
|
||||
|
||||
; CHECK-NOFP-NOT: str q7,
|
||||
; CHECK-NOT: str x7,
|
||||
|
||||
; Omit the middle ones
|
||||
|
||||
; CHECK: str q3, [sp]
|
||||
@ -102,6 +144,11 @@ define void @test_offsetstack([10 x i64], [3 x float], ...) {
|
||||
; CHECK: add [[STACK:x[0-9]+]], sp, #96
|
||||
; CHECK: str [[STACK]], [{{x[0-9]+}}, #:lo12:var]
|
||||
|
||||
; CHECK-NOFP: add x[[VA_LIST:[0-9]+]], {{x[0-9]+}}, #:lo12:var
|
||||
; CHECK-NOFP: add [[STACK:x[0-9]+]], sp, #40
|
||||
; CHECK-NOFP: str [[STACK]], [{{x[0-9]+}}, #:lo12:var]
|
||||
; CHECK-NOFP: str wzr, [x[[VA_LIST]], #28]
|
||||
; CHECK-NOFP: str wzr, [x[[VA_LIST]], #24]
|
||||
ret void
|
||||
}
|
||||
|
||||
@ -110,12 +157,14 @@ declare void @llvm.va_end(i8*)
|
||||
define void @test_va_end() nounwind {
|
||||
; CHECK-LABEL: test_va_end:
|
||||
; CHECK-NEXT: BB#0
|
||||
; CHECK-NOFP: BB#0
|
||||
|
||||
%addr = bitcast %va_list* @var to i8*
|
||||
call void @llvm.va_end(i8* %addr)
|
||||
|
||||
ret void
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-NOFP-NEXT: ret
|
||||
}
|
||||
|
||||
declare void @llvm.va_copy(i8* %dest, i8* %src)
|
||||
@ -132,6 +181,8 @@ define void @test_va_copy() {
|
||||
|
||||
; CHECK: ldr [[BLOCK:x[0-9]+]], [{{x[0-9]+}}, #:lo12:var]
|
||||
; CHECK: add x[[SRC_LIST:[0-9]+]], {{x[0-9]+}}, #:lo12:var
|
||||
; CHECK-NOFP: ldr [[BLOCK:x[0-9]+]], [{{x[0-9]+}}, #:lo12:var]
|
||||
; CHECK-NOFP: add x[[SRC_LIST:[0-9]+]], {{x[0-9]+}}, #:lo12:var
|
||||
|
||||
; CHECK: str [[BLOCK]], [{{x[0-9]+}}, #:lo12:second_list]
|
||||
|
||||
@ -140,6 +191,14 @@ define void @test_va_copy() {
|
||||
|
||||
; CHECK: str [[BLOCK]], [x[[DEST_LIST]], #24]
|
||||
|
||||
; CHECK-NOFP: str [[BLOCK]], [{{x[0-9]+}}, #:lo12:second_list]
|
||||
|
||||
; CHECK-NOFP: ldr [[BLOCK:x[0-9]+]], [x[[SRC_LIST]], #24]
|
||||
; CHECK-NOFP: add x[[DEST_LIST:[0-9]+]], {{x[0-9]+}}, #:lo12:second_list
|
||||
|
||||
; CHECK-NOFP: str [[BLOCK]], [x[[DEST_LIST]], #24]
|
||||
|
||||
ret void
|
||||
; CHECK: ret
|
||||
; CHECK-NOFP: ret
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding < %s | FileCheck %s
|
||||
// RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+fp-armv8 < %s | FileCheck %s
|
||||
.globl _func
|
||||
|
||||
// Check that the assembler can handle the documented syntax from the ARM ARM.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// RUN: llvm-mc -triple=aarch64-none-linux-gnu -filetype=obj %s -o - | \
|
||||
// RUN: llvm-mc -triple=aarch64-none-linux-gnu -mattr=+fp-armv8 -filetype=obj %s -o - | \
|
||||
// RUN: llvm-readobj -r | FileCheck -check-prefix=OBJ %s
|
||||
|
||||
ldrb w0, [sp, #:lo12:some_label]
|
||||
|
@ -1,4 +1,4 @@
|
||||
// RUN: llvm-mc -triple=aarch64-none-linux-gnu -filetype=obj < %s | llvm-objdump -r - | FileCheck %s
|
||||
// RUN: llvm-mc -triple=aarch64-none-linux-gnu -filetype=obj -mattr=+fp-armv8 < %s | llvm-objdump -r - | FileCheck %s
|
||||
|
||||
.file "<stdin>"
|
||||
.text
|
||||
|
@ -1,4 +1,4 @@
|
||||
# RUN: llvm-mc -triple=aarch64 -disassemble -show-encoding < %s | FileCheck %s
|
||||
# RUN: llvm-mc -triple=aarch64 -mattr=fp-armv8 -disassemble -show-encoding < %s | FileCheck %s
|
||||
|
||||
# The "Rm" bits are ignored, but the canonical representation has them filled
|
||||
# with 0s. This is what we should produce even if the input bit-pattern had
|
||||
|
@ -1,4 +1,4 @@
|
||||
# RUN: llvm-mc -triple=aarch64 -disassemble < %s | FileCheck %s
|
||||
# RUN: llvm-mc -triple=aarch64 -mattr=+fp-armv8 -disassemble < %s | FileCheck %s
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Add/sub (immediate)
|
||||
|
@ -1,4 +1,4 @@
|
||||
# RUN: llvm-mc -triple=aarch64 -disassemble < %s 2>&1 | FileCheck %s
|
||||
# RUN: llvm-mc -triple=aarch64 -mattr=+fp-armv8 -disassemble < %s 2>&1 | FileCheck %s
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Load-store exclusive
|
||||
|
@ -1,4 +1,4 @@
|
||||
# RUN: llvm-mc -triple=aarch64 -disassemble < %s 2>&1 | FileCheck %s
|
||||
# RUN: llvm-mc -triple=aarch64 -mattr=+fp-armv8 -disassemble < %s 2>&1 | FileCheck %s
|
||||
|
||||
# None of these instructions should be classified as unpredictable:
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# RUN: llvm-mc -triple=aarch64 -disassemble < %s 2>&1 | FileCheck %s
|
||||
# RUN: llvm-mc -triple=aarch64 -mattr=+fp-armv8 -disassemble < %s 2>&1 | FileCheck %s
|
||||
|
||||
# None of these instructions should be classified as unpredictable:
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user