10b57cec5SDimitry Andric//==- MicroMipsInstrFPU.td - microMIPS FPU Instruction Info -*- 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 microMIPS FPU instruction set. 100b57cec5SDimitry Andric// 110b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andricmulticlass ADDS_MMM<string opstr, InstrItinClass Itin, bit IsComm, 140b57cec5SDimitry Andric SDPatternOperator OpNode = null_frag> { 150b57cec5SDimitry Andric def _D32_MM : MMRel, ADDS_FT<opstr, AFGR64Opnd, Itin, IsComm, OpNode>, 160b57cec5SDimitry Andric FGR_32 { 170b57cec5SDimitry Andric string DecoderNamespace = "MicroMips"; 180b57cec5SDimitry Andric } 190b57cec5SDimitry Andric // FIXME: This needs to be part of the instruction mapping tables. 200b57cec5SDimitry Andric def _D64_MM : ADDS_FT<opstr, FGR64Opnd, Itin, IsComm, OpNode>, FGR_64 { 210b57cec5SDimitry Andric string DecoderNamespace = "MicroMipsFP64"; 220b57cec5SDimitry Andric } 230b57cec5SDimitry Andric} 240b57cec5SDimitry Andric 250b57cec5SDimitry Andricdef FADD_S_MM : MMRel, ADDS_FT<"add.s", FGR32Opnd, II_ADD_S, 1, fadd>, 260b57cec5SDimitry Andric ADDS_FM_MM<0, 0x30>, ISA_MICROMIPS; 270b57cec5SDimitry Andricdef FDIV_S_MM : MMRel, ADDS_FT<"div.s", FGR32Opnd, II_DIV_S, 0, fdiv>, 280b57cec5SDimitry Andric ADDS_FM_MM<0, 0xf0>, ISA_MICROMIPS; 290b57cec5SDimitry Andricdef FMUL_S_MM : MMRel, ADDS_FT<"mul.s", FGR32Opnd, II_MUL_S, 1, fmul>, 300b57cec5SDimitry Andric ADDS_FM_MM<0, 0xb0>, ISA_MICROMIPS; 310b57cec5SDimitry Andricdef FSUB_S_MM : MMRel, ADDS_FT<"sub.s", FGR32Opnd, II_SUB_S, 0, fsub>, 320b57cec5SDimitry Andric ADDS_FM_MM<0, 0x70>, ISA_MICROMIPS; 330b57cec5SDimitry Andric 340b57cec5SDimitry Andricdefm FADD : ADDS_MMM<"add.d", II_ADD_D, 1, fadd>, 350b57cec5SDimitry Andric ADDS_FM_MM<1, 0x30>, ISA_MICROMIPS; 360b57cec5SDimitry Andricdefm FDIV : ADDS_MMM<"div.d", II_DIV_D, 0, fdiv>, 370b57cec5SDimitry Andric ADDS_FM_MM<1, 0xf0>, ISA_MICROMIPS; 380b57cec5SDimitry Andricdefm FMUL : ADDS_MMM<"mul.d", II_MUL_D, 1, fmul>, 390b57cec5SDimitry Andric ADDS_FM_MM<1, 0xb0>, ISA_MICROMIPS; 400b57cec5SDimitry Andricdefm FSUB : ADDS_MMM<"sub.d", II_SUB_D, 0, fsub>, 410b57cec5SDimitry Andric ADDS_FM_MM<1, 0x70>, ISA_MICROMIPS; 420b57cec5SDimitry Andric 430b57cec5SDimitry Andriclet DecoderNamespace = "MicroMips" in { 440b57cec5SDimitry Andric def LWXC1_MM : MMRel, LWXC1_FT<"lwxc1", FGR32Opnd, II_LWXC1, load>, 450b57cec5SDimitry Andric LWXC1_FM_MM<0x48>, ISA_MICROMIPS32_NOT_MIPS32R6; 460b57cec5SDimitry Andric def SWXC1_MM : MMRel, SWXC1_FT<"swxc1", FGR32Opnd, II_SWXC1, store>, 470b57cec5SDimitry Andric SWXC1_FM_MM<0x88>, ISA_MICROMIPS32_NOT_MIPS32R6; 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric def LUXC1_MM : MMRel, LWXC1_FT<"luxc1", FGR64Opnd, II_LUXC1>, 500b57cec5SDimitry Andric LWXC1_FM_MM<0x148>, FGR_64, ISA_MICROMIPS32_NOT_MIPS32R6; 510b57cec5SDimitry Andric def SUXC1_MM : MMRel, SWXC1_FT<"suxc1", FGR64Opnd, II_SUXC1>, 520b57cec5SDimitry Andric SWXC1_FM_MM<0x188>, FGR_64, ISA_MICROMIPS32_NOT_MIPS32R6; 530b57cec5SDimitry Andric} 540b57cec5SDimitry Andriclet isCodeGenOnly = 1 in { 550b57cec5SDimitry Andricdef FCMP_S32_MM : MMRel, CEQS_FT<"s", FGR32, II_C_CC_S, MipsFPCmp>, 560b57cec5SDimitry Andric CEQS_FM_MM<0>, ISA_MICROMIPS32_NOT_MIPS32R6 { 570b57cec5SDimitry Andric // FIXME: This is a required to work around the fact that these instructions 580b57cec5SDimitry Andric // only use $fcc0. Ideally, MipsFPCmp nodes could be removed and the 590b57cec5SDimitry Andric // fcc register set is used directly. 600b57cec5SDimitry Andric bits<3> fcc = 0; 610b57cec5SDimitry Andric} 620b57cec5SDimitry Andric 630b57cec5SDimitry Andricdef FCMP_D32_MM : MMRel, CEQS_FT<"d", AFGR64, II_C_CC_D, MipsFPCmp>, 640b57cec5SDimitry Andric CEQS_FM_MM<1>, ISA_MICROMIPS32_NOT_MIPS32R6 { 650b57cec5SDimitry Andric // FIXME: This is a required to work around the fact that these instructions 660b57cec5SDimitry Andric // only use $fcc0. Ideally, MipsFPCmp nodes could be removed and the 670b57cec5SDimitry Andric // fcc register set is used directly. 680b57cec5SDimitry Andric bits<3> fcc = 0; 690b57cec5SDimitry Andric} 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric} 720b57cec5SDimitry Andric 730b57cec5SDimitry Andriclet DecoderNamespace = "MicroMips" in { 740b57cec5SDimitry Andric def BC1F_MM : MMRel, BC1F_FT<"bc1f", brtarget_mm, II_BC1F, MIPS_BRANCH_F>, 750b57cec5SDimitry Andric BC1F_FM_MM<0x1c>, ISA_MICROMIPS32_NOT_MIPS32R6; 760b57cec5SDimitry Andric def BC1T_MM : MMRel, BC1F_FT<"bc1t", brtarget_mm, II_BC1T, MIPS_BRANCH_T>, 770b57cec5SDimitry Andric BC1F_FM_MM<0x1d>, ISA_MICROMIPS32_NOT_MIPS32R6; 780b57cec5SDimitry Andric def CVT_W_S_MM : MMRel, ABSS_FT<"cvt.w.s", FGR32Opnd, FGR32Opnd, II_CVT>, 790b57cec5SDimitry Andric ROUND_W_FM_MM<0, 0x24>, ISA_MICROMIPS; 800b57cec5SDimitry Andric} 810b57cec5SDimitry Andric 820b57cec5SDimitry Andriclet DecoderNamespace = "MicroMips" in { 830b57cec5SDimitry Andric def ROUND_W_S_MM : MMRel, StdMMR6Rel, ABSS_FT<"round.w.s", FGR32Opnd, 840b57cec5SDimitry Andric FGR32Opnd, II_ROUND>, 850b57cec5SDimitry Andric ROUND_W_FM_MM<0, 0xec>, ISA_MICROMIPS; 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric def CEIL_W_MM : MMRel, ABSS_FT<"ceil.w.d", FGR32Opnd, AFGR64Opnd, II_CEIL>, 880b57cec5SDimitry Andric ROUND_W_FM_MM<1, 0x6c>, ISA_MICROMIPS, FGR_32; 890b57cec5SDimitry Andric def FLOOR_W_MM : MMRel, ABSS_FT<"floor.w.d", FGR32Opnd, AFGR64Opnd, II_FLOOR>, 900b57cec5SDimitry Andric ROUND_W_FM_MM<1, 0x2c>, ISA_MICROMIPS, FGR_32; 910b57cec5SDimitry Andric def ROUND_W_MM : MMRel, StdMMR6Rel, ABSS_FT<"round.w.d", FGR32Opnd, 920b57cec5SDimitry Andric AFGR64Opnd, II_ROUND>, 930b57cec5SDimitry Andric ROUND_W_FM_MM<1, 0xec>, ISA_MICROMIPS, FGR_32; 940b57cec5SDimitry Andric def TRUNC_W_MM : MMRel, ABSS_FT<"trunc.w.d", FGR32Opnd, AFGR64Opnd, II_TRUNC>, 950b57cec5SDimitry Andric ROUND_W_FM_MM<1, 0xac>, ISA_MICROMIPS, FGR_32; 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric def CVT_L_S_MM : MMRel, ABSS_FT<"cvt.l.s", FGR64Opnd, FGR32Opnd, II_CVT>, 980b57cec5SDimitry Andric ROUND_W_FM_MM<0, 0x4>, ISA_MICROMIPS, FGR_64; 990b57cec5SDimitry Andric def CVT_L_D64_MM : MMRel, ABSS_FT<"cvt.l.d", FGR64Opnd, FGR64Opnd, II_CVT>, 1000b57cec5SDimitry Andric ROUND_W_FM_MM<1, 0x4>, ISA_MICROMIPS, FGR_64; 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric def CVT_W_D32_MM : MMRel, ABSS_FT<"cvt.w.d", FGR32Opnd, AFGR64Opnd, II_CVT>, 1030b57cec5SDimitry Andric ROUND_W_FM_MM<1, 0x24>, ISA_MICROMIPS, FGR_32; 1040b57cec5SDimitry Andric} 1050b57cec5SDimitry Andriclet DecoderNamespace = "MicroMipsFP64" in { 1060b57cec5SDimitry Andric def CVT_W_D64_MM : ABSS_FT<"cvt.w.d", FGR32Opnd, FGR64Opnd, II_CVT>, 1070b57cec5SDimitry Andric ROUND_W_FM_MM<1, 0x24>, ISA_MICROMIPS, FGR_64; 1080b57cec5SDimitry Andric} 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andricmulticlass ABSS_MMM<string opstr, InstrItinClass Itin, 1110b57cec5SDimitry Andric SDPatternOperator OpNode = null_frag> { 1120b57cec5SDimitry Andric def _D32_MM : MMRel, ABSS_FT<opstr, AFGR64Opnd, AFGR64Opnd, Itin, OpNode>, 1130b57cec5SDimitry Andric ISA_MICROMIPS, FGR_32 { 1140b57cec5SDimitry Andric string DecoderNamespace = "MicroMips"; 1150b57cec5SDimitry Andric } 1160b57cec5SDimitry Andric def _D64_MM : StdMMR6Rel, ABSS_FT<opstr, FGR64Opnd, FGR64Opnd, Itin, OpNode>, 1170b57cec5SDimitry Andric ISA_MICROMIPS, FGR_64 { 1180b57cec5SDimitry Andric string DecoderNamespace = "MicroMipsFP64"; 1190b57cec5SDimitry Andric } 1200b57cec5SDimitry Andric} 1210b57cec5SDimitry Andric 1220b57cec5SDimitry Andricdefm FSQRT : ABSS_MMM<"sqrt.d", II_SQRT_D, fsqrt>, ROUND_W_FM_MM<1, 0x28>; 1230b57cec5SDimitry Andricdefm FABS : ABSS_MMM<"abs.d", II_SQRT_D, fabs>, ABS_FM_MM<1, 0xd>; 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andriclet DecoderNamespace = "MicroMips", AdditionalPredicates = [UseAbs] in { 1260b57cec5SDimitry Andric def FABS_S_MM : MMRel, ABSS_FT<"abs.s", FGR32Opnd, FGR32Opnd, II_ABS, fabs>, 1270b57cec5SDimitry Andric ABS_FM_MM<0, 0xd>, ISA_MICROMIPS; 1280b57cec5SDimitry Andric} 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andricdef FMOV_S_MM : MMRel, ABSS_FT<"mov.s", FGR32Opnd, FGR32Opnd, II_MOV_S>, 1310b57cec5SDimitry Andric ABS_FM_MM<0, 0x1>, ISA_MICROMIPS { 1320b57cec5SDimitry Andric let isMoveReg = 1; 1330b57cec5SDimitry Andric} 1340b57cec5SDimitry Andricdef FNEG_S_MM : MMRel, ABSS_FT<"neg.s", FGR32Opnd, FGR32Opnd, II_NEG, fneg>, 1350b57cec5SDimitry Andric ABS_FM_MM<0, 0x2d>, ISA_MICROMIPS; 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andriclet DecoderNamespace = "MicroMips" in { 1380b57cec5SDimitry Andric def CVT_D32_S_MM : MMRel, ABSS_FT<"cvt.d.s", AFGR64Opnd, FGR32Opnd, II_CVT>, 1390b57cec5SDimitry Andric ABS_FM_MM<0, 0x4d>, ISA_MICROMIPS, FGR_32; 1400b57cec5SDimitry Andric def CVT_D32_W_MM : MMRel, ABSS_FT<"cvt.d.w", AFGR64Opnd, FGR32Opnd, II_CVT>, 1410b57cec5SDimitry Andric ABS_FM_MM<1, 0x4d>, ISA_MICROMIPS, FGR_32; 1420b57cec5SDimitry Andric} 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andriclet DecoderNamespace = "MicroMipsFP64" in { 1450b57cec5SDimitry Andric def CVT_D64_S_MM : ABSS_FT<"cvt.d.s", FGR64Opnd, FGR32Opnd, II_CVT>, 1460b57cec5SDimitry Andric ABS_FM_MM<0, 0x4d>, ISA_MICROMIPS, FGR_64; 1470b57cec5SDimitry Andric def CVT_D64_W_MM : ABSS_FT<"cvt.d.w", FGR64Opnd, FGR32Opnd, II_CVT>, 1480b57cec5SDimitry Andric ABS_FM_MM<1, 0x4d>, ISA_MICROMIPS, FGR_64; 1490b57cec5SDimitry Andric def CVT_S_D64_MM : ABSS_FT<"cvt.s.d", FGR32Opnd, FGR64Opnd, II_CVT>, 1500b57cec5SDimitry Andric ABS_FM_MM<0, 0x6d>, ISA_MICROMIPS, FGR_64; 1510b57cec5SDimitry Andric} 1520b57cec5SDimitry Andric 1530b57cec5SDimitry Andriclet DecoderNamespace = "MicroMips" in { 1540b57cec5SDimitry Andric def CVT_S_D32_MM : MMRel, ABSS_FT<"cvt.s.d", FGR32Opnd, AFGR64Opnd, II_CVT>, 1550b57cec5SDimitry Andric ABS_FM_MM<0, 0x6d>, ISA_MICROMIPS, FGR_32; 1560b57cec5SDimitry Andric def CVT_S_W_MM : MMRel, ABSS_FT<"cvt.s.w", FGR32Opnd, FGR32Opnd, II_CVT>, 1570b57cec5SDimitry Andric ABS_FM_MM<1, 0x6d>, ISA_MICROMIPS; 1580b57cec5SDimitry Andric} 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andricdefm FNEG : ABSS_MMM<"neg.d", II_NEG, fneg>, ABS_FM_MM<1, 0x2d>; 1620b57cec5SDimitry Andricdefm FMOV : ABSS_MMM<"mov.d", II_MOV_D>, ABS_FM_MM<1, 0x1>; 1630b57cec5SDimitry Andric 1640b57cec5SDimitry Andriclet DecoderNamespace = "MicroMips" in { 1650b57cec5SDimitry Andric def MOVZ_I_S_MM : MMRel, CMov_I_F_FT<"movz.s", GPR32Opnd, FGR32Opnd, 1660b57cec5SDimitry Andric II_MOVZ_S>, CMov_I_F_FM_MM<0x78, 0>, 1670b57cec5SDimitry Andric ISA_MICROMIPS32_NOT_MIPS32R6; 1680b57cec5SDimitry Andric def MOVN_I_S_MM : MMRel, CMov_I_F_FT<"movn.s", GPR32Opnd, FGR32Opnd, 1690b57cec5SDimitry Andric II_MOVN_S>, CMov_I_F_FM_MM<0x38, 0>, 1700b57cec5SDimitry Andric ISA_MICROMIPS32_NOT_MIPS32R6; 1710b57cec5SDimitry Andric def MOVZ_I_D32_MM : MMRel, CMov_I_F_FT<"movz.d", GPR32Opnd, AFGR64Opnd, 1720b57cec5SDimitry Andric II_MOVZ_D>, CMov_I_F_FM_MM<0x78, 1>, 1730b57cec5SDimitry Andric ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32; 1740b57cec5SDimitry Andric def MOVN_I_D32_MM : MMRel, CMov_I_F_FT<"movn.d", GPR32Opnd, AFGR64Opnd, 1750b57cec5SDimitry Andric II_MOVN_D>, CMov_I_F_FM_MM<0x38, 1>, 1760b57cec5SDimitry Andric ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32; 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric def MOVT_S_MM : MMRel, CMov_F_F_FT<"movt.s", FGR32Opnd, II_MOVT_S, 1790b57cec5SDimitry Andric MipsCMovFP_T>, CMov_F_F_FM_MM<0x60, 0>, 1800b57cec5SDimitry Andric ISA_MICROMIPS32_NOT_MIPS32R6; 1810b57cec5SDimitry Andric def MOVF_S_MM : MMRel, CMov_F_F_FT<"movf.s", FGR32Opnd, II_MOVF_S, 1820b57cec5SDimitry Andric MipsCMovFP_F>, CMov_F_F_FM_MM<0x20, 0>, 1830b57cec5SDimitry Andric ISA_MICROMIPS32_NOT_MIPS32R6; 1840b57cec5SDimitry Andric def MOVT_D32_MM : MMRel, CMov_F_F_FT<"movt.d", AFGR64Opnd, II_MOVT_D, 1850b57cec5SDimitry Andric MipsCMovFP_T>, CMov_F_F_FM_MM<0x60, 1>, 1860b57cec5SDimitry Andric ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32; 1870b57cec5SDimitry Andric def MOVF_D32_MM : MMRel, CMov_F_F_FT<"movf.d", AFGR64Opnd, II_MOVF_D, 1880b57cec5SDimitry Andric MipsCMovFP_F>, CMov_F_F_FM_MM<0x20, 1>, 1890b57cec5SDimitry Andric ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32; 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric def MFC1_MM : MMRel, MFC1_FT<"mfc1", GPR32Opnd, FGR32Opnd, 1920b57cec5SDimitry Andric II_MFC1, bitconvert>, MFC1_FM_MM<0x80>, 1930b57cec5SDimitry Andric ISA_MICROMIPS; 1940b57cec5SDimitry Andric def MTC1_MM : MMRel, MTC1_FT<"mtc1", FGR32Opnd, GPR32Opnd, 1950b57cec5SDimitry Andric II_MTC1, bitconvert>, MFC1_FM_MM<0xa0>, 1960b57cec5SDimitry Andric ISA_MICROMIPS; 1970b57cec5SDimitry Andric 1980b57cec5SDimitry Andric def MADD_S_MM : MMRel, MADDS_FT<"madd.s", FGR32Opnd, II_MADD_S>, 1990b57cec5SDimitry Andric MADDS_FM_MM<0x1>, ISA_MICROMIPS32_NOT_MIPS32R6, MADD4; 2000b57cec5SDimitry Andric def MSUB_S_MM : MMRel, MADDS_FT<"msub.s", FGR32Opnd, II_MSUB_S>, 2010b57cec5SDimitry Andric MADDS_FM_MM<0x21>, ISA_MICROMIPS32_NOT_MIPS32R6, MADD4; 2020b57cec5SDimitry Andric let AdditionalPredicates = [NoNaNsFPMath, HasMadd4] in { 2030b57cec5SDimitry Andric def NMADD_S_MM : MMRel, NMADDS_FT<"nmadd.s", FGR32Opnd, II_NMADD_S>, 2040b57cec5SDimitry Andric MADDS_FM_MM<0x2>, ISA_MICROMIPS32_NOT_MIPS32R6; 2050b57cec5SDimitry Andric def NMSUB_S_MM : MMRel, NMADDS_FT<"nmsub.s", FGR32Opnd, II_NMSUB_S>, 2060b57cec5SDimitry Andric MADDS_FM_MM<0x22>, ISA_MICROMIPS32_NOT_MIPS32R6; 2070b57cec5SDimitry Andric } 2080b57cec5SDimitry Andric def MADD_D32_MM : MMRel, MADDS_FT<"madd.d", AFGR64Opnd, II_MADD_D>, 2090b57cec5SDimitry Andric MADDS_FM_MM<0x9>, ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32, 2100b57cec5SDimitry Andric MADD4; 2110b57cec5SDimitry Andric def MSUB_D32_MM : MMRel, MADDS_FT<"msub.d", AFGR64Opnd, II_MSUB_D>, 2120b57cec5SDimitry Andric MADDS_FM_MM<0x29>, ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32, 2130b57cec5SDimitry Andric MADD4; 2140b57cec5SDimitry Andric let AdditionalPredicates = [NoNaNsFPMath, HasMadd4] in { 2150b57cec5SDimitry Andric def NMADD_D32_MM : MMRel, NMADDS_FT<"nmadd.d", AFGR64Opnd, II_NMADD_D>, 2160b57cec5SDimitry Andric MADDS_FM_MM<0xa>, ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32; 2170b57cec5SDimitry Andric def NMSUB_D32_MM : MMRel, NMADDS_FT<"nmsub.d", AFGR64Opnd, II_NMSUB_D>, 2180b57cec5SDimitry Andric MADDS_FM_MM<0x2a>, ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32; 2190b57cec5SDimitry Andric } 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric def FLOOR_W_S_MM : MMRel, ABSS_FT<"floor.w.s", FGR32Opnd, FGR32Opnd, 2220b57cec5SDimitry Andric II_FLOOR>, ROUND_W_FM_MM<0, 0x2c>, 2230b57cec5SDimitry Andric ISA_MICROMIPS; 2240b57cec5SDimitry Andric def TRUNC_W_S_MM : MMRel, StdMMR6Rel, ABSS_FT<"trunc.w.s", FGR32Opnd, 2250b57cec5SDimitry Andric FGR32Opnd, II_TRUNC>, 2260b57cec5SDimitry Andric ROUND_W_FM_MM<0, 0xac>, ISA_MICROMIPS; 2270b57cec5SDimitry Andric def CEIL_W_S_MM : MMRel, ABSS_FT<"ceil.w.s", FGR32Opnd, FGR32Opnd, II_CEIL>, 2280b57cec5SDimitry Andric ROUND_W_FM_MM<0, 0x6c>, ISA_MICROMIPS; 2290b57cec5SDimitry Andric 2300b57cec5SDimitry Andric def FSQRT_S_MM : MMRel, ABSS_FT<"sqrt.s", FGR32Opnd, FGR32Opnd, II_SQRT_S, 2310b57cec5SDimitry Andric fsqrt>, ROUND_W_FM_MM<0, 0x28>, ISA_MICROMIPS; 2320b57cec5SDimitry Andric 233480093f4SDimitry Andric def MTHC1_D32_MM : MMRel, 234480093f4SDimitry Andric MTC1_64_FT<"mthc1", AFGR64Opnd, GPR32Opnd, II_MTHC1>, 2350b57cec5SDimitry Andric MFC1_FM_MM<0xe0>, ISA_MICROMIPS, FGR_32; 2360b57cec5SDimitry Andric def MFHC1_D32_MM : MMRel, MFC1_FT<"mfhc1", GPR32Opnd, AFGR64Opnd, II_MFHC1>, 2370b57cec5SDimitry Andric MFC1_FM_MM<0xc0>, ISA_MICROMIPS, FGR_32; 2380b57cec5SDimitry Andric} 2390b57cec5SDimitry Andric 2400b57cec5SDimitry Andriclet DecoderNamespace = "MicroMipsFP64" in { 2410b57cec5SDimitry Andric def MTHC1_D64_MM : MTC1_64_FT<"mthc1", FGR64Opnd, GPR32Opnd, II_MTHC1>, 2420b57cec5SDimitry Andric MFC1_FM_MM<0xe0>, ISA_MICROMIPS, FGR_64; 2430b57cec5SDimitry Andric def MFHC1_D64_MM : MFC1_FT<"mfhc1", GPR32Opnd, FGR64Opnd, II_MFHC1>, 2440b57cec5SDimitry Andric MFC1_FM_MM<0xc0>, ISA_MICROMIPS, FGR_64; 2450b57cec5SDimitry Andric def MTC1_D64_MM : MTC1_FT<"mtc1", FGR64Opnd, GPR32Opnd, II_MTC1>, 2460b57cec5SDimitry Andric MFC1_FM_MM<0xa0>, ISA_MICROMIPS, FGR_64; 2470b57cec5SDimitry Andric} 2480b57cec5SDimitry Andric 2490b57cec5SDimitry Andriclet DecoderNamespace = "MicroMips" in { 2500b57cec5SDimitry Andric def CFC1_MM : MMRel, MFC1_FT<"cfc1", GPR32Opnd, CCROpnd, II_CFC1>, 2510b57cec5SDimitry Andric MFC1_FM_MM<0x40>, ISA_MICROMIPS; 2520b57cec5SDimitry Andric def CTC1_MM : MMRel, MTC1_FT<"ctc1", CCROpnd, GPR32Opnd, II_CTC1>, 2530b57cec5SDimitry Andric MFC1_FM_MM<0x60>, ISA_MICROMIPS; 2540b57cec5SDimitry Andric def RECIP_S_MM : MMRel, ABSS_FT<"recip.s", FGR32Opnd, FGR32Opnd, 2550b57cec5SDimitry Andric II_RECIP_S>, 2560b57cec5SDimitry Andric ROUND_W_FM_MM<0b0, 0b01001000>, ISA_MICROMIPS; 2570b57cec5SDimitry Andric def RECIP_D32_MM : MMRel, ABSS_FT<"recip.d", AFGR64Opnd, AFGR64Opnd, 2580b57cec5SDimitry Andric II_RECIP_D>, 2590b57cec5SDimitry Andric ROUND_W_FM_MM<0b1, 0b01001000>, ISA_MICROMIPS, FGR_32 { 2600b57cec5SDimitry Andric let BaseOpcode = "RECIP_D32"; 2610b57cec5SDimitry Andric } 2620b57cec5SDimitry Andric let DecoderNamespace = "MicroMipsFP64" in 2630b57cec5SDimitry Andric def RECIP_D64_MM : MMRel, ABSS_FT<"recip.d", FGR64Opnd, FGR64Opnd, 2640b57cec5SDimitry Andric II_RECIP_D>, 2650b57cec5SDimitry Andric ROUND_W_FM_MM<0b1, 0b01001000>, ISA_MICROMIPS, FGR_64; 2660b57cec5SDimitry Andric def RSQRT_S_MM : MMRel, ABSS_FT<"rsqrt.s", FGR32Opnd, FGR32Opnd, 2670b57cec5SDimitry Andric II_RECIP_S>, 2680b57cec5SDimitry Andric ROUND_W_FM_MM<0b0, 0b00001000>, ISA_MICROMIPS; 2690b57cec5SDimitry Andric def RSQRT_D32_MM : MMRel, ABSS_FT<"rsqrt.d", AFGR64Opnd, AFGR64Opnd, 2700b57cec5SDimitry Andric II_RECIP_D>, 2710b57cec5SDimitry Andric ROUND_W_FM_MM<0b1, 0b00001000>, ISA_MICROMIPS, FGR_32 { 2720b57cec5SDimitry Andric let BaseOpcode = "RSQRT_D32"; 2730b57cec5SDimitry Andric } 2740b57cec5SDimitry Andric let DecoderNamespace = "MicroMipsFP64" in 2750b57cec5SDimitry Andric def RSQRT_D64_MM : MMRel, ABSS_FT<"rsqrt.d", FGR64Opnd, FGR64Opnd, 2760b57cec5SDimitry Andric II_RECIP_D>, 2770b57cec5SDimitry Andric ROUND_W_FM_MM<0b1, 0b00001000>, ISA_MICROMIPS, FGR_64; 2780b57cec5SDimitry Andric} 2790b57cec5SDimitry Andric 2800b57cec5SDimitry Andriclet DecoderNamespace = "MicroMips", DecoderMethod = "DecodeFMemMMR2" in { 281*81ad6265SDimitry Andric def LDC1_MM_D32 : MMRel, LW_FT<"ldc1", AFGR64Opnd, mem_mm_16, II_LDC1, load>, 2820b57cec5SDimitry Andric LW_FM_MM<0x2f>, ISA_MICROMIPS, FGR_32 { 2830b57cec5SDimitry Andric let BaseOpcode = "LDC132"; 2840b57cec5SDimitry Andric } 285*81ad6265SDimitry Andric def SDC1_MM_D32 : MMRel, SW_FT<"sdc1", AFGR64Opnd, mem_mm_16, II_SDC1, store>, 286*81ad6265SDimitry Andric LW_FM_MM<0x2e>, ISA_MICROMIPS, FGR_32 { 287*81ad6265SDimitry Andric let BaseOpcode = "SDC164"; 288*81ad6265SDimitry Andric } 2890b57cec5SDimitry Andric def LWC1_MM : MMRel, LW_FT<"lwc1", FGR32Opnd, mem_mm_16, II_LWC1, load>, 2900b57cec5SDimitry Andric LW_FM_MM<0x27>, ISA_MICROMIPS; 2910b57cec5SDimitry Andric def SWC1_MM : MMRel, SW_FT<"swc1", FGR32Opnd, mem_mm_16, II_SWC1, store>, 2920b57cec5SDimitry Andric LW_FM_MM<0x26>, ISA_MICROMIPS; 2930b57cec5SDimitry Andric} 2940b57cec5SDimitry Andric 295*81ad6265SDimitry Andriclet DecoderNamespace = "Mips64", DecoderMethod = "DecodeFMemMMR2" in { 296*81ad6265SDimitry Andric def LDC1_MM_D64 : MMRel, LW_FT<"ldc1", FGR64Opnd, mem_mm_16, II_LDC1, load>, 297*81ad6265SDimitry Andric LW_FM_MM<0x2f>, ISA_MICROMIPS, FGR_64 { 298*81ad6265SDimitry Andric let BaseOpcode = "LDC164"; 299*81ad6265SDimitry Andric } 300*81ad6265SDimitry Andric def SDC1_MM_D64 : MMRel, SW_FT<"sdc1", FGR64Opnd, mem_mm_16, II_SDC1, store>, 301*81ad6265SDimitry Andric LW_FM_MM<0x2e>, ISA_MICROMIPS, FGR_64 { 302*81ad6265SDimitry Andric let BaseOpcode = "SDC164"; 303*81ad6265SDimitry Andric } 304*81ad6265SDimitry Andric} 305*81ad6265SDimitry Andric 306*81ad6265SDimitry Andric 3070b57cec5SDimitry Andricmulticlass C_COND_MM<string TypeStr, RegisterOperand RC, bits<2> fmt, 3080b57cec5SDimitry Andric InstrItinClass itin> { 3090b57cec5SDimitry Andric def C_F_#NAME#_MM : MMRel, C_COND_FT<"f", TypeStr, RC, itin>, 3100b57cec5SDimitry Andric C_COND_FM_MM<fmt, 0> { 3110b57cec5SDimitry Andric let BaseOpcode = "c.f."#NAME; 3120b57cec5SDimitry Andric let isCommutable = 1; 3130b57cec5SDimitry Andric } 3140b57cec5SDimitry Andric def C_UN_#NAME#_MM : MMRel, C_COND_FT<"un", TypeStr, RC, itin>, 3150b57cec5SDimitry Andric C_COND_FM_MM<fmt, 1> { 3160b57cec5SDimitry Andric let BaseOpcode = "c.un."#NAME; 3170b57cec5SDimitry Andric let isCommutable = 1; 3180b57cec5SDimitry Andric } 3190b57cec5SDimitry Andric def C_EQ_#NAME#_MM : MMRel, C_COND_FT<"eq", TypeStr, RC, itin>, 3200b57cec5SDimitry Andric C_COND_FM_MM<fmt, 2> { 3210b57cec5SDimitry Andric let BaseOpcode = "c.eq."#NAME; 3220b57cec5SDimitry Andric let isCommutable = 1; 3230b57cec5SDimitry Andric } 3240b57cec5SDimitry Andric def C_UEQ_#NAME#_MM : MMRel, C_COND_FT<"ueq", TypeStr, RC, itin>, 3250b57cec5SDimitry Andric C_COND_FM_MM<fmt, 3> { 3260b57cec5SDimitry Andric let BaseOpcode = "c.ueq."#NAME; 3270b57cec5SDimitry Andric let isCommutable = 1; 3280b57cec5SDimitry Andric } 3290b57cec5SDimitry Andric def C_OLT_#NAME#_MM : MMRel, C_COND_FT<"olt", TypeStr, RC, itin>, 3300b57cec5SDimitry Andric C_COND_FM_MM<fmt, 4> { 3310b57cec5SDimitry Andric let BaseOpcode = "c.olt."#NAME; 3320b57cec5SDimitry Andric } 3330b57cec5SDimitry Andric def C_ULT_#NAME#_MM : MMRel, C_COND_FT<"ult", TypeStr, RC, itin>, 3340b57cec5SDimitry Andric C_COND_FM_MM<fmt, 5> { 3350b57cec5SDimitry Andric let BaseOpcode = "c.ult."#NAME; 3360b57cec5SDimitry Andric } 3370b57cec5SDimitry Andric def C_OLE_#NAME#_MM : MMRel, C_COND_FT<"ole", TypeStr, RC, itin>, 3380b57cec5SDimitry Andric C_COND_FM_MM<fmt, 6> { 3390b57cec5SDimitry Andric let BaseOpcode = "c.ole."#NAME; 3400b57cec5SDimitry Andric } 3410b57cec5SDimitry Andric def C_ULE_#NAME#_MM : MMRel, C_COND_FT<"ule", TypeStr, RC, itin>, 3420b57cec5SDimitry Andric C_COND_FM_MM<fmt, 7> { 3430b57cec5SDimitry Andric let BaseOpcode = "c.ule."#NAME; 3440b57cec5SDimitry Andric } 3450b57cec5SDimitry Andric def C_SF_#NAME#_MM : MMRel, C_COND_FT<"sf", TypeStr, RC, itin>, 3460b57cec5SDimitry Andric C_COND_FM_MM<fmt, 8> { 3470b57cec5SDimitry Andric let BaseOpcode = "c.sf."#NAME; 3480b57cec5SDimitry Andric let isCommutable = 1; 3490b57cec5SDimitry Andric } 3500b57cec5SDimitry Andric def C_NGLE_#NAME#_MM : MMRel, C_COND_FT<"ngle", TypeStr, RC, itin>, 3510b57cec5SDimitry Andric C_COND_FM_MM<fmt, 9> { 3520b57cec5SDimitry Andric let BaseOpcode = "c.ngle."#NAME; 3530b57cec5SDimitry Andric } 3540b57cec5SDimitry Andric def C_SEQ_#NAME#_MM : MMRel, C_COND_FT<"seq", TypeStr, RC, itin>, 3550b57cec5SDimitry Andric C_COND_FM_MM<fmt, 10> { 3560b57cec5SDimitry Andric let BaseOpcode = "c.seq."#NAME; 3570b57cec5SDimitry Andric let isCommutable = 1; 3580b57cec5SDimitry Andric } 3590b57cec5SDimitry Andric def C_NGL_#NAME#_MM : MMRel, C_COND_FT<"ngl", TypeStr, RC, itin>, 3600b57cec5SDimitry Andric C_COND_FM_MM<fmt, 11> { 3610b57cec5SDimitry Andric let BaseOpcode = "c.ngl."#NAME; 3620b57cec5SDimitry Andric } 3630b57cec5SDimitry Andric def C_LT_#NAME#_MM : MMRel, C_COND_FT<"lt", TypeStr, RC, itin>, 3640b57cec5SDimitry Andric C_COND_FM_MM<fmt, 12> { 3650b57cec5SDimitry Andric let BaseOpcode = "c.lt."#NAME; 3660b57cec5SDimitry Andric } 3670b57cec5SDimitry Andric def C_NGE_#NAME#_MM : MMRel, C_COND_FT<"nge", TypeStr, RC, itin>, 3680b57cec5SDimitry Andric C_COND_FM_MM<fmt, 13> { 3690b57cec5SDimitry Andric let BaseOpcode = "c.nge."#NAME; 3700b57cec5SDimitry Andric } 3710b57cec5SDimitry Andric def C_LE_#NAME#_MM : MMRel, C_COND_FT<"le", TypeStr, RC, itin>, 3720b57cec5SDimitry Andric C_COND_FM_MM<fmt, 14> { 3730b57cec5SDimitry Andric let BaseOpcode = "c.le."#NAME; 3740b57cec5SDimitry Andric } 3750b57cec5SDimitry Andric def C_NGT_#NAME#_MM : MMRel, C_COND_FT<"ngt", TypeStr, RC, itin>, 3760b57cec5SDimitry Andric C_COND_FM_MM<fmt, 15> { 3770b57cec5SDimitry Andric let BaseOpcode = "c.ngt."#NAME; 3780b57cec5SDimitry Andric } 3790b57cec5SDimitry Andric} 3800b57cec5SDimitry Andriclet DecoderNamespace = "MicroMips" in { 3810b57cec5SDimitry Andric defm S : C_COND_MM<"s", FGR32Opnd, 0b00, II_C_CC_S>, 3820b57cec5SDimitry Andric ISA_MICROMIPS32_NOT_MIPS32R6; 3830b57cec5SDimitry Andric defm D32 : C_COND_MM<"d", AFGR64Opnd, 0b01, II_C_CC_D>, 3840b57cec5SDimitry Andric ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32; 3850b57cec5SDimitry Andric} 3860b57cec5SDimitry Andric 3870b57cec5SDimitry Andriclet DecoderNamespace = "Mips64" in 3880b57cec5SDimitry Andric defm D64 : C_COND_MM<"d", FGR64Opnd, 0b01, II_C_CC_D>, 3890b57cec5SDimitry Andric ISA_MICROMIPS32_NOT_MIPS32R6, FGR_64; 3900b57cec5SDimitry Andric 3910b57cec5SDimitry Andricdefm S_MM : C_COND_ALIASES<"s", FGR32Opnd>, HARDFLOAT, 3920b57cec5SDimitry Andric ISA_MICROMIPS32_NOT_MIPS32R6; 3930b57cec5SDimitry Andricdefm D32_MM : C_COND_ALIASES<"d", AFGR64Opnd>, HARDFLOAT, 3940b57cec5SDimitry Andric ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32; 3950b57cec5SDimitry Andricdefm D64_MM : C_COND_ALIASES<"d", FGR64Opnd>, HARDFLOAT, 3960b57cec5SDimitry Andric ISA_MICROMIPS32_NOT_MIPS32R6, FGR_64; 3970b57cec5SDimitry Andric 3980b57cec5SDimitry Andricdefm : BC1_ALIASES<BC1T_MM, "bc1t", BC1F_MM, "bc1f">, 3990b57cec5SDimitry Andric ISA_MICROMIPS32_NOT_MIPS32R6, HARDFLOAT; 4000b57cec5SDimitry Andric 4010b57cec5SDimitry Andric 4020b57cec5SDimitry Andric// To generate NMADD and NMSUB instructions when fneg node is present 4030b57cec5SDimitry Andriclet AdditionalPredicates = [NoNaNsFPMath, HasMadd4, 4040b57cec5SDimitry Andric InMicroMips, NotMips32r6] in { 4050b57cec5SDimitry Andric defm : NMADD_NMSUB<NMADD_S_MM, NMSUB_S_MM, FGR32Opnd>, 4060b57cec5SDimitry Andric ISA_MICROMIPS32_NOT_MIPS32R6; 4070b57cec5SDimitry Andric defm : NMADD_NMSUB<NMADD_D32_MM, NMSUB_D32_MM, AFGR64Opnd>, 4080b57cec5SDimitry Andric ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32; 4090b57cec5SDimitry Andric} 4100b57cec5SDimitry Andric 4110b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 4120b57cec5SDimitry Andric// Floating Point Patterns 4130b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric// Patterns for loads/stores with a reg+imm operand. 4160b57cec5SDimitry Andriclet AddedComplexity = 40 in { 417*81ad6265SDimitry Andric def : LoadRegImmPat<LDC1_MM_D32, f64, load>, ISA_MICROMIPS, FGR_32; 418*81ad6265SDimitry Andric def : StoreRegImmPat<SDC1_MM_D32, f64>, ISA_MICROMIPS, FGR_32; 419*81ad6265SDimitry Andric def : LoadRegImmPat<LDC1_MM_D64, f64, load>, ISA_MICROMIPS, FGR_64; 420*81ad6265SDimitry Andric def : StoreRegImmPat<SDC1_MM_D64, f64>, ISA_MICROMIPS, FGR_64; 4210b57cec5SDimitry Andric def : LoadRegImmPat<LWC1_MM, f32, load>, ISA_MICROMIPS; 4220b57cec5SDimitry Andric def : StoreRegImmPat<SWC1_MM, f32>, ISA_MICROMIPS; 4230b57cec5SDimitry Andric} 4240b57cec5SDimitry Andric 4250b57cec5SDimitry Andricdef : MipsPat<(MipsMTC1_D64 GPR32Opnd:$src), 4260b57cec5SDimitry Andric (MTC1_D64_MM GPR32Opnd:$src)>, ISA_MICROMIPS, FGR_64; 4270b57cec5SDimitry Andric 4280b57cec5SDimitry Andricdef : MipsPat<(f32 fpimm0), (MTC1_MM ZERO)>, ISA_MICROMIPS32_NOT_MIPS32R6; 4290b57cec5SDimitry Andricdef : MipsPat<(f32 fpimm0neg), (FNEG_S_MM (MTC1_MM ZERO))>, 4300b57cec5SDimitry Andric ISA_MICROMIPS32_NOT_MIPS32R6; 4310b57cec5SDimitry Andric 4320b57cec5SDimitry Andricdef : MipsPat<(f32 (fpround FGR64Opnd:$src)), 4330b57cec5SDimitry Andric (CVT_S_D64_MM FGR64Opnd:$src)>, ISA_MICROMIPS, FGR_64; 4340b57cec5SDimitry Andricdef : MipsPat<(f64 (fpextend FGR32Opnd:$src)), 4350b57cec5SDimitry Andric (CVT_D64_S_MM FGR32Opnd:$src)>, ISA_MICROMIPS, FGR_64; 4360b57cec5SDimitry Andricdef : MipsPat<(f32 (fpround AFGR64Opnd:$src)), 4370b57cec5SDimitry Andric (CVT_S_D32_MM AFGR64Opnd:$src)>, ISA_MICROMIPS, FGR_32; 4380b57cec5SDimitry Andricdef : MipsPat<(f64 (fpextend FGR32Opnd:$src)), 4390b57cec5SDimitry Andric (CVT_D32_S_MM FGR32Opnd:$src)>, ISA_MICROMIPS, FGR_32; 4400b57cec5SDimitry Andricdef : MipsPat<(MipsTruncIntFP AFGR64Opnd:$src), 4410b57cec5SDimitry Andric (TRUNC_W_MM AFGR64Opnd:$src)>, ISA_MICROMIPS32_NOT_MIPS32R6, 4420b57cec5SDimitry Andric FGR_32; 4430b57cec5SDimitry Andricdef : MipsPat<(MipsTruncIntFP FGR64Opnd:$src), 4440b57cec5SDimitry Andric (CVT_W_D64_MM FGR64Opnd:$src)>, ISA_MICROMIPS32_NOT_MIPS32R6, 4450b57cec5SDimitry Andric FGR_64; 4460b57cec5SDimitry Andricdef : MipsPat<(MipsTruncIntFP FGR32Opnd:$src), 4470b57cec5SDimitry Andric (TRUNC_W_S_MM FGR32Opnd:$src)>, ISA_MICROMIPS32_NOT_MIPS32R6; 4480b57cec5SDimitry Andric 4490b57cec5SDimitry Andric// Selects 4500b57cec5SDimitry Andricdefm : MovzPats0<GPR32, FGR32, MOVZ_I_S_MM, SLT_MM, SLTu_MM, SLTi_MM, SLTiu_MM>, 4510b57cec5SDimitry Andric ISA_MICROMIPS32_NOT_MIPS32R6; 4520b57cec5SDimitry Andricdefm : MovzPats1<GPR32, FGR32, MOVZ_I_S_MM, XOR_MM>, 4530b57cec5SDimitry Andric ISA_MICROMIPS32_NOT_MIPS32R6; 4540b57cec5SDimitry Andric 4550b57cec5SDimitry Andricdefm : MovnPats<GPR32, FGR32, MOVN_I_S_MM, XOR_MM>, 4560b57cec5SDimitry Andric ISA_MICROMIPS32_NOT_MIPS32R6; 4570b57cec5SDimitry Andric 4580b57cec5SDimitry Andricdefm : MovzPats0<GPR32, AFGR64, MOVZ_I_D32_MM, SLT_MM, SLTu_MM, SLTi_MM, 4590b57cec5SDimitry Andric SLTiu_MM>, 4600b57cec5SDimitry Andric ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32; 4610b57cec5SDimitry Andricdefm : MovzPats1<GPR32, AFGR64, MOVZ_I_D32_MM, XOR_MM>, 4620b57cec5SDimitry Andric ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32; 4630b57cec5SDimitry Andricdefm : MovnPats<GPR32, AFGR64, MOVN_I_D32_MM, XOR_MM>, 4640b57cec5SDimitry Andric ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32; 465