[ARMv8] Add support for the NEON instructions vmaxnm/vminnm.

This adds a new class for non-predicable NEON instructions and a
new DecoderNamespace for v8 NEON instructions.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@186504 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Joey Gouly 2013-07-17 13:59:38 +00:00
parent 946dbd83df
commit 19c14abf1c
6 changed files with 121 additions and 0 deletions

View File

@ -180,10 +180,12 @@ let Properties = [IntrNoMem, Commutative] in {
// Vector Maximum.
def int_arm_neon_vmaxs : Neon_2Arg_Intrinsic;
def int_arm_neon_vmaxu : Neon_2Arg_Intrinsic;
def int_arm_neon_vmaxnm : Neon_2Arg_Intrinsic;
// Vector Minimum.
def int_arm_neon_vmins : Neon_2Arg_Intrinsic;
def int_arm_neon_vminu : Neon_2Arg_Intrinsic;
def int_arm_neon_vminnm : Neon_2Arg_Intrinsic;
// Vector Reciprocal Step.
def int_arm_neon_vrecps : Neon_2Arg_Intrinsic;

View File

@ -167,6 +167,8 @@ namespace {
const { return 0; }
unsigned NEONThumb2DupPostEncoder(const MachineInstr &MI,unsigned Val)
const { return 0; }
unsigned NEONThumb2V8PostEncoder(const MachineInstr &MI,unsigned Val)
const { return 0; }
unsigned VFPThumb2PostEncoder(const MachineInstr&MI, unsigned Val)
const { return 0; }
unsigned getAdrLabelOpValue(const MachineInstr &MI, unsigned Op)

View File

@ -1830,6 +1830,21 @@ class NeonXI<dag oops, dag iops, AddrMode am, IndexMode im, Format f,
let DecoderNamespace = "NEON";
}
// Same as NeonI except it is not predicated
class NeonInp<dag oops, dag iops, AddrMode am, IndexMode im, Format f,
InstrItinClass itin, string opc, string dt, string asm, string cstr,
list<dag> pattern>
: InstARM<am, 4, im, f, NeonDomain, cstr, itin> {
let OutOperandList = oops;
let InOperandList = iops;
let AsmString = !strconcat(opc, ".", dt, "\t", asm);
let Pattern = pattern;
list<Predicate> Predicates = [HasNEON];
let DecoderNamespace = "NEON";
let Inst{31-28} = 0b1111;
}
class NLdSt<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4,
dag oops, dag iops, InstrItinClass itin,
string opc, string dt, string asm, string cstr, list<dag> pattern>
@ -2030,6 +2045,32 @@ class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4,
let Inst{5} = Vm{4};
}
class N3Vnp<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6,
bit op4, dag oops, dag iops,Format f, InstrItinClass itin,
string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy,
SDPatternOperator IntOp, bit Commutable, list<dag> pattern>
: NeonInp<oops, iops, AddrModeNone, IndexModeNone, f, itin, OpcodeStr,
Dt, "$Vd, $Vn, $Vm", "", pattern> {
bits<5> Vd;
bits<5> Vn;
bits<5> Vm;
// Encode instruction operands
let Inst{22} = Vd{4};
let Inst{15-12} = Vd{3-0};
let Inst{19-16} = Vn{3-0};
let Inst{7} = Vn{4};
let Inst{5} = Vm{4};
let Inst{3-0} = Vm{3-0};
// Encode constant bits
let Inst{27-23} = op27_23;
let Inst{21-20} = op21_20;
let Inst{11-8} = op11_8;
let Inst{6} = op6;
let Inst{4} = op4;
}
class N3VLane32<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6,
bit op4, dag oops, dag iops, Format f, InstrItinClass itin,
string opc, string dt, string asm, string cstr,

View File

@ -2541,6 +2541,16 @@ class N3VDInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
let TwoOperandAliasConstraint = "$Vn = $Vd";
let isCommutable = Commutable;
}
class N3VDIntnp<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6,
bit op4, Format f, InstrItinClass itin, string OpcodeStr,
string Dt, ValueType ResTy, ValueType OpTy,
SDPatternOperator IntOp, bit Commutable>
: N3Vnp<op27_23, op21_20, op11_8, op6, op4,
(outs DPR:$Vd), (ins DPR:$Vn, DPR:$Vm), f, itin, OpcodeStr, Dt,
ResTy, OpTy, IntOp, Commutable,
[(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]>;
class N3VDIntSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
string OpcodeStr, string Dt, ValueType Ty, SDPatternOperator IntOp>
: N3VLane32<0, 1, op21_20, op11_8, 1, 0,
@ -2552,6 +2562,7 @@ class N3VDIntSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
imm:$lane)))))]> {
let isCommutable = 0;
}
class N3VDIntSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
string OpcodeStr, string Dt, ValueType Ty, SDPatternOperator IntOp>
: N3VLane16<0, 1, op21_20, op11_8, 1, 0,
@ -2584,6 +2595,16 @@ class N3VQInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
let TwoOperandAliasConstraint = "$Vn = $Vd";
let isCommutable = Commutable;
}
class N3VQIntnp<bits<5> op27_23, bits<2> op21_20, bits<4> op11_8, bit op6,
bit op4, Format f, InstrItinClass itin, string OpcodeStr,
string Dt, ValueType ResTy, ValueType OpTy,
SDPatternOperator IntOp, bit Commutable>
: N3Vnp<op27_23, op21_20, op11_8, op6, op4,
(outs QPR:$Vd), (ins QPR:$Vn, QPR:$Vm), f, itin, OpcodeStr, Dt,
ResTy, OpTy, IntOp, Commutable,
[(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vn), (OpTy QPR:$Vm))))]>;
class N3VQIntSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
string OpcodeStr, string Dt,
ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
@ -4659,6 +4680,18 @@ def VMAXfq : N3VQInt<0, 0, 0b00, 0b1111, 0, N3RegFrm, IIC_VBINQ,
"vmax", "f32",
v4f32, v4f32, int_arm_neon_vmaxs, 1>;
// VMAXNM
let PostEncoderMethod = "NEONThumb2V8PostEncoder", DecoderNamespace = "v8NEON" in {
def VMAXNMND : N3VDIntnp<0b000110, 0b00, 0b1111, 0, 1,
N3RegFrm, NoItinerary, "vmaxnm", "f32",
v2f32, v2f32, int_arm_neon_vmaxnm, 1>,
Requires<[HasV8, HasNEON]>;
def VMAXNMNQ : N3VQIntnp<0b00110, 0b00, 0b1111, 1, 1,
N3RegFrm, NoItinerary, "vmaxnm", "f32",
v4f32, v4f32, int_arm_neon_vmaxnm, 1>,
Requires<[HasV8, HasNEON]>;
}
// VMIN : Vector Minimum
defm VMINs : N3VInt_QHS<0, 0, 0b0110, 1, N3RegFrm,
IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,
@ -4673,6 +4706,18 @@ def VMINfq : N3VQInt<0, 0, 0b10, 0b1111, 0, N3RegFrm, IIC_VBINQ,
"vmin", "f32",
v4f32, v4f32, int_arm_neon_vmins, 1>;
// VMINNM
let PostEncoderMethod = "NEONThumb2V8PostEncoder", DecoderNamespace = "v8NEON" in {
def VMINNMND : N3VDIntnp<0b00110, 0b10, 0b1111, 0, 1,
N3RegFrm, NoItinerary, "vminnm", "f32",
v2f32, v2f32, int_arm_neon_vminnm, 1>,
Requires<[HasV8, HasNEON]>;
def VMINNMNQ : N3VQIntnp<0b00110, 0b10, 0b1111, 1, 1,
N3RegFrm, NoItinerary, "vminnm", "f32",
v4f32, v4f32, int_arm_neon_vminnm, 1>,
Requires<[HasV8, HasNEON]>;
}
// Vector Pairwise Operations.
// VPADD : Vector Pairwise Add

View File

@ -499,7 +499,14 @@ DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
}
MI.clear();
result = decodeInstruction(DecoderTablev8NEON32, MI, insn, Address,
this, STI);
if (result != MCDisassembler::Fail) {
Size = 4;
return result;
}
MI.clear();
Size = 0;
return MCDisassembler::Fail;
}
@ -818,6 +825,17 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
}
}
MI.clear();
uint32_t NEONv8Insn = insn32;
NEONv8Insn &= 0xF3FFFFFF; // Clear bits 27-26
result = decodeInstruction(DecoderTablev8NEON32, MI, NEONv8Insn, Address,
this, STI);
if (result != MCDisassembler::Fail) {
Size = 4;
return result;
}
MI.clear();
Size = 0;
return MCDisassembler::Fail;
}

View File

@ -315,6 +315,8 @@ public:
unsigned EncodedValue) const;
unsigned NEONThumb2DupPostEncoder(const MCInst &MI,
unsigned EncodedValue) const;
unsigned NEONThumb2V8PostEncoder(const MCInst &MI,
unsigned EncodedValue) const;
unsigned VFPThumb2PostEncoder(const MCInst &MI,
unsigned EncodedValue) const;
@ -389,6 +391,17 @@ unsigned ARMMCCodeEmitter::NEONThumb2DupPostEncoder(const MCInst &MI,
return EncodedValue;
}
/// Post-process encoded NEON v8 instructions, and rewrite them to Thumb2 form
/// if we are in Thumb2.
unsigned ARMMCCodeEmitter::NEONThumb2V8PostEncoder(const MCInst &MI,
unsigned EncodedValue) const {
if (isThumb2()) {
EncodedValue |= 0xC000000; // Set bits 27-26
}
return EncodedValue;
}
/// VFPThumb2PostEncoder - Post-process encoded VFP instructions and rewrite
/// them to their Thumb2 form if we are currently in Thumb2 mode.
unsigned ARMMCCodeEmitter::