10b57cec5SDimitry Andric//==- SystemZInstrHFP.td - Floating-point SystemZ instructions -*- tblgen-*-==// 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// The instructions in this file implement SystemZ hexadecimal floating-point 100b57cec5SDimitry Andric// arithmetic. Since this format is not mapped to any source-language data 110b57cec5SDimitry Andric// type, these instructions are not used for code generation, but are provided 120b57cec5SDimitry Andric// for use with the assembler and disassembler only. 130b57cec5SDimitry Andric// 140b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 170b57cec5SDimitry Andric// Move instructions 180b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric// Load and test. 210b57cec5SDimitry Andriclet Defs = [CC] in { 220b57cec5SDimitry Andric def LTER : UnaryRR <"lter", 0x32, null_frag, FP32, FP32>; 230b57cec5SDimitry Andric def LTDR : UnaryRR <"ltdr", 0x22, null_frag, FP64, FP64>; 240b57cec5SDimitry Andric def LTXR : UnaryRRE<"ltxr", 0xB362, null_frag, FP128, FP128>; 250b57cec5SDimitry Andric} 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 280b57cec5SDimitry Andric// Conversion instructions 290b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric// Convert floating-point values to narrower representations. 320b57cec5SDimitry Andricdef LEDR : UnaryRR <"ledr", 0x35, null_frag, FP32, FP64>; 330b57cec5SDimitry Andricdef LEXR : UnaryRRE<"lexr", 0xB366, null_frag, FP32, FP128>; 340b57cec5SDimitry Andricdef LDXR : UnaryRR <"ldxr", 0x25, null_frag, FP64, FP128>; 350b57cec5SDimitry Andriclet isAsmParserOnly = 1 in { 360b57cec5SDimitry Andric def LRER : UnaryRR <"lrer", 0x35, null_frag, FP32, FP64>; 370b57cec5SDimitry Andric def LRDR : UnaryRR <"lrdr", 0x25, null_frag, FP64, FP128>; 380b57cec5SDimitry Andric} 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric// Extend floating-point values to wider representations. 410b57cec5SDimitry Andricdef LDER : UnaryRRE<"lder", 0xB324, null_frag, FP64, FP32>; 420b57cec5SDimitry Andricdef LXER : UnaryRRE<"lxer", 0xB326, null_frag, FP128, FP32>; 430b57cec5SDimitry Andricdef LXDR : UnaryRRE<"lxdr", 0xB325, null_frag, FP128, FP64>; 440b57cec5SDimitry Andric 450b57cec5SDimitry Andricdef LDE : UnaryRXE<"lde", 0xED24, null_frag, FP64, 4>; 460b57cec5SDimitry Andricdef LXE : UnaryRXE<"lxe", 0xED26, null_frag, FP128, 4>; 470b57cec5SDimitry Andricdef LXD : UnaryRXE<"lxd", 0xED25, null_frag, FP128, 8>; 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric// Convert a signed integer register value to a floating-point one. 500b57cec5SDimitry Andricdef CEFR : UnaryRRE<"cefr", 0xB3B4, null_frag, FP32, GR32>; 510b57cec5SDimitry Andricdef CDFR : UnaryRRE<"cdfr", 0xB3B5, null_frag, FP64, GR32>; 520b57cec5SDimitry Andricdef CXFR : UnaryRRE<"cxfr", 0xB3B6, null_frag, FP128, GR32>; 530b57cec5SDimitry Andric 540b57cec5SDimitry Andricdef CEGR : UnaryRRE<"cegr", 0xB3C4, null_frag, FP32, GR64>; 550b57cec5SDimitry Andricdef CDGR : UnaryRRE<"cdgr", 0xB3C5, null_frag, FP64, GR64>; 560b57cec5SDimitry Andricdef CXGR : UnaryRRE<"cxgr", 0xB3C6, null_frag, FP128, GR64>; 570b57cec5SDimitry Andric 580b57cec5SDimitry Andric// Convert a floating-point register value to a signed integer value, 590b57cec5SDimitry Andric// with the second operand (modifier M3) specifying the rounding mode. 600b57cec5SDimitry Andriclet Defs = [CC] in { 610b57cec5SDimitry Andric def CFER : BinaryRRFe<"cfer", 0xB3B8, GR32, FP32>; 620b57cec5SDimitry Andric def CFDR : BinaryRRFe<"cfdr", 0xB3B9, GR32, FP64>; 630b57cec5SDimitry Andric def CFXR : BinaryRRFe<"cfxr", 0xB3BA, GR32, FP128>; 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric def CGER : BinaryRRFe<"cger", 0xB3C8, GR64, FP32>; 660b57cec5SDimitry Andric def CGDR : BinaryRRFe<"cgdr", 0xB3C9, GR64, FP64>; 670b57cec5SDimitry Andric def CGXR : BinaryRRFe<"cgxr", 0xB3CA, GR64, FP128>; 680b57cec5SDimitry Andric} 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric// Convert BFP to HFP. 710b57cec5SDimitry Andriclet Defs = [CC] in { 720b57cec5SDimitry Andric def THDER : UnaryRRE<"thder", 0xB358, null_frag, FP64, FP32>; 730b57cec5SDimitry Andric def THDR : UnaryRRE<"thdr", 0xB359, null_frag, FP64, FP64>; 740b57cec5SDimitry Andric} 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric// Convert HFP to BFP. 770b57cec5SDimitry Andriclet Defs = [CC] in { 780b57cec5SDimitry Andric def TBEDR : BinaryRRFe<"tbedr", 0xB350, FP32, FP64>; 790b57cec5SDimitry Andric def TBDR : BinaryRRFe<"tbdr", 0xB351, FP64, FP64>; 800b57cec5SDimitry Andric} 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 840b57cec5SDimitry Andric// Unary arithmetic 850b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric// Negation (Load Complement). 880b57cec5SDimitry Andriclet Defs = [CC] in { 890b57cec5SDimitry Andric def LCER : UnaryRR <"lcer", 0x33, null_frag, FP32, FP32>; 900b57cec5SDimitry Andric def LCDR : UnaryRR <"lcdr", 0x23, null_frag, FP64, FP64>; 910b57cec5SDimitry Andric def LCXR : UnaryRRE<"lcxr", 0xB363, null_frag, FP128, FP128>; 920b57cec5SDimitry Andric} 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric// Absolute value (Load Positive). 950b57cec5SDimitry Andriclet Defs = [CC] in { 960b57cec5SDimitry Andric def LPER : UnaryRR <"lper", 0x30, null_frag, FP32, FP32>; 970b57cec5SDimitry Andric def LPDR : UnaryRR <"lpdr", 0x20, null_frag, FP64, FP64>; 980b57cec5SDimitry Andric def LPXR : UnaryRRE<"lpxr", 0xB360, null_frag, FP128, FP128>; 990b57cec5SDimitry Andric} 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric// Negative absolute value (Load Negative). 1020b57cec5SDimitry Andriclet Defs = [CC] in { 1030b57cec5SDimitry Andric def LNER : UnaryRR <"lner", 0x31, null_frag, FP32, FP32>; 1040b57cec5SDimitry Andric def LNDR : UnaryRR <"lndr", 0x21, null_frag, FP64, FP64>; 1050b57cec5SDimitry Andric def LNXR : UnaryRRE<"lnxr", 0xB361, null_frag, FP128, FP128>; 1060b57cec5SDimitry Andric} 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric// Halve. 1090b57cec5SDimitry Andricdef HER : UnaryRR <"her", 0x34, null_frag, FP32, FP32>; 1100b57cec5SDimitry Andricdef HDR : UnaryRR <"hdr", 0x24, null_frag, FP64, FP64>; 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric// Square root. 1130b57cec5SDimitry Andricdef SQER : UnaryRRE<"sqer", 0xB245, null_frag, FP32, FP32>; 1140b57cec5SDimitry Andricdef SQDR : UnaryRRE<"sqdr", 0xB244, null_frag, FP64, FP64>; 1150b57cec5SDimitry Andricdef SQXR : UnaryRRE<"sqxr", 0xB336, null_frag, FP128, FP128>; 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andricdef SQE : UnaryRXE<"sqe", 0xED34, null_frag, FP32, 4>; 1180b57cec5SDimitry Andricdef SQD : UnaryRXE<"sqd", 0xED35, null_frag, FP64, 8>; 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric// Round to an integer (rounding towards zero). 1210b57cec5SDimitry Andricdef FIER : UnaryRRE<"fier", 0xB377, null_frag, FP32, FP32>; 1220b57cec5SDimitry Andricdef FIDR : UnaryRRE<"fidr", 0xB37F, null_frag, FP64, FP64>; 1230b57cec5SDimitry Andricdef FIXR : UnaryRRE<"fixr", 0xB367, null_frag, FP128, FP128>; 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 1270b57cec5SDimitry Andric// Binary arithmetic 1280b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric// Addition. 1310b57cec5SDimitry Andriclet Defs = [CC] in { 1320b57cec5SDimitry Andric let isCommutable = 1 in { 1330b57cec5SDimitry Andric def AER : BinaryRR<"aer", 0x3A, null_frag, FP32, FP32>; 1340b57cec5SDimitry Andric def ADR : BinaryRR<"adr", 0x2A, null_frag, FP64, FP64>; 1350b57cec5SDimitry Andric def AXR : BinaryRR<"axr", 0x36, null_frag, FP128, FP128>; 1360b57cec5SDimitry Andric } 137*0fca6ea1SDimitry Andric def AE : BinaryRX<"ae", 0x7A, null_frag, FP32, z_load, 4>; 138*0fca6ea1SDimitry Andric def AD : BinaryRX<"ad", 0x6A, null_frag, FP64, z_load, 8>; 1390b57cec5SDimitry Andric} 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric// Addition (unnormalized). 1420b57cec5SDimitry Andriclet Defs = [CC] in { 1430b57cec5SDimitry Andric let isCommutable = 1 in { 1440b57cec5SDimitry Andric def AUR : BinaryRR<"aur", 0x3E, null_frag, FP32, FP32>; 1450b57cec5SDimitry Andric def AWR : BinaryRR<"awr", 0x2E, null_frag, FP64, FP64>; 1460b57cec5SDimitry Andric } 147*0fca6ea1SDimitry Andric def AU : BinaryRX<"au", 0x7E, null_frag, FP32, z_load, 4>; 148*0fca6ea1SDimitry Andric def AW : BinaryRX<"aw", 0x6E, null_frag, FP64, z_load, 8>; 1490b57cec5SDimitry Andric} 1500b57cec5SDimitry Andric 1510b57cec5SDimitry Andric// Subtraction. 1520b57cec5SDimitry Andriclet Defs = [CC] in { 1530b57cec5SDimitry Andric def SER : BinaryRR<"ser", 0x3B, null_frag, FP32, FP32>; 1540b57cec5SDimitry Andric def SDR : BinaryRR<"sdr", 0x2B, null_frag, FP64, FP64>; 1550b57cec5SDimitry Andric def SXR : BinaryRR<"sxr", 0x37, null_frag, FP128, FP128>; 1560b57cec5SDimitry Andric 157*0fca6ea1SDimitry Andric def SE : BinaryRX<"se", 0x7B, null_frag, FP32, z_load, 4>; 158*0fca6ea1SDimitry Andric def SD : BinaryRX<"sd", 0x6B, null_frag, FP64, z_load, 8>; 1590b57cec5SDimitry Andric} 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric// Subtraction (unnormalized). 1620b57cec5SDimitry Andriclet Defs = [CC] in { 1630b57cec5SDimitry Andric def SUR : BinaryRR<"sur", 0x3F, null_frag, FP32, FP32>; 1640b57cec5SDimitry Andric def SWR : BinaryRR<"swr", 0x2F, null_frag, FP64, FP64>; 1650b57cec5SDimitry Andric 166*0fca6ea1SDimitry Andric def SU : BinaryRX<"su", 0x7F, null_frag, FP32, z_load, 4>; 167*0fca6ea1SDimitry Andric def SW : BinaryRX<"sw", 0x6F, null_frag, FP64, z_load, 8>; 1680b57cec5SDimitry Andric} 1690b57cec5SDimitry Andric 1700b57cec5SDimitry Andric// Multiplication. 1710b57cec5SDimitry Andriclet isCommutable = 1 in { 1720b57cec5SDimitry Andric def MEER : BinaryRRE<"meer", 0xB337, null_frag, FP32, FP32>; 1730b57cec5SDimitry Andric def MDR : BinaryRR <"mdr", 0x2C, null_frag, FP64, FP64>; 1740b57cec5SDimitry Andric def MXR : BinaryRR <"mxr", 0x26, null_frag, FP128, FP128>; 1750b57cec5SDimitry Andric} 176*0fca6ea1SDimitry Andricdef MEE : BinaryRXE<"mee", 0xED37, null_frag, FP32, z_load, 4>; 177*0fca6ea1SDimitry Andricdef MD : BinaryRX <"md", 0x6C, null_frag, FP64, z_load, 8>; 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric// Extending multiplication (f32 x f32 -> f64). 1800b57cec5SDimitry Andricdef MDER : BinaryRR<"mder", 0x3C, null_frag, FP64, FP32>; 181*0fca6ea1SDimitry Andricdef MDE : BinaryRX<"mde", 0x7C, null_frag, FP64, z_load, 4>; 1820b57cec5SDimitry Andriclet isAsmParserOnly = 1 in { 1830b57cec5SDimitry Andric def MER : BinaryRR<"mer", 0x3C, null_frag, FP64, FP32>; 184*0fca6ea1SDimitry Andric def ME : BinaryRX<"me", 0x7C, null_frag, FP64, z_load, 4>; 1850b57cec5SDimitry Andric} 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric// Extending multiplication (f64 x f64 -> f128). 1880b57cec5SDimitry Andricdef MXDR : BinaryRR<"mxdr", 0x27, null_frag, FP128, FP64>; 189*0fca6ea1SDimitry Andricdef MXD : BinaryRX<"mxd", 0x67, null_frag, FP128, z_load, 8>; 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric// Fused multiply-add. 1920b57cec5SDimitry Andricdef MAER : TernaryRRD<"maer", 0xB32E, null_frag, FP32, FP32>; 1930b57cec5SDimitry Andricdef MADR : TernaryRRD<"madr", 0xB33E, null_frag, FP64, FP64>; 194*0fca6ea1SDimitry Andricdef MAE : TernaryRXF<"mae", 0xED2E, null_frag, FP32, FP32, z_load, 4>; 195*0fca6ea1SDimitry Andricdef MAD : TernaryRXF<"mad", 0xED3E, null_frag, FP64, FP64, z_load, 8>; 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric// Fused multiply-subtract. 1980b57cec5SDimitry Andricdef MSER : TernaryRRD<"mser", 0xB32F, null_frag, FP32, FP32>; 1990b57cec5SDimitry Andricdef MSDR : TernaryRRD<"msdr", 0xB33F, null_frag, FP64, FP64>; 200*0fca6ea1SDimitry Andricdef MSE : TernaryRXF<"mse", 0xED2F, null_frag, FP32, FP32, z_load, 4>; 201*0fca6ea1SDimitry Andricdef MSD : TernaryRXF<"msd", 0xED3F, null_frag, FP64, FP64, z_load, 8>; 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andric// Multiplication (unnormalized). 2040b57cec5SDimitry Andricdef MYR : BinaryRRD<"myr", 0xB33B, null_frag, FP128, FP64>; 2050b57cec5SDimitry Andricdef MYHR : BinaryRRD<"myhr", 0xB33D, null_frag, FP64, FP64>; 2060b57cec5SDimitry Andricdef MYLR : BinaryRRD<"mylr", 0xB339, null_frag, FP64, FP64>; 207*0fca6ea1SDimitry Andricdef MY : BinaryRXF<"my", 0xED3B, null_frag, FP128, FP64, z_load, 8>; 208*0fca6ea1SDimitry Andricdef MYH : BinaryRXF<"myh", 0xED3D, null_frag, FP64, FP64, z_load, 8>; 209*0fca6ea1SDimitry Andricdef MYL : BinaryRXF<"myl", 0xED39, null_frag, FP64, FP64, z_load, 8>; 2100b57cec5SDimitry Andric 2110b57cec5SDimitry Andric// Fused multiply-add (unnormalized). 2120b57cec5SDimitry Andricdef MAYHR : TernaryRRD<"mayhr", 0xB33C, null_frag, FP64, FP64>; 2130b57cec5SDimitry Andricdef MAYLR : TernaryRRD<"maylr", 0xB338, null_frag, FP64, FP64>; 214*0fca6ea1SDimitry Andricdef MAYH : TernaryRXF<"mayh", 0xED3C, null_frag, FP64, FP64, z_load, 8>; 215*0fca6ea1SDimitry Andricdef MAYL : TernaryRXF<"mayl", 0xED38, null_frag, FP64, FP64, z_load, 8>; 216*0fca6ea1SDimitry Andric 217*0fca6ea1SDimitry Andric// MAY and MAYR allow the user to specify the floating point register pair 218*0fca6ea1SDimitry Andric// making up the FP128 register by either the lower-numbered register or the 219*0fca6ea1SDimitry Andric// higher-numbered register, in contrast to all other floating point 220*0fca6ea1SDimitry Andric// instructions. 221*0fca6ea1SDimitry Andric// For this reason, the defs below accept `FP64,FP64` instead of `FP128,FP64`. 222*0fca6ea1SDimitry Andric// This is ok since these instructions are not used in code generation. 223*0fca6ea1SDimitry Andric// If and when code generation is enabled, the code gen variants should be 224*0fca6ea1SDimitry Andric// split out from this and use the proper register classes, while these should 225*0fca6ea1SDimitry Andric// remain for the Assembler and Disassembler to remain compliant with the POP. 226*0fca6ea1SDimitry Andricdef MAY : TernaryRXF<"may", 0xED3A, null_frag, FP64, FP64, z_load, 8>; 227*0fca6ea1SDimitry Andricdef MAYR : TernaryRRD<"mayr", 0xB33A, null_frag, FP64, FP64>; 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric// Division. 2300b57cec5SDimitry Andricdef DER : BinaryRR <"der", 0x3D, null_frag, FP32, FP32>; 2310b57cec5SDimitry Andricdef DDR : BinaryRR <"ddr", 0x2D, null_frag, FP64, FP64>; 2320b57cec5SDimitry Andricdef DXR : BinaryRRE<"dxr", 0xB22D, null_frag, FP128, FP128>; 233*0fca6ea1SDimitry Andricdef DE : BinaryRX <"de", 0x7D, null_frag, FP32, z_load, 4>; 234*0fca6ea1SDimitry Andricdef DD : BinaryRX <"dd", 0x6D, null_frag, FP64, z_load, 8>; 2350b57cec5SDimitry Andric 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 2380b57cec5SDimitry Andric// Comparisons 2390b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 2400b57cec5SDimitry Andric 2410b57cec5SDimitry Andriclet Defs = [CC] in { 2420b57cec5SDimitry Andric def CER : CompareRR <"cer", 0x39, null_frag, FP32, FP32>; 2430b57cec5SDimitry Andric def CDR : CompareRR <"cdr", 0x29, null_frag, FP64, FP64>; 2440b57cec5SDimitry Andric def CXR : CompareRRE<"cxr", 0xB369, null_frag, FP128, FP128>; 2450b57cec5SDimitry Andric 246*0fca6ea1SDimitry Andric def CE : CompareRX<"ce", 0x79, null_frag, FP32, z_load, 4>; 247*0fca6ea1SDimitry Andric def CD : CompareRX<"cd", 0x69, null_frag, FP64, z_load, 8>; 2480b57cec5SDimitry Andric} 2490b57cec5SDimitry Andric 250