From d451f888b85d01caa586b0d45bacb41836fd2c31 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Thu, 21 Oct 2010 20:21:49 +0000 Subject: [PATCH] ARM encodes Q registers as 2xregno (i.e. the number of the D register that corresponds to the lower half of the Q register), rather than with just regno. This allows us to unify the encodings for a lot of different NEON instrucitons that differ only in whether they have Q or D register operands. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@117056 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMBaseInfo.h | 46 +++++++------- lib/Target/ARM/ARMInstrFormats.td | 12 ++++ lib/Target/ARM/ARMInstrNEON.td | 100 +++--------------------------- 3 files changed, 44 insertions(+), 114 deletions(-) diff --git a/lib/Target/ARM/ARMBaseInfo.h b/lib/Target/ARM/ARMBaseInfo.h index 2da7be25a13..17a65be458d 100644 --- a/lib/Target/ARM/ARMBaseInfo.h +++ b/lib/Target/ARM/ARMBaseInfo.h @@ -132,37 +132,37 @@ inline static unsigned getARMRegisterNumbering(unsigned Reg) { default: llvm_unreachable("Unknown ARM register!"); case R0: case S0: case D0: case Q0: return 0; - case R1: case S1: case D1: case Q1: return 1; - case R2: case S2: case D2: case Q2: return 2; - case R3: case S3: case D3: case Q3: return 3; - case R4: case S4: case D4: case Q4: return 4; - case R5: case S5: case D5: case Q5: return 5; - case R6: case S6: case D6: case Q6: return 6; - case R7: case S7: case D7: case Q7: return 7; - case R8: case S8: case D8: case Q8: return 8; - case R9: case S9: case D9: case Q9: return 9; - case R10: case S10: case D10: case Q10: return 10; - case R11: case S11: case D11: case Q11: return 11; - case R12: case S12: case D12: case Q12: return 12; - case SP: case S13: case D13: case Q13: return 13; - case LR: case S14: case D14: case Q14: return 14; - case PC: case S15: case D15: case Q15: return 15; + case R1: case S1: case D1: return 1; + case R2: case S2: case D2: case Q1: return 2; + case R3: case S3: case D3: return 3; + case R4: case S4: case D4: case Q2: return 4; + case R5: case S5: case D5: return 5; + case R6: case S6: case D6: case Q3: return 6; + case R7: case S7: case D7: return 7; + case R8: case S8: case D8: case Q4: return 8; + case R9: case S9: case D9: return 9; + case R10: case S10: case D10: case Q5: return 10; + case R11: case S11: case D11: return 11; + case R12: case S12: case D12: case Q6: return 12; + case SP: case S13: case D13: return 13; + case LR: case S14: case D14: case Q7: return 14; + case PC: case S15: case D15: return 15; - case S16: case D16: return 16; + case S16: case D16: case Q8: return 16; case S17: case D17: return 17; - case S18: case D18: return 18; + case S18: case D18: case Q9: return 18; case S19: case D19: return 19; - case S20: case D20: return 20; + case S20: case D20: case Q10: return 20; case S21: case D21: return 21; - case S22: case D22: return 22; + case S22: case D22: case Q11: return 22; case S23: case D23: return 23; - case S24: case D24: return 24; + case S24: case D24: case Q12: return 24; case S25: case D25: return 25; - case S26: case D26: return 26; + case S26: case D26: case Q13: return 26; case S27: case D27: return 27; - case S28: case D28: return 28; + case S28: case D28: case Q14: return 28; case S29: case D29: return 29; - case S30: case D30: return 30; + case S30: case D30: case Q15: return 30; case S31: case D31: return 31; } } diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index 3a6e5d6e1cb..fec626acf5e 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -1673,6 +1673,18 @@ class N3V op21_20, bits<4> op11_8, bit op6, bit op4, let Inst{11-8} = op11_8; let Inst{6} = op6; let Inst{4} = op4; + + // Instruction operands. + bits<5> Vd; + bits<5> Vn; + bits<5> Vm; + + let Inst{15-12} = Vd{3-0}; + let Inst{22} = Vd{4}; + let Inst{19-16} = Vn{3-0}; + let Inst{7} = Vn{4}; + let Inst{3-0} = Vm{3-0}; + let Inst{5} = Vm{4}; } // Same as N3V except it doesn't have a data type suffix. diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td index e9fb12575aa..f90a11db94d 100644 --- a/lib/Target/ARM/ARMInstrNEON.td +++ b/lib/Target/ARM/ARMInstrNEON.td @@ -1177,21 +1177,9 @@ class N3VD op21_20, bits<4> op11_8, bit op4, InstrItinClass itin, string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy, SDNode OpNode, bit Commutable> : N3V { - // Instruction operands. - bits<5> Dd; - bits<5> Dn; - bits<5> Dm; - - let Inst{15-12} = Dd{3-0}; - let Inst{22} = Dd{4}; - let Inst{19-16} = Dn{3-0}; - let Inst{7} = Dn{4}; - let Inst{3-0} = Dm{3-0}; - let Inst{5} = Dm{4}; - + (outs DPR:$Vd), (ins DPR:$Vn, DPR:$Vm), N3RegFrm, itin, + OpcodeStr, Dt, "$Vd, $Vn, $Vm", "", + [(set DPR:$Vd, (ResTy (OpNode (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]> { let isCommutable = Commutable; } // Same as N3VD but no data type. @@ -1236,20 +1224,6 @@ class N3VQ op21_20, bits<4> op11_8, bit op4, OpcodeStr, Dt, "$Qd, $Qn, $Qm", "", [(set QPR:$Qd, (ResTy (OpNode (OpTy QPR:$Qn), (OpTy QPR:$Qm))))]> { let isCommutable = Commutable; - - bits<4> Qd; - bits<4> Qn; - bits<4> Qm; - - let Inst{15-13} = Qd{2-0}; - let Inst{22} = Qd{3}; - let Inst{12} = 0; - let Inst{19-17} = Qn{2-0}; - let Inst{7} = Qn{3}; - let Inst{16} = 0; - let Inst{3-1} = Qm{2-0}; - let Inst{5} = Qm{3}; - let Inst{0} = 0; } class N3VQX op21_20, bits<4> op11_8, bit op4, InstrItinClass itin, string OpcodeStr, @@ -1289,22 +1263,10 @@ class N3VDInt op21_20, bits<4> op11_8, bit op4, Format f, InstrItinClass itin, string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy, Intrinsic IntOp, bit Commutable> : N3V { + (outs DPR:$Vd), (ins DPR:$Vn, DPR:$Vm), f, itin, + OpcodeStr, Dt, "$Vd, $Vn, $Vm", "", + [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]> { let isCommutable = Commutable; - - // Instruction operands. - bits<5> Dd; - bits<5> Dn; - bits<5> Dm; - - let Inst{15-12} = Dd{3-0}; - let Inst{22} = Dd{4}; - let Inst{19-16} = Dn{3-0}; - let Inst{7} = Dn{4}; - let Inst{3-0} = Dm{3-0}; - let Inst{5} = Dm{4}; } class N3VDIntSL op21_20, bits<4> op11_8, InstrItinClass itin, string OpcodeStr, string Dt, ValueType Ty, Intrinsic IntOp> @@ -1332,25 +1294,10 @@ class N3VQInt op21_20, bits<4> op11_8, bit op4, Format f, InstrItinClass itin, string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy, Intrinsic IntOp, bit Commutable> : N3V { + (outs QPR:$Vd), (ins QPR:$Vn, QPR:$Vm), f, itin, + OpcodeStr, Dt, "$Vd, $Vn, $Vm", "", + [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vn), (OpTy QPR:$Vm))))]> { let isCommutable = Commutable; - - // Instruction operands. - bits<4> Qd; - bits<4> Qn; - bits<4> Qm; - - let Inst{15-13} = Qd{2-0}; - let Inst{22} = Qd{3}; - let Inst{12} = 0; - let Inst{19-17} = Qn{2-0}; - let Inst{7} = Qn{3}; - let Inst{16} = 0; - let Inst{3-1} = Qm{2-0}; - let Inst{5} = Qm{3}; - let Inst{0} = 0; } class N3VQIntSL op21_20, bits<4> op11_8, InstrItinClass itin, string OpcodeStr, string Dt, @@ -1629,21 +1576,6 @@ class N3VLExt op21_20, bits<4> op11_8, bit op4, [(set QPR:$Qd, (OpNode (TyQ (ExtOp (TyD DPR:$Dn))), (TyQ (ExtOp (TyD DPR:$Dm)))))]> { let isCommutable = Commutable; - - // Instruction operands. - bits<4> Qd; - bits<5> Dn; - bits<5> Dm; - - let Inst{15-13} = Qd{2-0}; - let Inst{22} = Qd{3}; - let Inst{12} = 0; - let Inst{19-16} = Dn{3-0}; - let Inst{7} = Dn{4}; - let Inst{3-0} = Dm{3-0}; - let Inst{5} = Dm{4}; - - let isCommutable = Commutable; } // Long 3-register intrinsics with explicit extend (VABDL). @@ -1700,20 +1632,6 @@ class N3VW op21_20, bits<4> op11_8, bit op4, [(set QPR:$Qd, (OpNode (TyQ QPR:$Qn), (TyQ (ExtOp (TyD DPR:$Dm)))))]> { let isCommutable = Commutable; - - // Instruction operands. - bits<4> Qd; - bits<4> Qn; - bits<5> Dm; - - let Inst{15-13} = Qd{2-0}; - let Inst{22} = Qd{3}; - let Inst{12} = 0; - let Inst{19-17} = Qn{2-0}; - let Inst{7} = Qn{3}; - let Inst{16} = 0; - let Inst{3-0} = Dm{3-0}; - let Inst{5} = Dm{4}; } // Pairwise long 2-register intrinsics, both double- and quad-register.