From e56f9085b1e96f0cc302c678f1c00877676e455e Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Sat, 12 Sep 2009 22:21:08 +0000 Subject: [PATCH] Add QPR_VFP2 regclass and add copy_to_regclass nodes, where needed to constraint the register usage. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@81635 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMBaseInstrInfo.cpp | 14 +++++++++++--- lib/Target/ARM/ARMInstrNEON.td | 12 ++++++++---- lib/Target/ARM/ARMRegisterInfo.td | 7 +++++++ 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index 9da847a5762..52af9786954 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -613,6 +613,7 @@ ARMBaseInstrInfo::copyRegToReg(MachineBasicBlock &MBB, if (DestRC != SrcRC) { // Allow DPR / DPR_VFP2 / DPR_8 cross-class copies + // Allow QPR / QPR_VFP2 cross-class copies if (DestRC == ARM::DPRRegisterClass) { if (SrcRC == ARM::DPR_VFP2RegisterClass || SrcRC == ARM::DPR_8RegisterClass) { @@ -628,6 +629,10 @@ ARMBaseInstrInfo::copyRegToReg(MachineBasicBlock &MBB, SrcRC == ARM::DPR_VFP2RegisterClass) { } else return false; + } else if ((DestRC == ARM::QPRRegisterClass && + SrcRC == ARM::QPR_VFP2RegisterClass) || + (DestRC == ARM::QPR_VFP2RegisterClass && + SrcRC == ARM::QPRRegisterClass)) { } else return false; } @@ -643,7 +648,8 @@ ARMBaseInstrInfo::copyRegToReg(MachineBasicBlock &MBB, (DestRC == ARM::DPR_8RegisterClass)) { AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYD), DestReg) .addReg(SrcReg)); - } else if (DestRC == ARM::QPRRegisterClass) { + } else if (DestRC == ARM::QPRRegisterClass || + DestRC == ARM::QPR_VFP2RegisterClass) { BuildMI(MBB, I, DL, get(ARM::VMOVQ), DestReg).addReg(SrcReg); } else { return false; @@ -674,7 +680,8 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, .addReg(SrcReg, getKillRegState(isKill)) .addFrameIndex(FI).addImm(0)); } else { - assert(RC == ARM::QPRRegisterClass && "Unknown regclass!"); + assert((RC == ARM::QPRRegisterClass || + RC == ARM::QPR_VFP2RegisterClass) && "Unknown regclass!"); // FIXME: Neon instructions should support predicates BuildMI(MBB, I, DL, get(ARM::VSTRQ)).addReg(SrcReg, getKillRegState(isKill)) .addFrameIndex(FI).addImm(0); @@ -700,7 +707,8 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDS), DestReg) .addFrameIndex(FI).addImm(0)); } else { - assert(RC == ARM::QPRRegisterClass && "Unknown regclass!"); + assert((RC == ARM::QPRRegisterClass || + RC == ARM::QPR_VFP2RegisterClass) && "Unknown regclass!"); // FIXME: Neon instructions should support predicates BuildMI(MBB, I, DL, get(ARM::VLDRQ), DestReg).addFrameIndex(FI).addImm(0); } diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td index e9181231609..01b61b5d1dd 100644 --- a/lib/Target/ARM/ARMInstrNEON.td +++ b/lib/Target/ARM/ARMInstrNEON.td @@ -2115,9 +2115,11 @@ def : Pat<(extractelt (v4i32 QPR:$src), imm:$lane), (DSubReg_i32_reg imm:$lane))), (SubReg_i32_lane imm:$lane))>; def : Pat<(extractelt (v2f32 DPR:$src1), imm:$src2), - (EXTRACT_SUBREG DPR:$src1, (SSubReg_f32_reg imm:$src2))>; + (EXTRACT_SUBREG (COPY_TO_REGCLASS DPR:$src1, DPR_VFP2), + (SSubReg_f32_reg imm:$src2))>; def : Pat<(extractelt (v4f32 QPR:$src1), imm:$src2), - (EXTRACT_SUBREG QPR:$src1, (SSubReg_f32_reg imm:$src2))>; + (EXTRACT_SUBREG (COPY_TO_REGCLASS QPR:$src1, QPR_VFP2), + (SSubReg_f32_reg imm:$src2))>; //def : Pat<(extractelt (v2i64 QPR:$src1), imm:$src2), // (EXTRACT_SUBREG QPR:$src1, (DSubReg_f64_reg imm:$src2))>; def : Pat<(extractelt (v2f64 QPR:$src1), imm:$src2), @@ -2163,9 +2165,11 @@ def : Pat<(insertelt (v4i32 QPR:$src1), GPR:$src2, imm:$lane), (DSubReg_i32_reg imm:$lane)))>; def : Pat<(v2f32 (insertelt DPR:$src1, SPR:$src2, imm:$src3)), - (INSERT_SUBREG DPR:$src1, SPR:$src2, (SSubReg_f32_reg imm:$src3))>; + (INSERT_SUBREG (COPY_TO_REGCLASS DPR:$src1, DPR_VFP2), + SPR:$src2, (SSubReg_f32_reg imm:$src3))>; def : Pat<(v4f32 (insertelt QPR:$src1, SPR:$src2, imm:$src3)), - (INSERT_SUBREG QPR:$src1, SPR:$src2, (SSubReg_f32_reg imm:$src3))>; + (INSERT_SUBREG (COPY_TO_REGCLASS QPR:$src1, QPR_VFP2), + SPR:$src2, (SSubReg_f32_reg imm:$src3))>; //def : Pat<(v2i64 (insertelt QPR:$src1, DPR:$src2, imm:$src3)), // (INSERT_SUBREG QPR:$src1, DPR:$src2, (DSubReg_f64_reg imm:$src3))>; diff --git a/lib/Target/ARM/ARMRegisterInfo.td b/lib/Target/ARM/ARMRegisterInfo.td index 9183fa078d4..b20dfc0b61f 100644 --- a/lib/Target/ARM/ARMRegisterInfo.td +++ b/lib/Target/ARM/ARMRegisterInfo.td @@ -327,6 +327,13 @@ def QPR : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], 128, let SubRegClassList = [SPR, SPR, SPR, SPR, DPR, DPR]; } +// Subset of QPR that have 32-bit SPR subregs. +def QPR_VFP2 : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], + 128, + [Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]> { + let SubRegClassList = [SPR, SPR, SPR, SPR, DPR, DPR]; +} + // Condition code registers. def CCR : RegisterClass<"ARM", [i32], 32, [CPSR]>;