10b57cec5SDimitry Andric//===-- X86Instr3DNow.td - The 3DNow! Instruction Set ------*- tablegen -*-===// 20b57cec5SDimitry Andric// 30b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric// 70b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric// 90b57cec5SDimitry Andric// This file describes the 3DNow! instruction set, which extends MMX to support 100b57cec5SDimitry Andric// floating point and also adds a few more random instructions for good measure. 110b57cec5SDimitry Andric// 120b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andricclass I3DNow<bits<8> o, Format F, dag outs, dag ins, string asm, list<dag> pat> 150b57cec5SDimitry Andric : I<o, F, outs, ins, asm, pat>, Requires<[Has3DNow]> { 160b57cec5SDimitry Andric} 170b57cec5SDimitry Andric 180b57cec5SDimitry Andricclass I3DNow_binop<bits<8> o, Format F, dag ins, string Mnemonic, list<dag> pat> 190b57cec5SDimitry Andric : I3DNow<o, F, (outs VR64:$dst), ins, 200b57cec5SDimitry Andric !strconcat(Mnemonic, "\t{$src2, $dst|$dst, $src2}"), pat>, ThreeDNow { 210b57cec5SDimitry Andric let Constraints = "$src1 = $dst"; 220b57cec5SDimitry Andric} 230b57cec5SDimitry Andric 240b57cec5SDimitry Andricclass I3DNow_conv<bits<8> o, Format F, dag ins, string Mnemonic, list<dag> pat> 250b57cec5SDimitry Andric : I3DNow<o, F, (outs VR64:$dst), ins, 260b57cec5SDimitry Andric !strconcat(Mnemonic, "\t{$src, $dst|$dst, $src}"), pat>, ThreeDNow; 270b57cec5SDimitry Andric 280b57cec5SDimitry Andricmulticlass I3DNow_binop_rm_int<bits<8> opc, string Mn, 290b57cec5SDimitry Andric X86FoldableSchedWrite sched, bit Commutable = 0, 300b57cec5SDimitry Andric string Ver = ""> { 310b57cec5SDimitry Andric let isCommutable = Commutable in 320b57cec5SDimitry Andric def rr : I3DNow_binop<opc, MRMSrcReg, (ins VR64:$src1, VR64:$src2), Mn, 330b57cec5SDimitry Andric [(set VR64:$dst, (!cast<Intrinsic>( 340b57cec5SDimitry Andric !strconcat("int_x86_3dnow", Ver, "_", Mn)) VR64:$src1, VR64:$src2))]>, 350b57cec5SDimitry Andric Sched<[sched]>; 360b57cec5SDimitry Andric def rm : I3DNow_binop<opc, MRMSrcMem, (ins VR64:$src1, i64mem:$src2), Mn, 370b57cec5SDimitry Andric [(set VR64:$dst, (!cast<Intrinsic>( 380b57cec5SDimitry Andric !strconcat("int_x86_3dnow", Ver, "_", Mn)) VR64:$src1, 390b57cec5SDimitry Andric (bitconvert (load_mmx addr:$src2))))]>, 400b57cec5SDimitry Andric Sched<[sched.Folded, sched.ReadAfterFold]>; 410b57cec5SDimitry Andric} 420b57cec5SDimitry Andric 430b57cec5SDimitry Andricmulticlass I3DNow_conv_rm_int<bits<8> opc, string Mn, 440b57cec5SDimitry Andric X86FoldableSchedWrite sched, string Ver = ""> { 450b57cec5SDimitry Andric def rr : I3DNow_conv<opc, MRMSrcReg, (ins VR64:$src), Mn, 460b57cec5SDimitry Andric [(set VR64:$dst, (!cast<Intrinsic>( 470b57cec5SDimitry Andric !strconcat("int_x86_3dnow", Ver, "_", Mn)) VR64:$src))]>, 480b57cec5SDimitry Andric Sched<[sched]>; 490b57cec5SDimitry Andric def rm : I3DNow_conv<opc, MRMSrcMem, (ins i64mem:$src), Mn, 500b57cec5SDimitry Andric [(set VR64:$dst, (!cast<Intrinsic>( 510b57cec5SDimitry Andric !strconcat("int_x86_3dnow", Ver, "_", Mn)) 520b57cec5SDimitry Andric (bitconvert (load_mmx addr:$src))))]>, 530b57cec5SDimitry Andric Sched<[sched.Folded, sched.ReadAfterFold]>; 540b57cec5SDimitry Andric} 550b57cec5SDimitry Andric 560b57cec5SDimitry Andricdefm PAVGUSB : I3DNow_binop_rm_int<0xBF, "pavgusb", SchedWriteVecALU.MMX, 1>; 570b57cec5SDimitry Andricdefm PF2ID : I3DNow_conv_rm_int<0x1D, "pf2id", WriteCvtPS2I>; 580b57cec5SDimitry Andricdefm PFACC : I3DNow_binop_rm_int<0xAE, "pfacc", WriteFAdd>; 590b57cec5SDimitry Andricdefm PFADD : I3DNow_binop_rm_int<0x9E, "pfadd", WriteFAdd, 1>; 600b57cec5SDimitry Andricdefm PFCMPEQ : I3DNow_binop_rm_int<0xB0, "pfcmpeq", WriteFAdd, 1>; 610b57cec5SDimitry Andricdefm PFCMPGE : I3DNow_binop_rm_int<0x90, "pfcmpge", WriteFAdd>; 620b57cec5SDimitry Andricdefm PFCMPGT : I3DNow_binop_rm_int<0xA0, "pfcmpgt", WriteFAdd>; 630b57cec5SDimitry Andricdefm PFMAX : I3DNow_binop_rm_int<0xA4, "pfmax", WriteFAdd>; 640b57cec5SDimitry Andricdefm PFMIN : I3DNow_binop_rm_int<0x94, "pfmin", WriteFAdd>; 650b57cec5SDimitry Andricdefm PFMUL : I3DNow_binop_rm_int<0xB4, "pfmul", WriteFAdd, 1>; 660b57cec5SDimitry Andricdefm PFRCP : I3DNow_conv_rm_int<0x96, "pfrcp", WriteFAdd>; 670b57cec5SDimitry Andricdefm PFRCPIT1 : I3DNow_binop_rm_int<0xA6, "pfrcpit1", WriteFAdd>; 680b57cec5SDimitry Andricdefm PFRCPIT2 : I3DNow_binop_rm_int<0xB6, "pfrcpit2", WriteFAdd>; 690b57cec5SDimitry Andricdefm PFRSQIT1 : I3DNow_binop_rm_int<0xA7, "pfrsqit1", WriteFAdd>; 700b57cec5SDimitry Andricdefm PFRSQRT : I3DNow_conv_rm_int<0x97, "pfrsqrt", WriteFAdd>; 710b57cec5SDimitry Andricdefm PFSUB : I3DNow_binop_rm_int<0x9A, "pfsub", WriteFAdd, 1>; 720b57cec5SDimitry Andricdefm PFSUBR : I3DNow_binop_rm_int<0xAA, "pfsubr", WriteFAdd, 1>; 730b57cec5SDimitry Andricdefm PI2FD : I3DNow_conv_rm_int<0x0D, "pi2fd", WriteCvtI2PS>; 740b57cec5SDimitry Andricdefm PMULHRW : I3DNow_binop_rm_int<0xB7, "pmulhrw", SchedWriteVecIMul.MMX, 1>; 750b57cec5SDimitry Andric 760b57cec5SDimitry Andriclet SchedRW = [WriteEMMS], 770b57cec5SDimitry Andric Defs = [MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7, 780b57cec5SDimitry Andric ST0, ST1, ST2, ST3, ST4, ST5, ST6, ST7] in 790b57cec5SDimitry Andricdef FEMMS : I3DNow<0x0E, RawFrm, (outs), (ins), "femms", 800b57cec5SDimitry Andric [(int_x86_mmx_femms)]>, TB; 810b57cec5SDimitry Andric 820b57cec5SDimitry Andriclet SchedRW = [WriteLoad] in { 830b57cec5SDimitry Andriclet Predicates = [Has3DNow, NoSSEPrefetch] in 840b57cec5SDimitry Andricdef PREFETCH : I3DNow<0x0D, MRM0m, (outs), (ins i8mem:$addr), 850b57cec5SDimitry Andric "prefetch\t$addr", 865f757f3fSDimitry Andric [(prefetch addr:$addr, timm, timm, (i32 1))]>, TB; 870b57cec5SDimitry Andric 880b57cec5SDimitry Andricdef PREFETCHW : I<0x0D, MRM1m, (outs), (ins i8mem:$addr), "prefetchw\t$addr", 890b57cec5SDimitry Andric [(prefetch addr:$addr, (i32 1), (i32 PrefetchWLevel), (i32 1))]>, 900b57cec5SDimitry Andric TB, Requires<[HasPrefetchW]>; 910b57cec5SDimitry Andric 920b57cec5SDimitry Andricdef PREFETCHWT1 : I<0x0D, MRM2m, (outs), (ins i8mem:$addr), "prefetchwt1\t$addr", 930b57cec5SDimitry Andric [(prefetch addr:$addr, (i32 1), (i32 PrefetchWT1Level), (i32 1))]>, 940b57cec5SDimitry Andric TB, Requires<[HasPREFETCHWT1]>; 950b57cec5SDimitry Andric} 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric// "3DNowA" instructions 980b57cec5SDimitry Andricdefm PF2IW : I3DNow_conv_rm_int<0x1C, "pf2iw", WriteCvtPS2I, "a">; 990b57cec5SDimitry Andricdefm PI2FW : I3DNow_conv_rm_int<0x0C, "pi2fw", WriteCvtI2PS, "a">; 1000b57cec5SDimitry Andricdefm PFNACC : I3DNow_binop_rm_int<0x8A, "pfnacc", WriteFAdd, 0, "a">; 1010b57cec5SDimitry Andricdefm PFPNACC : I3DNow_binop_rm_int<0x8E, "pfpnacc", WriteFAdd, 0, "a">; 1020b57cec5SDimitry Andricdefm PSWAPD : I3DNow_conv_rm_int<0xBB, "pswapd", SchedWriteShuffle.MMX, "a">; 103