File: X86Instr3DNow.td

package info (click to toggle)
llvm-toolchain-6.0 1%3A6.0.1-10
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 598,080 kB
  • sloc: cpp: 3,046,253; ansic: 595,057; asm: 271,965; python: 128,926; objc: 106,554; sh: 21,906; lisp: 10,191; pascal: 6,094; ml: 5,544; perl: 5,265; makefile: 2,227; cs: 2,027; xml: 686; php: 212; csh: 117
file content (150 lines) | stat: -rw-r--r-- 6,394 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
//===-- X86Instr3DNow.td - The 3DNow! Instruction Set ------*- tablegen -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file describes the 3DNow! instruction set, which extends MMX to support
// floating point and also adds a few more random instructions for good measure.
//
//===----------------------------------------------------------------------===//

let Sched = WriteFAdd in {
def I3DNOW_FALU_ITINS : OpndItins<
  IIC_3DNOW_FALU_RR, IIC_3DNOW_FALU_RM
>;
}

let Sched = WriteCvtF2I in {
def I3DNOW_FCVT_F2I_ITINS : OpndItins<
  IIC_3DNOW_FCVT_F2I_RR, IIC_3DNOW_FCVT_F2I_RM
>;
}

let Sched = WriteCvtI2F in {
def I3DNOW_FCVT_I2F_ITINS : OpndItins<
  IIC_3DNOW_FCVT_I2F_RR, IIC_3DNOW_FCVT_I2F_RM
>;
}

let Sched = WriteVecIMul in {
def I3DNOW_MISC_FUNC_ITINS : OpndItins<
  IIC_3DNOW_MISC_FUNC_REG, IIC_3DNOW_MISC_FUNC_MEM
>;
}

let Sched = WriteShuffle in {
def I3DNOW_PSHUF_ITINS : OpndItins<
  IIC_MMX_PSHUF, IIC_MMX_PSHUF
>;
}

class I3DNow<bits<8> o, Format F, dag outs, dag ins, string asm, list<dag> pat,
             InstrItinClass itin>
      : I<o, F, outs, ins, asm, pat, itin>, TB, Requires<[Has3DNow]> {
}

class I3DNow_binop<bits<8> o, Format F, dag ins, string Mnemonic, list<dag> pat,
                   InstrItinClass itin>
      : I3DNow<o, F, (outs VR64:$dst), ins,
          !strconcat(Mnemonic, "\t{$src2, $dst|$dst, $src2}"), pat, itin>,
        Has3DNow0F0FOpcode {
  // FIXME: The disassembler doesn't support Has3DNow0F0FOpcode yet.
  let isAsmParserOnly = 1;
  let Constraints = "$src1 = $dst";
}

class I3DNow_conv<bits<8> o, Format F, dag ins, string Mnemonic, list<dag> pat,
                  InstrItinClass itin>
      : I3DNow<o, F, (outs VR64:$dst), ins,
          !strconcat(Mnemonic, "\t{$src, $dst|$dst, $src}"), pat, itin>,
        Has3DNow0F0FOpcode {
  // FIXME: The disassembler doesn't support Has3DNow0F0FOpcode yet.
  let isAsmParserOnly = 1;
}

multiclass I3DNow_binop_rm_int<bits<8> opc, string Mn, OpndItins itins,
                               bit Commutable = 0, string Ver = ""> {
  let isCommutable = Commutable in
  def rr : I3DNow_binop<opc, MRMSrcReg, (ins VR64:$src1, VR64:$src2), Mn,
    [(set VR64:$dst, (!cast<Intrinsic>(
      !strconcat("int_x86_3dnow", Ver, "_", Mn)) VR64:$src1, VR64:$src2))],
      itins.rr>, Sched<[itins.Sched]>;
  def rm : I3DNow_binop<opc, MRMSrcMem, (ins VR64:$src1, i64mem:$src2), Mn,
    [(set VR64:$dst, (!cast<Intrinsic>(
      !strconcat("int_x86_3dnow", Ver, "_", Mn)) VR64:$src1,
        (bitconvert (load_mmx addr:$src2))))], itins.rm>,
        Sched<[itins.Sched.Folded, ReadAfterLd]>;
}

multiclass I3DNow_conv_rm_int<bits<8> opc, string Mn, OpndItins itins,
                              string Ver = ""> {
  def rr : I3DNow_conv<opc, MRMSrcReg, (ins VR64:$src), Mn,
    [(set VR64:$dst, (!cast<Intrinsic>(
      !strconcat("int_x86_3dnow", Ver, "_", Mn)) VR64:$src))], itins.rr>,
      Sched<[itins.Sched]>;
  def rm : I3DNow_conv<opc, MRMSrcMem, (ins i64mem:$src), Mn,
    [(set VR64:$dst, (!cast<Intrinsic>(
      !strconcat("int_x86_3dnow", Ver, "_", Mn))
        (bitconvert (load_mmx addr:$src))))], itins.rm>,
        Sched<[itins.Sched.Folded, ReadAfterLd]>;
}

defm PAVGUSB  : I3DNow_binop_rm_int<0xBF, "pavgusb", I3DNOW_MISC_FUNC_ITINS, 1>;
defm PF2ID    : I3DNow_conv_rm_int<0x1D, "pf2id", I3DNOW_FCVT_F2I_ITINS>;
defm PFACC    : I3DNow_binop_rm_int<0xAE, "pfacc", I3DNOW_FALU_ITINS>;
defm PFADD    : I3DNow_binop_rm_int<0x9E, "pfadd", I3DNOW_FALU_ITINS, 1>;
defm PFCMPEQ  : I3DNow_binop_rm_int<0xB0, "pfcmpeq", I3DNOW_FALU_ITINS, 1>;
defm PFCMPGE  : I3DNow_binop_rm_int<0x90, "pfcmpge", I3DNOW_FALU_ITINS>;
defm PFCMPGT  : I3DNow_binop_rm_int<0xA0, "pfcmpgt", I3DNOW_FALU_ITINS>;
defm PFMAX    : I3DNow_binop_rm_int<0xA4, "pfmax", I3DNOW_FALU_ITINS>;
defm PFMIN    : I3DNow_binop_rm_int<0x94, "pfmin", I3DNOW_FALU_ITINS>;
defm PFMUL    : I3DNow_binop_rm_int<0xB4, "pfmul", I3DNOW_FALU_ITINS, 1>;
defm PFRCP    : I3DNow_conv_rm_int<0x96, "pfrcp", I3DNOW_FALU_ITINS>;
defm PFRCPIT1 : I3DNow_binop_rm_int<0xA6, "pfrcpit1", I3DNOW_FALU_ITINS>;
defm PFRCPIT2 : I3DNow_binop_rm_int<0xB6, "pfrcpit2", I3DNOW_FALU_ITINS>;
defm PFRSQIT1 : I3DNow_binop_rm_int<0xA7, "pfrsqit1", I3DNOW_FALU_ITINS>;
defm PFRSQRT  : I3DNow_conv_rm_int<0x97, "pfrsqrt", I3DNOW_FALU_ITINS>;
defm PFSUB    : I3DNow_binop_rm_int<0x9A, "pfsub", I3DNOW_FALU_ITINS, 1>;
defm PFSUBR   : I3DNow_binop_rm_int<0xAA, "pfsubr", I3DNOW_FALU_ITINS, 1>;
defm PI2FD    : I3DNow_conv_rm_int<0x0D, "pi2fd", I3DNOW_FCVT_I2F_ITINS>;
defm PMULHRW  : I3DNow_binop_rm_int<0xB7, "pmulhrw", I3DNOW_MISC_FUNC_ITINS, 1>;

def FEMMS : I3DNow<0x0E, RawFrm, (outs), (ins), "femms",
                   [(int_x86_mmx_femms)], IIC_MMX_EMMS>;

// PREFETCHWT1 is supported we want to use it for everything but T0.
def PrefetchWLevel : PatFrag<(ops), (i32 imm), [{
  return N->getSExtValue() == 3 || !Subtarget->hasPREFETCHWT1();
}]>;

// Use PREFETCHWT1 for NTA, T2, T1.
def PrefetchWT1Level : ImmLeaf<i32, [{
  return Imm < 3;
}]>;

let SchedRW = [WriteLoad] in {
let Predicates = [Has3DNow, NoSSEPrefetch] in
def PREFETCH : I3DNow<0x0D, MRM0m, (outs), (ins i8mem:$addr),
                      "prefetch\t$addr",
                      [(prefetch addr:$addr, imm, imm, (i32 1))],
                      IIC_SSE_PREFETCH>;

def PREFETCHW : I<0x0D, MRM1m, (outs), (ins i8mem:$addr), "prefetchw\t$addr",
                  [(prefetch addr:$addr, (i32 1), (i32 PrefetchWLevel), (i32 1))],
                  IIC_SSE_PREFETCH>, TB, Requires<[HasPrefetchW]>;

def PREFETCHWT1 : I<0x0D, MRM2m, (outs), (ins i8mem:$addr), "prefetchwt1\t$addr",
                    [(prefetch addr:$addr, (i32 1), (i32 PrefetchWT1Level), (i32 1))],
                    IIC_SSE_PREFETCH>, TB, Requires<[HasPREFETCHWT1]>;
}

// "3DNowA" instructions
defm PF2IW    : I3DNow_conv_rm_int<0x1C, "pf2iw", I3DNOW_FCVT_F2I_ITINS, "a">;
defm PI2FW    : I3DNow_conv_rm_int<0x0C, "pi2fw", I3DNOW_FCVT_I2F_ITINS, "a">;
defm PFNACC   : I3DNow_binop_rm_int<0x8A, "pfnacc", I3DNOW_FALU_ITINS, 0, "a">;
defm PFPNACC  : I3DNow_binop_rm_int<0x8E, "pfpnacc", I3DNOW_FALU_ITINS, 0, "a">;
defm PSWAPD   : I3DNow_conv_rm_int<0xBB, "pswapd", I3DNOW_PSHUF_ITINS, "a">;