Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions llvm/include/llvm/IR/IntrinsicsAArch64.td
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,9 @@ def int_aarch64_get_fpcr : FPENV_Get_Intrinsic;
def int_aarch64_set_fpcr : FPENV_Set_Intrinsic;
def int_aarch64_get_fpsr : FPENV_Get_Intrinsic;
def int_aarch64_set_fpsr : FPENV_Set_Intrinsic;
def int_aarch64_set_fpmr : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrInaccessibleMemOnly]>{
let TargetPrefix = "aarch64";
}

// Armv8.5-A Random number generation intrinsics
def int_aarch64_rndr : RNDR_Intrinsic;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/LivePhysRegs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ void llvm::addLiveIns(MachineBasicBlock &MBB, const LivePhysRegs &LiveRegs) {
const MachineRegisterInfo &MRI = MF.getRegInfo();
const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
for (MCPhysReg Reg : LiveRegs) {
if (MRI.isReserved(Reg))
if (TRI.getReservedRegs(MF).test(Reg))
continue;
// Skip the register if we are about to add one of its super registers.
if (any_of(TRI.superregs(Reg), [&](MCPhysReg SReg) {
Expand Down
45 changes: 45 additions & 0 deletions llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3007,6 +3007,49 @@ MachineBasicBlock *AArch64TargetLowering::EmitLoweredCatchRet(
return BB;
}

MachineBasicBlock *
AArch64TargetLowering::EmitLoweredSetFpmr(MachineInstr &MI,
MachineBasicBlock *MBB) const {
MachineFunction *MF = MBB->getParent();
const TargetInstrInfo *TII = Subtarget->getInstrInfo();
DebugLoc DL = MI.getDebugLoc();
const BasicBlock *LLVM_BB = MBB->getBasicBlock();
Register NewFpmrVal = MI.getOperand(0).getReg();

// Test if FPMR is set correctly already
Register OldFpmrVal =
MI.getMF()->getRegInfo().createVirtualRegister(&AArch64::GPR64RegClass);
BuildMI(*MBB, MI, DL, TII->get(AArch64::MRS), OldFpmrVal)
.addImm(0xda22)
.addUse(AArch64::FPMR, RegState::Implicit);
BuildMI(*MBB, MI, DL, TII->get(AArch64::SUBSXrs), AArch64::XZR)
.addReg(OldFpmrVal)
.addReg(NewFpmrVal)
.addImm(0);

MachineBasicBlock *MsrBB = MF->CreateMachineBasicBlock(LLVM_BB);
// Transfer rest of current basic-block to EndBB
MachineBasicBlock *EndBB = MBB->splitAt(MI);
MF->insert(++MBB->getIterator(), MsrBB);

// If already set continue
BuildMI(*MBB, MI, DL, TII->get(AArch64::Bcc))
.addImm(AArch64CC::EQ)
.addMBB(EndBB);

BuildMI(*MsrBB, MsrBB->begin(), DL, TII->get(AArch64::MSR))
.addImm(0xda22)
.addReg(NewFpmrVal)
.addDef(AArch64::FPMR, RegState::Implicit);

MBB->addSuccessor(MsrBB);
// MsrBB falls through to the end.
MsrBB->addSuccessor(EndBB);

MI.eraseFromParent();
return EndBB;
}

MachineBasicBlock *
AArch64TargetLowering::EmitDynamicProbedAlloc(MachineInstr &MI,
MachineBasicBlock *MBB) const {
Expand Down Expand Up @@ -3292,6 +3335,8 @@ MachineBasicBlock *AArch64TargetLowering::EmitInstrWithCustomInserter(
return EmitZTInstr(MI, BB, AArch64::ZERO_T, /*Op0IsDef=*/true);
case AArch64::MOVT_TIZ_PSEUDO:
return EmitZTInstr(MI, BB, AArch64::MOVT_TIZ, /*Op0IsDef=*/true);
case AArch64::SET_FPMR:
return EmitLoweredSetFpmr(MI, BB);
}
}

Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/AArch64/AArch64ISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,9 @@ class AArch64TargetLowering : public TargetLowering {
MachineBasicBlock *EmitLoweredCatchRet(MachineInstr &MI,
MachineBasicBlock *BB) const;

MachineBasicBlock *EmitLoweredSetFpmr(MachineInstr &MI,
MachineBasicBlock *BB) const;

MachineBasicBlock *EmitDynamicProbedAlloc(MachineInstr &MI,
MachineBasicBlock *MBB) const;

Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/Target/AArch64/AArch64InstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -2145,6 +2145,11 @@ def MSR_FPSR : Pseudo<(outs), (ins GPR64:$val),
PseudoInstExpansion<(MSR 0xda21, GPR64:$val)>,
Sched<[WriteSys]>;

let Uses = [FPMR], Defs = [FPMR, NZCV], usesCustomInserter = 1 in
def SET_FPMR : Pseudo<(outs), (ins GPR64:$val),
[(int_aarch64_set_fpmr i64:$val)]>,
Sched<[WriteSys]>;

// Generic system instructions
def SYSxt : SystemXtI<0, "sys">;
def SYSLxt : SystemLXtI<1, "sysl">;
Expand Down
16 changes: 15 additions & 1 deletion llvm/test/CodeGen/AArch64/arm64-fpenv.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
; RUN: llc -mtriple=aarch64 < %s | FileCheck %s
; RUN: llc -mtriple=aarch64 -mattr=+fpmr -verify-machineinstrs < %s | FileCheck %s

define i64 @get_fpcr() #0 {
; CHECK-LABEL: get_fpcr:
Expand Down Expand Up @@ -37,6 +37,20 @@ define void @set_fpsr(i64 %sr) {
ret void
}

define dso_local void @set_fpmr(i64 %sr) {
; CHECK-LABEL: set_fpmr:
; CHECK: // %bb.0:
; CHECK-NEXT: mrs x8, FPMR
; CHECK-NEXT: cmp x8, x0
; CHECK-NEXT: b.eq .LBB4_2
; CHECK-NEXT: // %bb.1:
; CHECK-NEXT: msr FPMR, x0
; CHECK-NEXT: .LBB4_2:
; CHECK-NEXT: ret
call void @llvm.aarch64.set.fpmr(i64 %sr)
ret void
}

declare i64 @llvm.aarch64.get.fpcr()
declare void @llvm.aarch64.set.fpcr(i64)
declare i64 @llvm.aarch64.get.fpsr()
Expand Down
Loading