xref: /freebsd/contrib/llvm-project/llvm/lib/Target/SystemZ/SystemZInstrHFP.td (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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