From 36c74721061dedfa3d704bfff18170ffc49d0e44 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Wed, 30 Apr 2014 13:14:14 +0000 Subject: [PATCH] AArch64/ARM64: expunge CPSR from the sources AArch64 does not have a CPSR register in the same way that AArch32 does. Most of its compiler-relevant roles have been taken over by the more specific NZCV register (representing just the flags set by normal instructions). Its system control functions still remain, but are now under the pseudo-register referred to as "PSTATE". They're accessed via various MRS & MSR instructions described in the reference manual. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207645 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM64/ARM64ConditionalCompares.cpp | 16 +-- lib/Target/ARM64/ARM64ISelLowering.cpp | 18 ++-- lib/Target/ARM64/ARM64InstrFormats.td | 99 ++++++++++--------- lib/Target/ARM64/ARM64InstrInfo.cpp | 52 +++++----- lib/Target/ARM64/ARM64InstrInfo.h | 2 +- lib/Target/ARM64/ARM64InstrInfo.td | 26 ++--- lib/Target/ARM64/ARM64RegisterInfo.cpp | 2 +- lib/Target/ARM64/ARM64RegisterInfo.td | 4 +- lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp | 4 +- .../ARM64/Disassembler/ARM64Disassembler.cpp | 19 ++-- .../ARM64/InstPrinter/ARM64InstPrinter.cpp | 4 +- .../ARM64/InstPrinter/ARM64InstPrinter.h | 2 +- 12 files changed, 125 insertions(+), 123 deletions(-) diff --git a/lib/Target/ARM64/ARM64ConditionalCompares.cpp b/lib/Target/ARM64/ARM64ConditionalCompares.cpp index ae756c683d3..2243cce51a1 100644 --- a/lib/Target/ARM64/ARM64ConditionalCompares.cpp +++ b/lib/Target/ARM64/ARM64ConditionalCompares.cpp @@ -63,8 +63,8 @@ STATISTIC(NumCmpBranchRejs, "Number of ccmps rejected (CmpBB branch)"); STATISTIC(NumCmpTermRejs, "Number of ccmps rejected (CmpBB is cbz...)"); STATISTIC(NumImmRangeRejs, "Number of ccmps rejected (Imm out of range)"); STATISTIC(NumLiveDstRejs, "Number of ccmps rejected (Cmp dest live)"); -STATISTIC(NumMultCPSRUses, "Number of ccmps rejected (CPSR used)"); -STATISTIC(NumUnknCPSRDefs, "Number of ccmps rejected (CPSR def unknown)"); +STATISTIC(NumMultNZCVUses, "Number of ccmps rejected (NZCV used)"); +STATISTIC(NumUnknNZCVDefs, "Number of ccmps rejected (NZCV def unknown)"); STATISTIC(NumSpeculateRejs, "Number of ccmps rejected (Can't speculate)"); @@ -300,7 +300,7 @@ MachineInstr *SSACCmpConv::findConvertibleCompare(MachineBasicBlock *MBB) { if (I == MBB->end()) return nullptr; // The terminator must be controlled by the flags. - if (!I->readsRegister(ARM64::CPSR)) { + if (!I->readsRegister(ARM64::NZCV)) { switch (I->getOpcode()) { case ARM64::CBZW: case ARM64::CBZX: @@ -351,20 +351,20 @@ MachineInstr *SSACCmpConv::findConvertibleCompare(MachineBasicBlock *MBB) { // Check for flag reads and clobbers. MIOperands::PhysRegInfo PRI = - MIOperands(I).analyzePhysReg(ARM64::CPSR, TRI); + MIOperands(I).analyzePhysReg(ARM64::NZCV, TRI); if (PRI.Reads) { // The ccmp doesn't produce exactly the same flags as the original // compare, so reject the transform if there are uses of the flags // besides the terminators. DEBUG(dbgs() << "Can't create ccmp with multiple uses: " << *I); - ++NumMultCPSRUses; + ++NumMultNZCVUses; return nullptr; } if (PRI.Clobbers) { DEBUG(dbgs() << "Not convertible compare: " << *I); - ++NumUnknCPSRDefs; + ++NumUnknNZCVDefs; return nullptr; } } @@ -379,7 +379,7 @@ MachineInstr *SSACCmpConv::findConvertibleCompare(MachineBasicBlock *MBB) { /// bool SSACCmpConv::canSpeculateInstrs(MachineBasicBlock *MBB, const MachineInstr *CmpMI) { - // Reject any live-in physregs. It's probably CPSR/EFLAGS, and very hard to + // Reject any live-in physregs. It's probably NZCV/EFLAGS, and very hard to // get right. if (!MBB->livein_empty()) { DEBUG(dbgs() << "BB#" << MBB->getNumber() << " has live-ins.\n"); @@ -422,7 +422,7 @@ bool SSACCmpConv::canSpeculateInstrs(MachineBasicBlock *MBB, } // Only CmpMI is allowed to clobber the flags. - if (&I != CmpMI && I.modifiesRegister(ARM64::CPSR, TRI)) { + if (&I != CmpMI && I.modifiesRegister(ARM64::NZCV, TRI)) { DEBUG(dbgs() << "Clobbers flags: " << I); return false; } diff --git a/lib/Target/ARM64/ARM64ISelLowering.cpp b/lib/Target/ARM64/ARM64ISelLowering.cpp index 029112986ec..ccd80175faf 100644 --- a/lib/Target/ARM64/ARM64ISelLowering.cpp +++ b/lib/Target/ARM64/ARM64ISelLowering.cpp @@ -213,7 +213,7 @@ ARM64TargetLowering::ARM64TargetLowering(ARM64TargetMachine &TM) // BlockAddress setOperationAction(ISD::BlockAddress, MVT::i64, Custom); - // Add/Sub overflow ops with MVT::Glues are lowered to CPSR dependences. + // Add/Sub overflow ops with MVT::Glues are lowered to NZCV dependences. setOperationAction(ISD::ADDC, MVT::i32, Custom); setOperationAction(ISD::ADDE, MVT::i32, Custom); setOperationAction(ISD::SUBC, MVT::i32, Custom); @@ -738,7 +738,7 @@ ARM64TargetLowering::EmitF128CSEL(MachineInstr *MI, unsigned IfTrueReg = MI->getOperand(1).getReg(); unsigned IfFalseReg = MI->getOperand(2).getReg(); unsigned CondCode = MI->getOperand(3).getImm(); - bool CPSRKilled = MI->getOperand(4).isKill(); + bool NZCVKilled = MI->getOperand(4).isKill(); MachineBasicBlock *TrueBB = MF->CreateMachineBasicBlock(LLVM_BB); MachineBasicBlock *EndBB = MF->CreateMachineBasicBlock(LLVM_BB); @@ -758,9 +758,9 @@ ARM64TargetLowering::EmitF128CSEL(MachineInstr *MI, // TrueBB falls through to the end. TrueBB->addSuccessor(EndBB); - if (!CPSRKilled) { - TrueBB->addLiveIn(ARM64::CPSR); - EndBB->addLiveIn(ARM64::CPSR); + if (!NZCVKilled) { + TrueBB->addLiveIn(ARM64::NZCV); + EndBB->addLiveIn(ARM64::NZCV); } BuildMI(*EndBB, EndBB->begin(), DL, TII->get(ARM64::PHI), DestReg) @@ -2350,7 +2350,7 @@ ARM64TargetLowering::LowerDarwinGlobalTLSAddress(SDValue Op, MFI->setAdjustsStack(true); // TLS calls preserve all registers except those that absolutely must be - // trashed: X0 (it takes an argument), LR (it's a call) and CPSR (let's not be + // trashed: X0 (it takes an argument), LR (it's a call) and NZCV (let's not be // silly). const TargetRegisterInfo *TRI = getTargetMachine().getRegisterInfo(); const ARM64RegisterInfo *ARI = static_cast(TRI); @@ -2371,7 +2371,7 @@ ARM64TargetLowering::LowerDarwinGlobalTLSAddress(SDValue Op, /// have a descriptor, accessible via a PC-relative ADRP, and whose first entry /// is a function pointer to carry out the resolution. This function takes the /// address of the descriptor in X0 and returns the TPIDR_EL0 offset in X0. All -/// other registers (except LR, CPSR) are preserved. +/// other registers (except LR, NZCV) are preserved. /// /// Thus, the ideal call sequence on AArch64 is: /// @@ -2398,7 +2398,7 @@ SDValue ARM64TargetLowering::LowerELFTLSDescCall(SDValue SymAddr, SDValue Func = DAG.getNode(ARM64ISD::LOADgot, DL, PtrVT, SymAddr); // TLS calls preserve all registers except those that absolutely must be - // trashed: X0 (it takes an argument), LR (it's a call) and CPSR (let's not be + // trashed: X0 (it takes an argument), LR (it's a call) and NZCV (let's not be // silly). const TargetRegisterInfo *TRI = getTargetMachine().getRegisterInfo(); const ARM64RegisterInfo *ARI = static_cast(TRI); @@ -3602,7 +3602,7 @@ ARM64TargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint, } } if (StringRef("{cc}").equals_lower(Constraint)) - return std::make_pair(unsigned(ARM64::CPSR), &ARM64::CCRRegClass); + return std::make_pair(unsigned(ARM64::NZCV), &ARM64::CCRRegClass); // Use the default implementation in TargetLowering to convert the register // constraint into a member of a register class. diff --git a/lib/Target/ARM64/ARM64InstrFormats.td b/lib/Target/ARM64/ARM64InstrFormats.td index 0d5c2a95656..173f0ef4d3b 100644 --- a/lib/Target/ARM64/ARM64InstrFormats.td +++ b/lib/Target/ARM64/ARM64InstrFormats.td @@ -752,7 +752,7 @@ class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg), let Inst{19-5} = systemreg; } -// FIXME: Some of these def CPSR, others don't. Best way to model that? +// FIXME: Some of these def NZCV, others don't. Best way to model that? // Explicitly modeling each of the system register as a register class // would do it, but feels like overkill at this point. class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt), @@ -762,28 +762,29 @@ class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt), let Inst{19-5} = systemreg; } -def SystemCPSRFieldOperand : AsmOperandClass { - let Name = "SystemCPSRField"; +def SystemPStateFieldOperand : AsmOperandClass { + let Name = "SystemPStateField"; let ParserMethod = "tryParseSysReg"; } -def cpsrfield_op : Operand { - let ParserMatchClass = SystemCPSRFieldOperand; - let PrintMethod = "printSystemCPSRField"; +def pstatefield_op : Operand { + let ParserMatchClass = SystemPStateFieldOperand; + let PrintMethod = "printSystemPStateField"; } -let Defs = [CPSR] in -class MSRcpsrI : SimpleSystemI<0, (ins cpsrfield_op:$cpsr_field, imm0_15:$imm), - "msr", "\t$cpsr_field, $imm">, - Sched<[WriteSys]> { - bits<6> cpsrfield; +let Defs = [NZCV] in +class MSRpstateI + : SimpleSystemI<0, (ins pstatefield_op:$pstate_field, imm0_15:$imm), + "msr", "\t$pstate_field, $imm">, + Sched<[WriteSys]> { + bits<6> pstatefield; bits<4> imm; let Inst{20-19} = 0b00; - let Inst{18-16} = cpsrfield{5-3}; + let Inst{18-16} = pstatefield{5-3}; let Inst{15-12} = 0b0100; let Inst{11-8} = imm; - let Inst{7-5} = cpsrfield{2-0}; + let Inst{7-5} = pstatefield{2-0}; - let DecoderMethod = "DecodeSystemCPSRInstruction"; + let DecoderMethod = "DecodeSystemPStateInstruction"; } // SYS and SYSL generic system instructions. @@ -882,11 +883,11 @@ def am_brcond : Operand { class BranchCond : I<(outs), (ins dotCcode:$cond, am_brcond:$target), "b", "$cond\t$target", "", - [(ARM64brcond bb:$target, imm:$cond, CPSR)]>, + [(ARM64brcond bb:$target, imm:$cond, NZCV)]>, Sched<[WriteBr]> { let isBranch = 1; let isTerminator = 1; - let Uses = [CPSR]; + let Uses = [NZCV]; bits<4> cond; bits<19> target; @@ -1041,7 +1042,7 @@ class BaseBaseAddSubCarry, Sched<[WriteI]> { - let Uses = [CPSR]; + let Uses = [NZCV]; bits<5> Rd; bits<5> Rn; bits<5> Rm; @@ -1056,14 +1057,14 @@ class BaseBaseAddSubCarry : BaseBaseAddSubCarry; + [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>; class BaseAddSubCarrySetFlags : BaseBaseAddSubCarry { - let Defs = [CPSR]; + [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)), + (implicit NZCV)]> { + let Defs = [NZCV]; } multiclass AddSubCarry { - let isCompare = 1, Defs = [CPSR] in { + let isCompare = 1, Defs = [NZCV] in { // Add/Subtract immediate def Wri : BaseAddSubImm { @@ -1565,7 +1566,7 @@ multiclass AddSubS { let Inst{14-13} = 0b11; let Inst{31} = 1; } - } // Defs = [CPSR] + } // Defs = [NZCV] // Register/register aliases with no shift when SP is not used. def : AddSubRegAlias(NAME#"Wrs"), @@ -1770,7 +1771,7 @@ multiclass LogicalImm opc, string mnemonic, SDNode OpNode> { } multiclass LogicalImmS opc, string mnemonic, SDNode OpNode> { - let isCompare = 1, Defs = [CPSR] in { + let isCompare = 1, Defs = [NZCV] in { def Wri : BaseLogicalImm { let Inst{31} = 0; @@ -1780,7 +1781,7 @@ multiclass LogicalImmS opc, string mnemonic, SDNode OpNode> { [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> { let Inst{31} = 1; } - } // end Defs = [CPSR] + } // end Defs = [NZCV] } class BaseLogicalRegPseudo @@ -1811,10 +1812,10 @@ multiclass LogicalReg opc, bit N, string mnemonic, !cast(NAME#"Xrs"), GPR64>; } -// Split from LogicalReg to allow setting CPSR Defs +// Split from LogicalReg to allow setting NZCV Defs multiclass LogicalRegS opc, bit N, string mnemonic, SDPatternOperator OpNode = null_frag> { - let Defs = [CPSR], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { + let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { def Wrr : BaseLogicalRegPseudo; def Xrr : BaseLogicalRegPseudo; @@ -1826,7 +1827,7 @@ multiclass LogicalRegS opc, bit N, string mnemonic, [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> { let Inst{31} = 1; } - } // Defs = [CPSR] + } // Defs = [NZCV] def : LogicalRegAlias(NAME#"Wrs"), GPR32>; @@ -1849,8 +1850,8 @@ class BaseCondSetFlagsImm : I<(outs), (ins regtype:$Rn, imm0_31:$imm, imm0_15:$nzcv, ccode:$cond), asm, "\t$Rn, $imm, $nzcv, $cond", "", []>, Sched<[WriteI]> { - let Uses = [CPSR]; - let Defs = [CPSR]; + let Uses = [NZCV]; + let Defs = [NZCV]; bits<5> Rn; bits<5> imm; @@ -1881,8 +1882,8 @@ class BaseCondSetFlagsReg : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm0_15:$nzcv, ccode:$cond), asm, "\t$Rn, $Rm, $nzcv, $cond", "", []>, Sched<[WriteI]> { - let Uses = [CPSR]; - let Defs = [CPSR]; + let Uses = [NZCV]; + let Defs = [NZCV]; bits<5> Rn; bits<5> Rm; @@ -1916,9 +1917,9 @@ class BaseCondSelect op2, RegisterClass regtype, string asm> : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond), asm, "\t$Rd, $Rn, $Rm, $cond", "", [(set regtype:$Rd, - (ARM64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), CPSR))]>, + (ARM64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>, Sched<[WriteI]> { - let Uses = [CPSR]; + let Uses = [NZCV]; bits<5> Rd; bits<5> Rn; @@ -1949,9 +1950,9 @@ class BaseCondSelectOp op2, RegisterClass regtype, string asm, asm, "\t$Rd, $Rn, $Rm, $cond", "", [(set regtype:$Rd, (ARM64csel regtype:$Rn, (frag regtype:$Rm), - (i32 imm:$cond), CPSR))]>, + (i32 imm:$cond), NZCV))]>, Sched<[WriteI]> { - let Uses = [CPSR]; + let Uses = [NZCV]; bits<5> Rd; bits<5> Rn; @@ -1980,11 +1981,11 @@ multiclass CondSelectOp op2, string asm, PatFrag frag> { let Inst{31} = 1; } - def : Pat<(ARM64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), CPSR), + def : Pat<(ARM64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV), (!cast(NAME # Wr) GPR32:$Rn, GPR32:$Rm, (inv_cond_XFORM imm:$cond))>; - def : Pat<(ARM64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), CPSR), + def : Pat<(ARM64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV), (!cast(NAME # Xr) GPR64:$Rn, GPR64:$Rm, (inv_cond_XFORM imm:$cond))>; } @@ -3610,27 +3611,27 @@ class BaseTwoOperandFPComparison { - let Defs = [CPSR] in { + let Defs = [NZCV] in { def Srr : BaseTwoOperandFPComparison { + [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> { let Inst{22} = 0; } def Sri : BaseOneOperandFPComparison { + [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> { let Inst{22} = 0; } def Drr : BaseTwoOperandFPComparison { + [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> { let Inst{22} = 1; } def Dri : BaseOneOperandFPComparison { + [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> { let Inst{22} = 1; } - } // Defs = [CPSR] + } // Defs = [NZCV] } //--- @@ -3659,7 +3660,7 @@ class BaseFPCondComparison { - let Defs = [CPSR], Uses = [CPSR] in { + let Defs = [NZCV], Uses = [NZCV] in { def Srr : BaseFPCondComparison { let Inst{22} = 0; } @@ -3667,7 +3668,7 @@ multiclass FPCondComparison { def Drr : BaseFPCondComparison { let Inst{22} = 1; } - } // Defs = [CPSR], Uses = [CPSR] + } // Defs = [NZCV], Uses = [NZCV] } //--- @@ -3679,7 +3680,7 @@ class BaseFPCondSelect asm, "\t$Rd, $Rn, $Rm, $cond", "", [(set regtype:$Rd, (ARM64csel (vt regtype:$Rn), regtype:$Rm, - (i32 imm:$cond), CPSR))]>, + (i32 imm:$cond), NZCV))]>, Sched<[WriteF]> { bits<5> Rd; bits<5> Rn; @@ -3696,7 +3697,7 @@ class BaseFPCondSelect } multiclass FPCondSelect { - let Uses = [CPSR] in { + let Uses = [NZCV] in { def Srrr : BaseFPCondSelect { let Inst{22} = 0; } @@ -3704,7 +3705,7 @@ multiclass FPCondSelect { def Drrr : BaseFPCondSelect { let Inst{22} = 1; } - } // Uses = [CPSR] + } // Uses = [NZCV] } //--- diff --git a/lib/Target/ARM64/ARM64InstrInfo.cpp b/lib/Target/ARM64/ARM64InstrInfo.cpp index 95b247a0a2f..06cc40111c6 100644 --- a/lib/Target/ARM64/ARM64InstrInfo.cpp +++ b/lib/Target/ARM64/ARM64InstrInfo.cpp @@ -301,8 +301,8 @@ static unsigned canFoldIntoCSel(const MachineRegisterInfo &MRI, unsigned VReg, switch (DefMI->getOpcode()) { case ARM64::ADDSXri: case ARM64::ADDSWri: - // if CPSR is used, do not fold. - if (DefMI->findRegisterDefOperandIdx(ARM64::CPSR, true) == -1) + // if NZCV is used, do not fold. + if (DefMI->findRegisterDefOperandIdx(ARM64::NZCV, true) == -1) return 0; // fall-through to ADDXri and ADDWri. case ARM64::ADDXri: @@ -328,8 +328,8 @@ static unsigned canFoldIntoCSel(const MachineRegisterInfo &MRI, unsigned VReg, case ARM64::SUBSXrr: case ARM64::SUBSWrr: - // if CPSR is used, do not fold. - if (DefMI->findRegisterDefOperandIdx(ARM64::CPSR, true) == -1) + // if NZCV is used, do not fold. + if (DefMI->findRegisterDefOperandIdx(ARM64::NZCV, true) == -1) return 0; // fall-through to SUBXrr and SUBWrr. case ARM64::SUBXrr: @@ -559,7 +559,7 @@ bool ARM64InstrInfo::analyzeCompare(const MachineInstr *MI, unsigned &SrcReg, case ARM64::ADDSXrr: case ARM64::ADDSXrs: case ARM64::ADDSXrx: - // Replace SUBSWrr with SUBWrr if CPSR is not used. + // Replace SUBSWrr with SUBWrr if NZCV is not used. SrcReg = MI->getOperand(1).getReg(); SrcReg2 = MI->getOperand(2).getReg(); CmpMask = ~0; @@ -635,9 +635,9 @@ bool ARM64InstrInfo::optimizeCompareInstr( MachineInstr *CmpInstr, unsigned SrcReg, unsigned SrcReg2, int CmpMask, int CmpValue, const MachineRegisterInfo *MRI) const { - // Replace SUBSWrr with SUBWrr if CPSR is not used. - int Cmp_CPSR = CmpInstr->findRegisterDefOperandIdx(ARM64::CPSR, true); - if (Cmp_CPSR != -1) { + // Replace SUBSWrr with SUBWrr if NZCV is not used. + int Cmp_NZCV = CmpInstr->findRegisterDefOperandIdx(ARM64::NZCV, true); + if (Cmp_NZCV != -1) { unsigned NewOpc; switch (CmpInstr->getOpcode()) { default: @@ -662,7 +662,7 @@ bool ARM64InstrInfo::optimizeCompareInstr( const MCInstrDesc &MCID = get(NewOpc); CmpInstr->setDesc(MCID); - CmpInstr->RemoveOperand(Cmp_CPSR); + CmpInstr->RemoveOperand(Cmp_NZCV); bool succeeded = UpdateOperandRegClass(CmpInstr); (void)succeeded; assert(succeeded && "Some operands reg class are incompatible!"); @@ -684,7 +684,7 @@ bool ARM64InstrInfo::optimizeCompareInstr( // We iterate backward, starting from the instruction before CmpInstr and // stop when reaching the definition of the source register or done with the - // basic block, to check whether CPSR is used or modified in between. + // basic block, to check whether NZCV is used or modified in between. MachineBasicBlock::iterator I = CmpInstr, E = MI, B = CmpInstr->getParent()->begin(); @@ -697,15 +697,15 @@ bool ARM64InstrInfo::optimizeCompareInstr( if (MI->getParent() != CmpInstr->getParent()) return false; - // Check that CPSR isn't set between the comparison instruction and the one we + // Check that NZCV isn't set between the comparison instruction and the one we // want to change. const TargetRegisterInfo *TRI = &getRegisterInfo(); for (--I; I != E; --I) { const MachineInstr &Instr = *I; - if (Instr.modifiesRegister(ARM64::CPSR, TRI) || - Instr.readsRegister(ARM64::CPSR, TRI)) - // This instruction modifies or uses CPSR after the one we want to + if (Instr.modifiesRegister(ARM64::NZCV, TRI) || + Instr.readsRegister(ARM64::NZCV, TRI)) + // This instruction modifies or uses NZCV after the one we want to // change. We can't do this transformation. return false; if (I == B) @@ -742,11 +742,11 @@ bool ARM64InstrInfo::optimizeCompareInstr( case ARM64::ANDXri: NewOpc = ARM64::ANDSXri; break; } - // Scan forward for the use of CPSR. + // Scan forward for the use of NZCV. // When checking against MI: if it's a conditional code requires // checking of V bit, then this is not safe to do. - // It is safe to remove CmpInstr if CPSR is redefined or killed. - // If we are done with the basic block, we need to check whether CPSR is + // It is safe to remove CmpInstr if NZCV is redefined or killed. + // If we are done with the basic block, we need to check whether NZCV is // live-out. bool IsSafe = false; for (MachineBasicBlock::iterator I = CmpInstr, @@ -756,11 +756,11 @@ bool ARM64InstrInfo::optimizeCompareInstr( for (unsigned IO = 0, EO = Instr.getNumOperands(); !IsSafe && IO != EO; ++IO) { const MachineOperand &MO = Instr.getOperand(IO); - if (MO.isRegMask() && MO.clobbersPhysReg(ARM64::CPSR)) { + if (MO.isRegMask() && MO.clobbersPhysReg(ARM64::NZCV)) { IsSafe = true; break; } - if (!MO.isReg() || MO.getReg() != ARM64::CPSR) + if (!MO.isReg() || MO.getReg() != ARM64::NZCV) continue; if (MO.isDef()) { IsSafe = true; @@ -793,7 +793,7 @@ bool ARM64InstrInfo::optimizeCompareInstr( // It is not safe to remove Compare instruction if Overflow(V) is used. switch (CC) { default: - // CPSR can be used multiple times, we should continue. + // NZCV can be used multiple times, we should continue. break; case ARM64CC::VS: case ARM64CC::VC: @@ -806,22 +806,22 @@ bool ARM64InstrInfo::optimizeCompareInstr( } } - // If CPSR is not killed nor re-defined, we should check whether it is + // If NZCV is not killed nor re-defined, we should check whether it is // live-out. If it is live-out, do not optimize. if (!IsSafe) { MachineBasicBlock *ParentBlock = CmpInstr->getParent(); for (auto *MBB : ParentBlock->successors()) - if (MBB->isLiveIn(ARM64::CPSR)) + if (MBB->isLiveIn(ARM64::NZCV)) return false; } - // Update the instruction to set CPSR. + // Update the instruction to set NZCV. MI->setDesc(get(NewOpc)); CmpInstr->eraseFromParent(); bool succeeded = UpdateOperandRegClass(MI); (void)succeeded; assert(succeeded && "Some operands reg class are incompatible!"); - MI->addRegisterDefined(ARM64::CPSR, TRI); + MI->addRegisterDefined(ARM64::NZCV, TRI); return true; } @@ -1591,7 +1591,7 @@ void llvm::emitFrameOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc DL, unsigned DestReg, unsigned SrcReg, int Offset, const ARM64InstrInfo *TII, MachineInstr::MIFlag Flag, - bool SetCPSR) { + bool SetNZCV) { if (DestReg == SrcReg && Offset == 0) return; @@ -1611,7 +1611,7 @@ void llvm::emitFrameOffset(MachineBasicBlock &MBB, // assert(Offset < (1 << 24) && "unimplemented reg plus immediate"); unsigned Opc; - if (SetCPSR) + if (SetNZCV) Opc = isSub ? ARM64::SUBSXri : ARM64::ADDSXri; else Opc = isSub ? ARM64::SUBXri : ARM64::ADDXri; diff --git a/lib/Target/ARM64/ARM64InstrInfo.h b/lib/Target/ARM64/ARM64InstrInfo.h index 03822e1c3bf..8f8165b02eb 100644 --- a/lib/Target/ARM64/ARM64InstrInfo.h +++ b/lib/Target/ARM64/ARM64InstrInfo.h @@ -162,7 +162,7 @@ void emitFrameOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc DL, unsigned DestReg, unsigned SrcReg, int Offset, const ARM64InstrInfo *TII, MachineInstr::MIFlag = MachineInstr::NoFlags, - bool SetCPSR = false); + bool SetNZCV = false); /// rewriteARM64FrameIndex - Rewrite MI to access 'Offset' bytes from the /// FP. Return false if the offset could not be handled directly in MI, and diff --git a/lib/Target/ARM64/ARM64InstrInfo.td b/lib/Target/ARM64/ARM64InstrInfo.td index ddcedee04c3..b67ef790874 100644 --- a/lib/Target/ARM64/ARM64InstrInfo.td +++ b/lib/Target/ARM64/ARM64InstrInfo.td @@ -339,7 +339,7 @@ def : InstAlias<"isb", (ISB 0xf)>; def MRS : MRSI; def MSR : MSRI; -def MSRcpsr: MSRcpsrI; +def MSRpstate: MSRpstateI; // The thread pointer (on Linux, at least, where this has been implemented) is // TPIDR_EL0. @@ -847,26 +847,26 @@ defm CSINC : CondSelectOp<0, 0b01, "csinc", inc>; defm CSINV : CondSelectOp<1, 0b00, "csinv", not>; defm CSNEG : CondSelectOp<1, 0b01, "csneg", ineg>; -def : Pat<(ARM64csinv GPR32:$tval, GPR32:$fval, (i32 imm:$cc), CPSR), +def : Pat<(ARM64csinv GPR32:$tval, GPR32:$fval, (i32 imm:$cc), NZCV), (CSINVWr GPR32:$tval, GPR32:$fval, (i32 imm:$cc))>; -def : Pat<(ARM64csinv GPR64:$tval, GPR64:$fval, (i32 imm:$cc), CPSR), +def : Pat<(ARM64csinv GPR64:$tval, GPR64:$fval, (i32 imm:$cc), NZCV), (CSINVXr GPR64:$tval, GPR64:$fval, (i32 imm:$cc))>; -def : Pat<(ARM64csneg GPR32:$tval, GPR32:$fval, (i32 imm:$cc), CPSR), +def : Pat<(ARM64csneg GPR32:$tval, GPR32:$fval, (i32 imm:$cc), NZCV), (CSNEGWr GPR32:$tval, GPR32:$fval, (i32 imm:$cc))>; -def : Pat<(ARM64csneg GPR64:$tval, GPR64:$fval, (i32 imm:$cc), CPSR), +def : Pat<(ARM64csneg GPR64:$tval, GPR64:$fval, (i32 imm:$cc), NZCV), (CSNEGXr GPR64:$tval, GPR64:$fval, (i32 imm:$cc))>; -def : Pat<(ARM64csinc GPR32:$tval, GPR32:$fval, (i32 imm:$cc), CPSR), +def : Pat<(ARM64csinc GPR32:$tval, GPR32:$fval, (i32 imm:$cc), NZCV), (CSINCWr GPR32:$tval, GPR32:$fval, (i32 imm:$cc))>; -def : Pat<(ARM64csinc GPR64:$tval, GPR64:$fval, (i32 imm:$cc), CPSR), +def : Pat<(ARM64csinc GPR64:$tval, GPR64:$fval, (i32 imm:$cc), NZCV), (CSINCXr GPR64:$tval, GPR64:$fval, (i32 imm:$cc))>; -def : Pat<(ARM64csel (i32 0), (i32 1), (i32 imm:$cc), CPSR), +def : Pat<(ARM64csel (i32 0), (i32 1), (i32 imm:$cc), NZCV), (CSINCWr WZR, WZR, (i32 imm:$cc))>; -def : Pat<(ARM64csel (i64 0), (i64 1), (i32 imm:$cc), CPSR), +def : Pat<(ARM64csel (i64 0), (i64 1), (i32 imm:$cc), NZCV), (CSINCXr XZR, XZR, (i32 imm:$cc))>; -def : Pat<(ARM64csel (i32 0), (i32 -1), (i32 imm:$cc), CPSR), +def : Pat<(ARM64csel (i32 0), (i32 -1), (i32 imm:$cc), NZCV), (CSINVWr WZR, WZR, (i32 imm:$cc))>; -def : Pat<(ARM64csel (i64 0), (i64 -1), (i32 imm:$cc), CPSR), +def : Pat<(ARM64csel (i64 0), (i64 -1), (i32 imm:$cc), NZCV), (CSINVXr XZR, XZR, (i32 imm:$cc))>; // The inverse of the condition code from the alias instruction is what is used @@ -2115,8 +2115,8 @@ def F128CSEL : Pseudo<(outs FPR128:$Rd), (ins FPR128:$Rn, FPR128:$Rm, ccode:$cond), [(set (f128 FPR128:$Rd), (ARM64csel FPR128:$Rn, FPR128:$Rm, - (i32 imm:$cond), CPSR))]> { - let Uses = [CPSR]; + (i32 imm:$cond), NZCV))]> { + let Uses = [NZCV]; let usesCustomInserter = 1; } diff --git a/lib/Target/ARM64/ARM64RegisterInfo.cpp b/lib/Target/ARM64/ARM64RegisterInfo.cpp index aa7d9b70b50..d3c647bd90b 100644 --- a/lib/Target/ARM64/ARM64RegisterInfo.cpp +++ b/lib/Target/ARM64/ARM64RegisterInfo.cpp @@ -136,7 +136,7 @@ ARM64RegisterInfo::getPointerRegClass(const MachineFunction &MF, const TargetRegisterClass * ARM64RegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const { if (RC == &ARM64::CCRRegClass) - return nullptr; // Can't copy CPSR. + return nullptr; // Can't copy NZCV. return RC; } diff --git a/lib/Target/ARM64/ARM64RegisterInfo.td b/lib/Target/ARM64/ARM64RegisterInfo.td index c9193246d31..d6c5acb0b9d 100644 --- a/lib/Target/ARM64/ARM64RegisterInfo.td +++ b/lib/Target/ARM64/ARM64RegisterInfo.td @@ -119,7 +119,7 @@ def XZR : ARM64Reg<31, "xzr", [WZR]>, DwarfRegAlias; } // Condition code register. -def CPSR : ARM64Reg<0, "cpsr">; +def NZCV : ARM64Reg<0, "nzcv">; // GPR register classes with the intersections of GPR32/GPR32sp and // GPR64/GPR64sp for use by the coalescer. @@ -181,7 +181,7 @@ def GPR64pi48 : RegisterOperand">; def GPR64pi64 : RegisterOperand">; // Condition code regclass. -def CCR : RegisterClass<"ARM64", [i32], 32, (add CPSR)> { +def CCR : RegisterClass<"ARM64", [i32], 32, (add NZCV)> { let CopyCost = -1; // Don't allow copying of status registers. // CCR is not allocatable. diff --git a/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp b/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp index 3df5b8b708a..115bff89c40 100644 --- a/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp +++ b/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp @@ -680,7 +680,7 @@ public: return IsKnownRegister; } - bool isSystemCPSRField() const { + bool isSystemPStateField() const { if (!isSysReg()) return false; bool IsKnownRegister; @@ -1346,7 +1346,7 @@ public: Inst.addOperand(MCOperand::CreateImm(Bits)); } - void addSystemCPSRFieldOperands(MCInst &Inst, unsigned N) const { + void addSystemPStateFieldOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); bool Valid; diff --git a/lib/Target/ARM64/Disassembler/ARM64Disassembler.cpp b/lib/Target/ARM64/Disassembler/ARM64Disassembler.cpp index 2ada4a4cf9e..0fc559c5cf7 100644 --- a/lib/Target/ARM64/Disassembler/ARM64Disassembler.cpp +++ b/lib/Target/ARM64/Disassembler/ARM64Disassembler.cpp @@ -137,9 +137,10 @@ static DecodeStatus DecodeBaseAddSubImm(llvm::MCInst &Inst, uint32_t insn, static DecodeStatus DecodeUnconditionalBranch(llvm::MCInst &Inst, uint32_t insn, uint64_t Address, const void *Decoder); -static DecodeStatus DecodeSystemCPSRInstruction(llvm::MCInst &Inst, - uint32_t insn, uint64_t Address, - const void *Decoder); +static DecodeStatus DecodeSystemPStateInstruction(llvm::MCInst &Inst, + uint32_t insn, + uint64_t Address, + const void *Decoder); static DecodeStatus DecodeTestAndBranch(llvm::MCInst &Inst, uint32_t insn, uint64_t Address, const void *Decoder); static DecodeStatus DecodeSIMDLdStPost(llvm::MCInst &Inst, uint32_t insn, @@ -1408,20 +1409,20 @@ static DecodeStatus DecodeUnconditionalBranch(llvm::MCInst &Inst, uint32_t insn, return Success; } -static DecodeStatus DecodeSystemCPSRInstruction(llvm::MCInst &Inst, - uint32_t insn, uint64_t Addr, - const void *Decoder) { +static DecodeStatus DecodeSystemPStateInstruction(llvm::MCInst &Inst, + uint32_t insn, uint64_t Addr, + const void *Decoder) { uint64_t op1 = fieldFromInstruction(insn, 16, 3); uint64_t op2 = fieldFromInstruction(insn, 5, 3); uint64_t crm = fieldFromInstruction(insn, 8, 4); - uint64_t cpsr_field = (op1 << 3) | op2; + uint64_t pstate_field = (op1 << 3) | op2; - Inst.addOperand(MCOperand::CreateImm(cpsr_field)); + Inst.addOperand(MCOperand::CreateImm(pstate_field)); Inst.addOperand(MCOperand::CreateImm(crm)); bool ValidNamed; - (void)ARM64PState::PStateMapper().toString(cpsr_field, ValidNamed); + (void)ARM64PState::PStateMapper().toString(pstate_field, ValidNamed); return ValidNamed ? Success : Fail; } diff --git a/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp b/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp index f9c562e92af..266b5f294b5 100644 --- a/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp +++ b/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.cpp @@ -1418,8 +1418,8 @@ void ARM64InstPrinter::printMSRSystemRegister(const MCInst *MI, unsigned OpNo, O << StringRef(Name).upper(); } -void ARM64InstPrinter::printSystemCPSRField(const MCInst *MI, unsigned OpNo, - raw_ostream &O) { +void ARM64InstPrinter::printSystemPStateField(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { unsigned Val = MI->getOperand(OpNo).getImm(); bool Valid; diff --git a/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.h b/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.h index c3488a01d19..b3e693f68f9 100644 --- a/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.h +++ b/lib/Target/ARM64/InstPrinter/ARM64InstPrinter.h @@ -119,7 +119,7 @@ protected: void printBarrierOption(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printMSRSystemRegister(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printMRSSystemRegister(const MCInst *MI, unsigned OpNum, raw_ostream &O); - void printSystemCPSRField(const MCInst *MI, unsigned OpNum, raw_ostream &O); + void printSystemPStateField(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printSIMDType10Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O); };