10b57cec5SDimitry Andric//===-- R600Instructions.td - R600 Instruction defs  -------*- 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// TableGen definitions for instructions which are available on R600 family
100b57cec5SDimitry Andric// GPUs.
110b57cec5SDimitry Andric//
120b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric
140b57cec5SDimitry Andricinclude "R600InstrFormats.td"
150b57cec5SDimitry Andric
160b57cec5SDimitry Andric// FIXME: Should not be arbitrarily split from other R600 inst classes.
170b57cec5SDimitry Andricclass R600WrapperInst <dag outs, dag ins, string asm = "", list<dag> pattern = []> :
180b57cec5SDimitry Andric  AMDGPUInst<outs, ins, asm, pattern>, PredicateControl {
190b57cec5SDimitry Andric  let SubtargetPredicate = isR600toCayman;
200b57cec5SDimitry Andric  let Namespace = "R600";
210b57cec5SDimitry Andric}
220b57cec5SDimitry Andric
230b57cec5SDimitry Andric
240b57cec5SDimitry Andricclass InstR600ISA <dag outs, dag ins, string asm, list<dag> pattern = []> :
250b57cec5SDimitry Andric    InstR600 <outs, ins, asm, pattern, NullALU> {
260b57cec5SDimitry Andric
270b57cec5SDimitry Andric}
280b57cec5SDimitry Andric
290b57cec5SDimitry Andricdef MEMxi : Operand<iPTR> {
300b57cec5SDimitry Andric  let MIOperandInfo = (ops R600_TReg32_X:$ptr, i32imm:$index);
310b57cec5SDimitry Andric  let PrintMethod = "printMemOperand";
320b57cec5SDimitry Andric}
330b57cec5SDimitry Andric
340b57cec5SDimitry Andricdef MEMrr : Operand<iPTR> {
350b57cec5SDimitry Andric  let MIOperandInfo = (ops R600_Reg32:$ptr, R600_Reg32:$index);
360b57cec5SDimitry Andric}
370b57cec5SDimitry Andric
380b57cec5SDimitry Andric// Operands for non-registers
390b57cec5SDimitry Andric
400b57cec5SDimitry Andricclass InstFlag<string PM = "printOperand", int Default = 0>
410b57cec5SDimitry Andric    : OperandWithDefaultOps <i32, (ops (i32 Default))> {
420b57cec5SDimitry Andric  let PrintMethod = PM;
430b57cec5SDimitry Andric}
440b57cec5SDimitry Andric
450b57cec5SDimitry Andric// src_sel for ALU src operands, see also ALU_CONST, ALU_PARAM registers
460b57cec5SDimitry Andricdef SEL : OperandWithDefaultOps <i32, (ops (i32 -1))>;
470b57cec5SDimitry Andricdef BANK_SWIZZLE : OperandWithDefaultOps <i32, (ops (i32 0))> {
480b57cec5SDimitry Andric  let PrintMethod = "printBankSwizzle";
490b57cec5SDimitry Andric}
500b57cec5SDimitry Andric
510b57cec5SDimitry Andricdef LITERAL : InstFlag<"printLiteral">;
520b57cec5SDimitry Andric
530b57cec5SDimitry Andricdef WRITE : InstFlag <"printWrite", 1>;
540b57cec5SDimitry Andricdef OMOD : InstFlag <"printOMOD">;
550b57cec5SDimitry Andricdef REL : InstFlag <"printRel">;
560b57cec5SDimitry Andricdef CLAMP : InstFlag <"printClamp">;
570b57cec5SDimitry Andricdef NEG : InstFlag <"printNeg">;
580b57cec5SDimitry Andricdef ABS : InstFlag <"printAbs">;
590b57cec5SDimitry Andricdef UEM : InstFlag <"printUpdateExecMask">;
600b57cec5SDimitry Andricdef UP : InstFlag <"printUpdatePred">;
610b57cec5SDimitry Andric
620b57cec5SDimitry Andric// XXX: The r600g finalizer in Mesa expects last to be one in most cases.
630b57cec5SDimitry Andric// Once we start using the packetizer in this backend we should have this
640b57cec5SDimitry Andric// default to 0.
650b57cec5SDimitry Andricdef LAST : InstFlag<"printLast", 1>;
660b57cec5SDimitry Andricdef RSel : Operand<i32> {
670b57cec5SDimitry Andric  let PrintMethod = "printRSel";
680b57cec5SDimitry Andric}
690b57cec5SDimitry Andricdef CT: Operand<i32> {
700b57cec5SDimitry Andric  let PrintMethod = "printCT";
710b57cec5SDimitry Andric}
720b57cec5SDimitry Andric
730b57cec5SDimitry Andricdef FRAMEri : Operand<iPTR> {
740b57cec5SDimitry Andric  let MIOperandInfo = (ops R600_Reg32:$ptr, i32imm:$index);
750b57cec5SDimitry Andric}
760b57cec5SDimitry Andric
770b57cec5SDimitry Andricdef ADDRVTX_READ : ComplexPattern<i32, 2, "SelectADDRVTX_READ", [], []>;
780b57cec5SDimitry Andricdef ADDRGA_CONST_OFFSET : ComplexPattern<i32, 1, "SelectGlobalValueConstantOffset", [], []>;
790b57cec5SDimitry Andricdef ADDRGA_VAR_OFFSET : ComplexPattern<i32, 2, "SelectGlobalValueVariableOffset", [], []>;
800b57cec5SDimitry Andricdef ADDRIndirect : ComplexPattern<iPTR, 2, "SelectADDRIndirect", [], []>;
810b57cec5SDimitry Andric
820b57cec5SDimitry Andric
830b57cec5SDimitry Andricdef R600_Pred : PredicateOperand<i32, (ops R600_Predicate),
840b57cec5SDimitry Andric                                     (ops PRED_SEL_OFF)>;
850b57cec5SDimitry Andric
860b57cec5SDimitry Andriclet isTerminator = 1, isReturn = 1, hasCtrlDep = 1,
870b57cec5SDimitry Andric    usesCustomInserter = 1, Namespace = "R600" in {
880b57cec5SDimitry Andric  def RETURN : ILFormat<(outs), (ins variable_ops),
890b57cec5SDimitry Andric    "RETURN", [(AMDGPUendpgm)]
900b57cec5SDimitry Andric  >;
910b57cec5SDimitry Andric}
920b57cec5SDimitry Andric
930b57cec5SDimitry Andriclet mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
940b57cec5SDimitry Andric
950b57cec5SDimitry Andric// Class for instructions with only one source register.
960b57cec5SDimitry Andric// If you add new ins to this instruction, make sure they are listed before
970b57cec5SDimitry Andric// $literal, because the backend currently assumes that the last operand is
980b57cec5SDimitry Andric// a literal.  Also be sure to update the enum R600Op1OperandIndex::ROI in
990b57cec5SDimitry Andric// R600Defines.h, R600InstrInfo::buildDefaultInstruction(),
1000b57cec5SDimitry Andric// and R600InstrInfo::getOperandIdx().
1010b57cec5SDimitry Andricclass R600_1OP <bits<11> inst, string opName, list<dag> pattern,
1020b57cec5SDimitry Andric                InstrItinClass itin = AnyALU> :
1030b57cec5SDimitry Andric    InstR600 <(outs R600_Reg32:$dst),
1040b57cec5SDimitry Andric              (ins WRITE:$write, OMOD:$omod, REL:$dst_rel, CLAMP:$clamp,
1050b57cec5SDimitry Andric                   R600_Reg32:$src0, NEG:$src0_neg, REL:$src0_rel, ABS:$src0_abs, SEL:$src0_sel,
1060b57cec5SDimitry Andric                   LAST:$last, R600_Pred:$pred_sel, LITERAL:$literal,
1070b57cec5SDimitry Andric                   BANK_SWIZZLE:$bank_swizzle),
1080b57cec5SDimitry Andric              !strconcat("  ", opName,
1090b57cec5SDimitry Andric                   "$clamp $last $dst$write$dst_rel$omod, "
1100b57cec5SDimitry Andric                   "$src0_neg$src0_abs$src0$src0_abs$src0_rel, "
1110b57cec5SDimitry Andric                   "$pred_sel $bank_swizzle"),
1120b57cec5SDimitry Andric              pattern,
1130b57cec5SDimitry Andric              itin>,
1140b57cec5SDimitry Andric    R600ALU_Word0,
1150b57cec5SDimitry Andric    R600ALU_Word1_OP2 <inst> {
1160b57cec5SDimitry Andric
1170b57cec5SDimitry Andric  let src1 = 0;
1180b57cec5SDimitry Andric  let src1_rel = 0;
1190b57cec5SDimitry Andric  let src1_neg = 0;
1200b57cec5SDimitry Andric  let src1_abs = 0;
1210b57cec5SDimitry Andric  let update_exec_mask = 0;
1220b57cec5SDimitry Andric  let update_pred = 0;
1230b57cec5SDimitry Andric  let HasNativeOperands = 1;
1240b57cec5SDimitry Andric  let Op1 = 1;
1250b57cec5SDimitry Andric  let ALUInst = 1;
1260b57cec5SDimitry Andric  let DisableEncoding = "$literal";
1270b57cec5SDimitry Andric  let UseNamedOperandTable = 1;
1280b57cec5SDimitry Andric
1290b57cec5SDimitry Andric  let Inst{31-0}  = Word0;
1300b57cec5SDimitry Andric  let Inst{63-32} = Word1;
1310b57cec5SDimitry Andric}
1320b57cec5SDimitry Andric
1330b57cec5SDimitry Andricclass R600_1OP_Helper <bits<11> inst, string opName, SDPatternOperator node,
1340b57cec5SDimitry Andric                    InstrItinClass itin = AnyALU> :
1350b57cec5SDimitry Andric    R600_1OP <inst, opName,
1360b57cec5SDimitry Andric              [(set R600_Reg32:$dst, (node R600_Reg32:$src0))], itin
1370b57cec5SDimitry Andric>;
1380b57cec5SDimitry Andric
1390b57cec5SDimitry Andric// If you add or change the operands for R600_2OP instructions, you must
1400b57cec5SDimitry Andric// also update the R600Op2OperandIndex::ROI enum in R600Defines.h,
1410b57cec5SDimitry Andric// R600InstrInfo::buildDefaultInstruction(), and R600InstrInfo::getOperandIdx().
1420b57cec5SDimitry Andricclass R600_2OP <bits<11> inst, string opName, list<dag> pattern,
1430b57cec5SDimitry Andric                InstrItinClass itin = AnyALU> :
1440b57cec5SDimitry Andric  InstR600 <(outs R600_Reg32:$dst),
1450b57cec5SDimitry Andric          (ins UEM:$update_exec_mask, UP:$update_pred, WRITE:$write,
1460b57cec5SDimitry Andric               OMOD:$omod, REL:$dst_rel, CLAMP:$clamp,
1470b57cec5SDimitry Andric               R600_Reg32:$src0, NEG:$src0_neg, REL:$src0_rel, ABS:$src0_abs, SEL:$src0_sel,
1480b57cec5SDimitry Andric               R600_Reg32:$src1, NEG:$src1_neg, REL:$src1_rel, ABS:$src1_abs, SEL:$src1_sel,
1490b57cec5SDimitry Andric               LAST:$last, R600_Pred:$pred_sel, LITERAL:$literal,
1500b57cec5SDimitry Andric               BANK_SWIZZLE:$bank_swizzle),
1510b57cec5SDimitry Andric          !strconcat("  ", opName,
1520b57cec5SDimitry Andric                "$clamp $last $update_exec_mask$update_pred$dst$write$dst_rel$omod, "
1530b57cec5SDimitry Andric                "$src0_neg$src0_abs$src0$src0_abs$src0_rel, "
1540b57cec5SDimitry Andric                "$src1_neg$src1_abs$src1$src1_abs$src1_rel, "
1550b57cec5SDimitry Andric                "$pred_sel $bank_swizzle"),
1560b57cec5SDimitry Andric          pattern,
1570b57cec5SDimitry Andric          itin>,
1580b57cec5SDimitry Andric    R600ALU_Word0,
1590b57cec5SDimitry Andric    R600ALU_Word1_OP2 <inst> {
1600b57cec5SDimitry Andric
1610b57cec5SDimitry Andric  let HasNativeOperands = 1;
1620b57cec5SDimitry Andric  let Op2 = 1;
1630b57cec5SDimitry Andric  let ALUInst = 1;
1640b57cec5SDimitry Andric  let DisableEncoding = "$literal";
1650b57cec5SDimitry Andric  let UseNamedOperandTable = 1;
1660b57cec5SDimitry Andric
1670b57cec5SDimitry Andric  let Inst{31-0}  = Word0;
1680b57cec5SDimitry Andric  let Inst{63-32} = Word1;
1690b57cec5SDimitry Andric}
1700b57cec5SDimitry Andric
1710b57cec5SDimitry Andricclass R600_2OP_Helper <bits<11> inst, string opName,
1720b57cec5SDimitry Andric                       SDPatternOperator node = null_frag,
1730b57cec5SDimitry Andric                       InstrItinClass itin = AnyALU> :
1740b57cec5SDimitry Andric    R600_2OP <inst, opName,
1750b57cec5SDimitry Andric              [(set R600_Reg32:$dst, (node R600_Reg32:$src0,
1760b57cec5SDimitry Andric                                           R600_Reg32:$src1))], itin
1770b57cec5SDimitry Andric>;
1780b57cec5SDimitry Andric
1790b57cec5SDimitry Andric// If you add our change the operands for R600_3OP instructions, you must
1800b57cec5SDimitry Andric// also update the R600Op3OperandIndex::ROI enum in R600Defines.h,
1810b57cec5SDimitry Andric// R600InstrInfo::buildDefaultInstruction(), and
1820b57cec5SDimitry Andric// R600InstrInfo::getOperandIdx().
1830b57cec5SDimitry Andricclass R600_3OP <bits<5> inst, string opName, list<dag> pattern,
1840b57cec5SDimitry Andric                InstrItinClass itin = AnyALU> :
1850b57cec5SDimitry Andric  InstR600 <(outs R600_Reg32:$dst),
1860b57cec5SDimitry Andric          (ins REL:$dst_rel, CLAMP:$clamp,
1870b57cec5SDimitry Andric               R600_Reg32:$src0, NEG:$src0_neg, REL:$src0_rel, SEL:$src0_sel,
1880b57cec5SDimitry Andric               R600_Reg32:$src1, NEG:$src1_neg, REL:$src1_rel, SEL:$src1_sel,
1890b57cec5SDimitry Andric               R600_Reg32:$src2, NEG:$src2_neg, REL:$src2_rel, SEL:$src2_sel,
1900b57cec5SDimitry Andric               LAST:$last, R600_Pred:$pred_sel, LITERAL:$literal,
1910b57cec5SDimitry Andric               BANK_SWIZZLE:$bank_swizzle),
1920b57cec5SDimitry Andric          !strconcat("  ", opName, "$clamp $last $dst$dst_rel, "
1930b57cec5SDimitry Andric                             "$src0_neg$src0$src0_rel, "
1940b57cec5SDimitry Andric                             "$src1_neg$src1$src1_rel, "
1950b57cec5SDimitry Andric                             "$src2_neg$src2$src2_rel, "
1960b57cec5SDimitry Andric                             "$pred_sel"
1970b57cec5SDimitry Andric                             "$bank_swizzle"),
1980b57cec5SDimitry Andric          pattern,
1990b57cec5SDimitry Andric          itin>,
2000b57cec5SDimitry Andric    R600ALU_Word0,
2010b57cec5SDimitry Andric    R600ALU_Word1_OP3<inst>{
2020b57cec5SDimitry Andric
2030b57cec5SDimitry Andric  let HasNativeOperands = 1;
2040b57cec5SDimitry Andric  let DisableEncoding = "$literal";
2050b57cec5SDimitry Andric  let Op3 = 1;
2060b57cec5SDimitry Andric  let UseNamedOperandTable = 1;
2070b57cec5SDimitry Andric  let ALUInst = 1;
2080b57cec5SDimitry Andric
2090b57cec5SDimitry Andric  let Inst{31-0}  = Word0;
2100b57cec5SDimitry Andric  let Inst{63-32} = Word1;
2110b57cec5SDimitry Andric}
2120b57cec5SDimitry Andric
2130b57cec5SDimitry Andric} // End mayLoad = 1, mayStore = 0, hasSideEffects = 0
2140b57cec5SDimitry Andric
2150b57cec5SDimitry Andricclass EG_CF_RAT <bits <8> cfinst, bits <6> ratinst, bits<4> ratid, bits<4> mask,
2160b57cec5SDimitry Andric                 dag outs, dag ins, string asm, list<dag> pattern> :
2170b57cec5SDimitry Andric    InstR600ISA <outs, ins, asm, pattern>,
2180b57cec5SDimitry Andric    CF_ALLOC_EXPORT_WORD0_RAT, CF_ALLOC_EXPORT_WORD1_BUF  {
2190b57cec5SDimitry Andric
2200b57cec5SDimitry Andric  let rat_id = ratid;
2210b57cec5SDimitry Andric  let rat_inst = ratinst;
2220b57cec5SDimitry Andric  let rim         = 0;
2230b57cec5SDimitry Andric  // XXX: Have a separate instruction for non-indexed writes.
2240b57cec5SDimitry Andric  let type        = 1;
2250b57cec5SDimitry Andric  let rw_rel      = 0;
2260b57cec5SDimitry Andric  let elem_size   = 0;
2270b57cec5SDimitry Andric
2280b57cec5SDimitry Andric  let array_size  = 0;
2290b57cec5SDimitry Andric  let comp_mask   = mask;
2300b57cec5SDimitry Andric  let burst_count = 0;
2310b57cec5SDimitry Andric  let vpm         = 0;
2320b57cec5SDimitry Andric  let cf_inst = cfinst;
2330b57cec5SDimitry Andric  let mark        = 0;
2340b57cec5SDimitry Andric  let barrier     = 1;
2350b57cec5SDimitry Andric
2360b57cec5SDimitry Andric  let Inst{31-0} = Word0;
2370b57cec5SDimitry Andric  let Inst{63-32} = Word1;
2380b57cec5SDimitry Andric  let IsExport = 1;
2390b57cec5SDimitry Andric
2400b57cec5SDimitry Andric}
2410b57cec5SDimitry Andric
2420b57cec5SDimitry Andricclass VTX_READ <string name, dag outs, list<dag> pattern>
2430b57cec5SDimitry Andric    : InstR600ISA <outs, (ins MEMxi:$src_gpr, i8imm:$buffer_id), !strconcat("  ", name, ", #$buffer_id"), pattern>,
2440b57cec5SDimitry Andric      VTX_WORD1_GPR {
2450b57cec5SDimitry Andric
2460b57cec5SDimitry Andric  // Static fields
2470b57cec5SDimitry Andric  let DST_REL = 0;
2480b57cec5SDimitry Andric  // The docs say that if this bit is set, then DATA_FORMAT, NUM_FORMAT_ALL,
2490b57cec5SDimitry Andric  // FORMAT_COMP_ALL, SRF_MODE_ALL, and ENDIAN_SWAP fields will be ignored,
2500b57cec5SDimitry Andric  // however, based on my testing if USE_CONST_FIELDS is set, then all
2510b57cec5SDimitry Andric  // these fields need to be set to 0.
2520b57cec5SDimitry Andric  let USE_CONST_FIELDS = 0;
2530b57cec5SDimitry Andric  let NUM_FORMAT_ALL = 1;
2540b57cec5SDimitry Andric  let FORMAT_COMP_ALL = 0;
2550b57cec5SDimitry Andric  let SRF_MODE_ALL = 0;
2560b57cec5SDimitry Andric
2570b57cec5SDimitry Andric  let Inst{63-32} = Word1;
2580b57cec5SDimitry Andric  // LLVM can only encode 64-bit instructions, so these fields are manually
2590b57cec5SDimitry Andric  // encoded in R600CodeEmitter
2600b57cec5SDimitry Andric  //
2610b57cec5SDimitry Andric  // bits<16> OFFSET;
2620b57cec5SDimitry Andric  // bits<2>  ENDIAN_SWAP = 0;
2630b57cec5SDimitry Andric  // bits<1>  CONST_BUF_NO_STRIDE = 0;
2640b57cec5SDimitry Andric  // bits<1>  MEGA_FETCH = 0;
2650b57cec5SDimitry Andric  // bits<1>  ALT_CONST = 0;
2660b57cec5SDimitry Andric  // bits<2>  BUFFER_INDEX_MODE = 0;
2670b57cec5SDimitry Andric
2680b57cec5SDimitry Andric  // VTX_WORD2 (LLVM can only encode 64-bit instructions, so WORD2 encoding
2690b57cec5SDimitry Andric  // is done in R600CodeEmitter
2700b57cec5SDimitry Andric  //
2710b57cec5SDimitry Andric  // Inst{79-64} = OFFSET;
2720b57cec5SDimitry Andric  // Inst{81-80} = ENDIAN_SWAP;
2730b57cec5SDimitry Andric  // Inst{82}    = CONST_BUF_NO_STRIDE;
2740b57cec5SDimitry Andric  // Inst{83}    = MEGA_FETCH;
2750b57cec5SDimitry Andric  // Inst{84}    = ALT_CONST;
2760b57cec5SDimitry Andric  // Inst{86-85} = BUFFER_INDEX_MODE;
2770b57cec5SDimitry Andric  // Inst{95-86} = 0; Reserved
2780b57cec5SDimitry Andric
2790b57cec5SDimitry Andric  // VTX_WORD3 (Padding)
2800b57cec5SDimitry Andric  //
2810b57cec5SDimitry Andric  // Inst{127-96} = 0;
2820b57cec5SDimitry Andric
2830b57cec5SDimitry Andric  let VTXInst = 1;
2840b57cec5SDimitry Andric}
2850b57cec5SDimitry Andric
286480093f4SDimitry Andric// Legacy.
287480093f4SDimitry Andricdef atomic_cmp_swap_global_noret : PatFrag<
288480093f4SDimitry Andric  (ops node:$ptr, node:$cmp, node:$value),
289480093f4SDimitry Andric  (atomic_cmp_swap node:$ptr, node:$cmp, node:$value),
290480093f4SDimitry Andric  [{return cast<MemSDNode>(N)->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS && (SDValue(N, 0).use_empty());}]>;
2910b57cec5SDimitry Andric
292480093f4SDimitry Andricdef atomic_cmp_swap_global_ret : PatFrag<
293480093f4SDimitry Andric  (ops node:$ptr, node:$cmp, node:$value),
294480093f4SDimitry Andric  (atomic_cmp_swap node:$ptr, node:$cmp, node:$value),
295480093f4SDimitry Andric  [{return cast<MemSDNode>(N)->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS && (!SDValue(N, 0).use_empty());}]>;
296480093f4SDimitry Andric
297480093f4SDimitry Andricdef mskor_global : PatFrag<(ops node:$val, node:$ptr),
298480093f4SDimitry Andric                            (AMDGPUstore_mskor node:$val, node:$ptr), [{
299480093f4SDimitry Andric  return cast<MemSDNode>(N)->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS;
300480093f4SDimitry Andric}]>;
301480093f4SDimitry Andric
302480093f4SDimitry Andric// FIXME: These are deprecated
3030b57cec5SDimitry Andricclass AZExtLoadBase <SDPatternOperator ld_node>: PatFrag<(ops node:$ptr),
3040b57cec5SDimitry Andric                                              (ld_node node:$ptr), [{
3050b57cec5SDimitry Andric  LoadSDNode *L = cast<LoadSDNode>(N);
3060b57cec5SDimitry Andric  return L->getExtensionType() == ISD::ZEXTLOAD ||
3070b57cec5SDimitry Andric         L->getExtensionType() == ISD::EXTLOAD;
3080b57cec5SDimitry Andric}]>;
3090b57cec5SDimitry Andric
3100b57cec5SDimitry Andricdef az_extload : AZExtLoadBase <unindexedload>;
3110b57cec5SDimitry Andric
3120b57cec5SDimitry Andricdef az_extloadi8 : PatFrag<(ops node:$ptr), (az_extload node:$ptr), [{
3130b57cec5SDimitry Andric  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;
3140b57cec5SDimitry Andric}]>;
3150b57cec5SDimitry Andric
3160b57cec5SDimitry Andricdef az_extloadi16 : PatFrag<(ops node:$ptr), (az_extload node:$ptr), [{
3170b57cec5SDimitry Andric  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;
3180b57cec5SDimitry Andric}]>;
3190b57cec5SDimitry Andric
3200b57cec5SDimitry Andricdef az_extloadi32 : PatFrag<(ops node:$ptr), (az_extload node:$ptr), [{
3210b57cec5SDimitry Andric  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32;
3220b57cec5SDimitry Andric}]>;
3230b57cec5SDimitry Andric
324480093f4SDimitry Andriclet AddressSpaces = LoadAddress_local.AddrSpaces in {
325480093f4SDimitry Andricdef az_extloadi8_local : PatFrag<(ops node:$ptr), (az_extloadi8 node:$ptr)>;
326480093f4SDimitry Andricdef az_extloadi16_local : PatFrag<(ops node:$ptr), (az_extloadi16 node:$ptr)>;
327480093f4SDimitry Andric}
3280b57cec5SDimitry Andric
3290b57cec5SDimitry Andricclass LoadParamFrag <PatFrag load_type> : PatFrag <
3300b57cec5SDimitry Andric  (ops node:$ptr), (load_type node:$ptr),
3310b57cec5SDimitry Andric  [{ return isConstantLoad(cast<LoadSDNode>(N), 0) ||
3320b57cec5SDimitry Andric            (cast<LoadSDNode>(N)->getAddressSpace() == AMDGPUAS::PARAM_I_ADDRESS); }]
3330b57cec5SDimitry Andric>;
3340b57cec5SDimitry Andric
3350b57cec5SDimitry Andricdef vtx_id3_az_extloadi8 : LoadParamFrag<az_extloadi8>;
3360b57cec5SDimitry Andricdef vtx_id3_az_extloadi16 : LoadParamFrag<az_extloadi16>;
3370b57cec5SDimitry Andricdef vtx_id3_load : LoadParamFrag<load>;
3380b57cec5SDimitry Andric
3390b57cec5SDimitry Andricclass LoadVtxId1 <PatFrag load> : PatFrag <
3400b57cec5SDimitry Andric  (ops node:$ptr), (load node:$ptr), [{
3410b57cec5SDimitry Andric  const MemSDNode *LD = cast<MemSDNode>(N);
3420b57cec5SDimitry Andric  return LD->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS ||
3430b57cec5SDimitry Andric         (LD->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS &&
344e8d8bef9SDimitry Andric           !isa<GlobalValue>(getUnderlyingObject(
345e8d8bef9SDimitry Andric           LD->getMemOperand()->getValue())));
3460b57cec5SDimitry Andric}]>;
3470b57cec5SDimitry Andric
3480b57cec5SDimitry Andricdef vtx_id1_az_extloadi8 : LoadVtxId1 <az_extloadi8>;
3490b57cec5SDimitry Andricdef vtx_id1_az_extloadi16 : LoadVtxId1 <az_extloadi16>;
3500b57cec5SDimitry Andricdef vtx_id1_load : LoadVtxId1 <load>;
3510b57cec5SDimitry Andric
3520b57cec5SDimitry Andricclass LoadVtxId2 <PatFrag load> : PatFrag <
3530b57cec5SDimitry Andric  (ops node:$ptr), (load node:$ptr), [{
3540b57cec5SDimitry Andric  const MemSDNode *LD = cast<MemSDNode>(N);
3550b57cec5SDimitry Andric  return LD->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS &&
356e8d8bef9SDimitry Andric         isa<GlobalValue>(getUnderlyingObject(
357e8d8bef9SDimitry Andric         LD->getMemOperand()->getValue()));
3580b57cec5SDimitry Andric}]>;
3590b57cec5SDimitry Andric
3600b57cec5SDimitry Andricdef vtx_id2_az_extloadi8 : LoadVtxId2 <az_extloadi8>;
3610b57cec5SDimitry Andricdef vtx_id2_az_extloadi16 : LoadVtxId2 <az_extloadi16>;
3620b57cec5SDimitry Andricdef vtx_id2_load : LoadVtxId2 <load>;
3630b57cec5SDimitry Andric
3640b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
3650b57cec5SDimitry Andric// R600 SDNodes
3660b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
3670b57cec5SDimitry Andric
3680b57cec5SDimitry Andriclet Namespace = "R600" in {
3690b57cec5SDimitry Andric
3700b57cec5SDimitry Andricdef INTERP_PAIR_XY :  AMDGPUShaderInst <
3710b57cec5SDimitry Andric  (outs R600_TReg32_X:$dst0, R600_TReg32_Y:$dst1),
3720b57cec5SDimitry Andric  (ins i32imm:$src0, R600_TReg32_Y:$src1, R600_TReg32_X:$src2),
3730b57cec5SDimitry Andric  "INTERP_PAIR_XY $src0 $src1 $src2 : $dst0 dst1",
3740b57cec5SDimitry Andric  []>;
3750b57cec5SDimitry Andric
3760b57cec5SDimitry Andricdef INTERP_PAIR_ZW :  AMDGPUShaderInst <
3770b57cec5SDimitry Andric  (outs R600_TReg32_Z:$dst0, R600_TReg32_W:$dst1),
3780b57cec5SDimitry Andric  (ins i32imm:$src0, R600_TReg32_Y:$src1, R600_TReg32_X:$src2),
3790b57cec5SDimitry Andric  "INTERP_PAIR_ZW $src0 $src1 $src2 : $dst0 dst1",
3800b57cec5SDimitry Andric  []>;
3810b57cec5SDimitry Andric
3820b57cec5SDimitry Andric}
3830b57cec5SDimitry Andric
3840b57cec5SDimitry Andricdef CONST_ADDRESS: SDNode<"AMDGPUISD::CONST_ADDRESS",
3850b57cec5SDimitry Andric  SDTypeProfile<1, -1, [SDTCisInt<0>, SDTCisPtrTy<1>]>,
3860b57cec5SDimitry Andric  [SDNPVariadic]
3870b57cec5SDimitry Andric>;
3880b57cec5SDimitry Andric
3890b57cec5SDimitry Andricdef DOT4 : SDNode<"AMDGPUISD::DOT4",
3900b57cec5SDimitry Andric  SDTypeProfile<1, 8, [SDTCisFP<0>, SDTCisVT<1, f32>, SDTCisVT<2, f32>,
3910b57cec5SDimitry Andric      SDTCisVT<3, f32>, SDTCisVT<4, f32>, SDTCisVT<5, f32>,
3920b57cec5SDimitry Andric      SDTCisVT<6, f32>, SDTCisVT<7, f32>, SDTCisVT<8, f32>]>,
3930b57cec5SDimitry Andric  []
3940b57cec5SDimitry Andric>;
3950b57cec5SDimitry Andric
3960b57cec5SDimitry Andricdef COS_HW : SDNode<"AMDGPUISD::COS_HW",
3970b57cec5SDimitry Andric  SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisFP<1>]>
3980b57cec5SDimitry Andric>;
3990b57cec5SDimitry Andric
4000b57cec5SDimitry Andricdef SIN_HW : SDNode<"AMDGPUISD::SIN_HW",
4010b57cec5SDimitry Andric  SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisFP<1>]>
4020b57cec5SDimitry Andric>;
4030b57cec5SDimitry Andric
4040b57cec5SDimitry Andricdef TEXTURE_FETCH_Type : SDTypeProfile<1, 19, [SDTCisFP<0>]>;
4050b57cec5SDimitry Andric
4060b57cec5SDimitry Andricdef TEXTURE_FETCH: SDNode<"AMDGPUISD::TEXTURE_FETCH", TEXTURE_FETCH_Type, []>;
4070b57cec5SDimitry Andric
4080b57cec5SDimitry Andricmulticlass TexPattern<bits<32> TextureOp, Instruction inst, ValueType vt = v4f32> {
4090b57cec5SDimitry Andricdef : R600Pat<(TEXTURE_FETCH (i32 TextureOp), vt:$SRC_GPR,
4100b57cec5SDimitry Andric          (i32 imm:$srcx), (i32 imm:$srcy), (i32 imm:$srcz), (i32 imm:$srcw),
4110b57cec5SDimitry Andric          (i32 imm:$offsetx), (i32 imm:$offsety), (i32 imm:$offsetz),
4120b57cec5SDimitry Andric          (i32 imm:$DST_SEL_X), (i32 imm:$DST_SEL_Y), (i32 imm:$DST_SEL_Z),
4130b57cec5SDimitry Andric          (i32 imm:$DST_SEL_W),
4140b57cec5SDimitry Andric          (i32 imm:$RESOURCE_ID), (i32 imm:$SAMPLER_ID),
4150b57cec5SDimitry Andric          (i32 imm:$COORD_TYPE_X), (i32 imm:$COORD_TYPE_Y), (i32 imm:$COORD_TYPE_Z),
4160b57cec5SDimitry Andric          (i32 imm:$COORD_TYPE_W)),
4170b57cec5SDimitry Andric          (inst R600_Reg128:$SRC_GPR,
4180b57cec5SDimitry Andric          imm:$srcx, imm:$srcy, imm:$srcz, imm:$srcw,
4190b57cec5SDimitry Andric          imm:$offsetx, imm:$offsety, imm:$offsetz,
4200b57cec5SDimitry Andric          imm:$DST_SEL_X, imm:$DST_SEL_Y, imm:$DST_SEL_Z,
4210b57cec5SDimitry Andric          imm:$DST_SEL_W,
4220b57cec5SDimitry Andric          imm:$RESOURCE_ID, imm:$SAMPLER_ID,
4230b57cec5SDimitry Andric          imm:$COORD_TYPE_X, imm:$COORD_TYPE_Y, imm:$COORD_TYPE_Z,
4240b57cec5SDimitry Andric          imm:$COORD_TYPE_W)>;
4250b57cec5SDimitry Andric}
4260b57cec5SDimitry Andric
4270b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
4280b57cec5SDimitry Andric// Interpolation Instructions
4290b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
4300b57cec5SDimitry Andric
4310b57cec5SDimitry Andriclet Namespace = "R600" in {
4320b57cec5SDimitry Andric
4330b57cec5SDimitry Andricdef INTERP_VEC_LOAD :  AMDGPUShaderInst <
4340b57cec5SDimitry Andric  (outs R600_Reg128:$dst),
4350b57cec5SDimitry Andric  (ins i32imm:$src0),
4360b57cec5SDimitry Andric  "INTERP_LOAD $src0 : $dst">;
4370b57cec5SDimitry Andric
4380b57cec5SDimitry Andric}
4390b57cec5SDimitry Andric
4400b57cec5SDimitry Andricdef INTERP_XY : R600_2OP <0xD6, "INTERP_XY", []> {
4410b57cec5SDimitry Andric  let bank_swizzle = 5;
4420b57cec5SDimitry Andric}
4430b57cec5SDimitry Andric
4440b57cec5SDimitry Andricdef INTERP_ZW : R600_2OP <0xD7, "INTERP_ZW", []> {
4450b57cec5SDimitry Andric  let bank_swizzle = 5;
4460b57cec5SDimitry Andric}
4470b57cec5SDimitry Andric
4480b57cec5SDimitry Andricdef INTERP_LOAD_P0 : R600_1OP <0xE0, "INTERP_LOAD_P0", []>;
4490b57cec5SDimitry Andric
4500b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
4510b57cec5SDimitry Andric// Export Instructions
4520b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
4530b57cec5SDimitry Andric
4540b57cec5SDimitry Andricclass ExportWord0 {
4550b57cec5SDimitry Andric  field bits<32> Word0;
4560b57cec5SDimitry Andric
4570b57cec5SDimitry Andric  bits<13> arraybase;
4580b57cec5SDimitry Andric  bits<2> type;
4590b57cec5SDimitry Andric  bits<7> gpr;
4600b57cec5SDimitry Andric  bits<2> elem_size;
4610b57cec5SDimitry Andric
4620b57cec5SDimitry Andric  let Word0{12-0} = arraybase;
4630b57cec5SDimitry Andric  let Word0{14-13} = type;
4640b57cec5SDimitry Andric  let Word0{21-15} = gpr;
4650b57cec5SDimitry Andric  let Word0{22} = 0; // RW_REL
4660b57cec5SDimitry Andric  let Word0{29-23} = 0; // INDEX_GPR
4670b57cec5SDimitry Andric  let Word0{31-30} = elem_size;
4680b57cec5SDimitry Andric}
4690b57cec5SDimitry Andric
4700b57cec5SDimitry Andricclass ExportSwzWord1 {
4710b57cec5SDimitry Andric  field bits<32> Word1;
4720b57cec5SDimitry Andric
4730b57cec5SDimitry Andric  bits<3> sw_x;
4740b57cec5SDimitry Andric  bits<3> sw_y;
4750b57cec5SDimitry Andric  bits<3> sw_z;
4760b57cec5SDimitry Andric  bits<3> sw_w;
4770b57cec5SDimitry Andric  bits<1> eop;
4780b57cec5SDimitry Andric  bits<8> inst;
4790b57cec5SDimitry Andric
4800b57cec5SDimitry Andric  let Word1{2-0} = sw_x;
4810b57cec5SDimitry Andric  let Word1{5-3} = sw_y;
4820b57cec5SDimitry Andric  let Word1{8-6} = sw_z;
4830b57cec5SDimitry Andric  let Word1{11-9} = sw_w;
4840b57cec5SDimitry Andric}
4850b57cec5SDimitry Andric
4860b57cec5SDimitry Andricclass ExportBufWord1 {
4870b57cec5SDimitry Andric  field bits<32> Word1;
4880b57cec5SDimitry Andric
4890b57cec5SDimitry Andric  bits<12> arraySize;
4900b57cec5SDimitry Andric  bits<4> compMask;
4910b57cec5SDimitry Andric  bits<1> eop;
4920b57cec5SDimitry Andric  bits<8> inst;
4930b57cec5SDimitry Andric
4940b57cec5SDimitry Andric  let Word1{11-0} = arraySize;
4950b57cec5SDimitry Andric  let Word1{15-12} = compMask;
4960b57cec5SDimitry Andric}
4970b57cec5SDimitry Andric
4980b57cec5SDimitry Andricmulticlass ExportPattern<Instruction ExportInst, bits<8> cf_inst> {
4990b57cec5SDimitry Andric  def : R600Pat<(R600_EXPORT (v4f32 R600_Reg128:$src), (i32 imm:$base), (i32 imm:$type),
5000b57cec5SDimitry Andric    (i32 imm:$swz_x), (i32 imm:$swz_y), (i32 imm:$swz_z), (i32 imm:$swz_w)),
5010b57cec5SDimitry Andric        (ExportInst R600_Reg128:$src, imm:$type, imm:$base,
5020b57cec5SDimitry Andric        imm:$swz_x, imm:$swz_y, imm:$swz_z, imm:$swz_w, cf_inst, 0)
5030b57cec5SDimitry Andric  >;
5040b57cec5SDimitry Andric
5050b57cec5SDimitry Andric}
5060b57cec5SDimitry Andric
5070b57cec5SDimitry Andricmulticlass SteamOutputExportPattern<Instruction ExportInst,
5080b57cec5SDimitry Andric    bits<8> buf0inst, bits<8> buf1inst, bits<8> buf2inst, bits<8> buf3inst> {
5090b57cec5SDimitry Andric// Stream0
5100b57cec5SDimitry Andric  def : R600Pat<(int_r600_store_stream_output (v4f32 R600_Reg128:$src),
5110b57cec5SDimitry Andric      (i32 imm:$arraybase), (i32 0), (i32 imm:$mask)),
5120b57cec5SDimitry Andric      (ExportInst R600_Reg128:$src, 0, imm:$arraybase,
5130b57cec5SDimitry Andric      4095, imm:$mask, buf0inst, 0)>;
5140b57cec5SDimitry Andric// Stream1
5150b57cec5SDimitry Andric  def : R600Pat<(int_r600_store_stream_output (v4f32 R600_Reg128:$src),
5160b57cec5SDimitry Andric      (i32 imm:$arraybase), (i32 1), (i32 imm:$mask)),
5170b57cec5SDimitry Andric      (ExportInst $src, 0, imm:$arraybase,
5180b57cec5SDimitry Andric      4095, imm:$mask, buf1inst, 0)>;
5190b57cec5SDimitry Andric// Stream2
5200b57cec5SDimitry Andric  def : R600Pat<(int_r600_store_stream_output (v4f32 R600_Reg128:$src),
5210b57cec5SDimitry Andric      (i32 imm:$arraybase), (i32 2), (i32 imm:$mask)),
5220b57cec5SDimitry Andric      (ExportInst $src, 0, imm:$arraybase,
5230b57cec5SDimitry Andric      4095, imm:$mask, buf2inst, 0)>;
5240b57cec5SDimitry Andric// Stream3
5250b57cec5SDimitry Andric  def : R600Pat<(int_r600_store_stream_output (v4f32 R600_Reg128:$src),
5260b57cec5SDimitry Andric      (i32 imm:$arraybase), (i32 3), (i32 imm:$mask)),
5270b57cec5SDimitry Andric      (ExportInst $src, 0, imm:$arraybase,
5280b57cec5SDimitry Andric      4095, imm:$mask, buf3inst, 0)>;
5290b57cec5SDimitry Andric}
5300b57cec5SDimitry Andric
5310b57cec5SDimitry Andric// Export Instructions should not be duplicated by TailDuplication pass
5320b57cec5SDimitry Andric// (which assumes that duplicable instruction are affected by exec mask)
5330b57cec5SDimitry Andriclet usesCustomInserter = 1, isNotDuplicable = 1 in {
5340b57cec5SDimitry Andric
5350b57cec5SDimitry Andricclass ExportSwzInst : InstR600ISA<(
5360b57cec5SDimitry Andric    outs),
5370b57cec5SDimitry Andric    (ins R600_Reg128:$gpr, i32imm:$type, i32imm:$arraybase,
5380b57cec5SDimitry Andric    RSel:$sw_x, RSel:$sw_y, RSel:$sw_z, RSel:$sw_w, i32imm:$inst,
5390b57cec5SDimitry Andric    i32imm:$eop),
5400b57cec5SDimitry Andric    !strconcat("EXPORT", " $gpr.$sw_x$sw_y$sw_z$sw_w"),
5410b57cec5SDimitry Andric    []>, ExportWord0, ExportSwzWord1 {
5420b57cec5SDimitry Andric  let elem_size = 3;
5430b57cec5SDimitry Andric  let Inst{31-0} = Word0;
5440b57cec5SDimitry Andric  let Inst{63-32} = Word1;
5450b57cec5SDimitry Andric  let IsExport = 1;
5460b57cec5SDimitry Andric}
5470b57cec5SDimitry Andric
5480b57cec5SDimitry Andric} // End usesCustomInserter = 1
5490b57cec5SDimitry Andric
5500b57cec5SDimitry Andricclass ExportBufInst : InstR600ISA<(
5510b57cec5SDimitry Andric    outs),
5520b57cec5SDimitry Andric    (ins R600_Reg128:$gpr, i32imm:$type, i32imm:$arraybase,
5530b57cec5SDimitry Andric    i32imm:$arraySize, i32imm:$compMask, i32imm:$inst, i32imm:$eop),
5540b57cec5SDimitry Andric    !strconcat("EXPORT", " $gpr"),
5550b57cec5SDimitry Andric    []>, ExportWord0, ExportBufWord1 {
5560b57cec5SDimitry Andric  let elem_size = 0;
5570b57cec5SDimitry Andric  let Inst{31-0} = Word0;
5580b57cec5SDimitry Andric  let Inst{63-32} = Word1;
5590b57cec5SDimitry Andric  let IsExport = 1;
5600b57cec5SDimitry Andric}
5610b57cec5SDimitry Andric
5620b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
5630b57cec5SDimitry Andric// Control Flow Instructions
5640b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
5650b57cec5SDimitry Andric
5660b57cec5SDimitry Andric
5670b57cec5SDimitry Andricdef KCACHE : InstFlag<"printKCache">;
5680b57cec5SDimitry Andric
5690b57cec5SDimitry Andricclass ALU_CLAUSE<bits<4> inst, string OpName> : R600WrapperInst <(outs),
5700b57cec5SDimitry Andric(ins i32imm:$ADDR, i32imm:$KCACHE_BANK0, i32imm:$KCACHE_BANK1,
5710b57cec5SDimitry AndricKCACHE:$KCACHE_MODE0, KCACHE:$KCACHE_MODE1,
5720b57cec5SDimitry Andrici32imm:$KCACHE_ADDR0, i32imm:$KCACHE_ADDR1,
5730b57cec5SDimitry Andrici32imm:$COUNT, i32imm:$Enabled),
5740b57cec5SDimitry Andric!strconcat(OpName, " $COUNT, @$ADDR, "
5750b57cec5SDimitry Andric"KC0[$KCACHE_MODE0], KC1[$KCACHE_MODE1]"),
5760b57cec5SDimitry Andric[] >, CF_ALU_WORD0, CF_ALU_WORD1 {
5770b57cec5SDimitry Andric  field bits<64> Inst;
5780b57cec5SDimitry Andric
5790b57cec5SDimitry Andric  let CF_INST = inst;
5800b57cec5SDimitry Andric  let ALT_CONST = 0;
5810b57cec5SDimitry Andric  let WHOLE_QUAD_MODE = 0;
5820b57cec5SDimitry Andric  let BARRIER = 1;
5830b57cec5SDimitry Andric  let isCodeGenOnly = 1;
5840b57cec5SDimitry Andric  let UseNamedOperandTable = 1;
5850b57cec5SDimitry Andric
5860b57cec5SDimitry Andric  let Inst{31-0} = Word0;
5870b57cec5SDimitry Andric  let Inst{63-32} = Word1;
5880b57cec5SDimitry Andric}
5890b57cec5SDimitry Andric
5900b57cec5SDimitry Andricclass CF_WORD0_R600 {
5910b57cec5SDimitry Andric  field bits<32> Word0;
5920b57cec5SDimitry Andric
5930b57cec5SDimitry Andric  bits<32> ADDR;
5940b57cec5SDimitry Andric
5950b57cec5SDimitry Andric  let Word0 = ADDR;
5960b57cec5SDimitry Andric}
5970b57cec5SDimitry Andric
5980b57cec5SDimitry Andricclass CF_CLAUSE_R600 <bits<7> inst, dag ins, string AsmPrint> : R600WrapperInst <(outs),
5990b57cec5SDimitry Andricins, AsmPrint, [] >, CF_WORD0_R600, CF_WORD1_R600 {
6000b57cec5SDimitry Andric  field bits<64> Inst;
6010b57cec5SDimitry Andric  bits<4> CNT;
6020b57cec5SDimitry Andric
6030b57cec5SDimitry Andric  let CF_INST = inst;
6040b57cec5SDimitry Andric  let BARRIER = 1;
6050b57cec5SDimitry Andric  let CF_CONST = 0;
6060b57cec5SDimitry Andric  let VALID_PIXEL_MODE = 0;
6070b57cec5SDimitry Andric  let COND = 0;
6080b57cec5SDimitry Andric  let COUNT = CNT{2-0};
6090b57cec5SDimitry Andric  let CALL_COUNT = 0;
6100b57cec5SDimitry Andric  let COUNT_3 = CNT{3};
6110b57cec5SDimitry Andric  let END_OF_PROGRAM = 0;
6120b57cec5SDimitry Andric  let WHOLE_QUAD_MODE = 0;
6130b57cec5SDimitry Andric
6140b57cec5SDimitry Andric  let Inst{31-0} = Word0;
6150b57cec5SDimitry Andric  let Inst{63-32} = Word1;
6160b57cec5SDimitry Andric}
6170b57cec5SDimitry Andric
6180b57cec5SDimitry Andricclass CF_CLAUSE_EG <bits<8> inst, dag ins, string AsmPrint> : R600WrapperInst <(outs),
6190b57cec5SDimitry Andricins, AsmPrint, [] >, CF_WORD0_EG, CF_WORD1_EG {
6200b57cec5SDimitry Andric  field bits<64> Inst;
6210b57cec5SDimitry Andric
6220b57cec5SDimitry Andric  let CF_INST = inst;
6230b57cec5SDimitry Andric  let BARRIER = 1;
6240b57cec5SDimitry Andric  let JUMPTABLE_SEL = 0;
6250b57cec5SDimitry Andric  let CF_CONST = 0;
6260b57cec5SDimitry Andric  let VALID_PIXEL_MODE = 0;
6270b57cec5SDimitry Andric  let COND = 0;
6280b57cec5SDimitry Andric  let END_OF_PROGRAM = 0;
6290b57cec5SDimitry Andric
6300b57cec5SDimitry Andric  let Inst{31-0} = Word0;
6310b57cec5SDimitry Andric  let Inst{63-32} = Word1;
6320b57cec5SDimitry Andric}
6330b57cec5SDimitry Andric
6340b57cec5SDimitry Andricdef CF_ALU : ALU_CLAUSE<8, "ALU">;
6350b57cec5SDimitry Andricdef CF_ALU_PUSH_BEFORE : ALU_CLAUSE<9, "ALU_PUSH_BEFORE">;
6360b57cec5SDimitry Andricdef CF_ALU_POP_AFTER : ALU_CLAUSE<10, "ALU_POP_AFTER">;
6370b57cec5SDimitry Andricdef CF_ALU_CONTINUE : ALU_CLAUSE<13, "ALU_CONTINUE">;
6380b57cec5SDimitry Andricdef CF_ALU_BREAK : ALU_CLAUSE<14, "ALU_BREAK">;
6390b57cec5SDimitry Andricdef CF_ALU_ELSE_AFTER : ALU_CLAUSE<15, "ALU_ELSE_AFTER">;
6400b57cec5SDimitry Andric
6410b57cec5SDimitry Andricdef FETCH_CLAUSE : R600WrapperInst <(outs),
6420b57cec5SDimitry Andric(ins i32imm:$addr), "Fetch clause starting at $addr:", [] > {
6430b57cec5SDimitry Andric  field bits<8> Inst;
644bdd1243dSDimitry Andric  bits<8> addr;
645bdd1243dSDimitry Andric  let Inst = addr;
6460b57cec5SDimitry Andric  let isCodeGenOnly = 1;
6470b57cec5SDimitry Andric}
6480b57cec5SDimitry Andric
6490b57cec5SDimitry Andricdef ALU_CLAUSE : R600WrapperInst <(outs),
6500b57cec5SDimitry Andric(ins i32imm:$addr), "ALU clause starting at $addr:", [] > {
6510b57cec5SDimitry Andric  field bits<8> Inst;
652bdd1243dSDimitry Andric  bits<8> addr;
653bdd1243dSDimitry Andric  let Inst = addr;
6540b57cec5SDimitry Andric  let isCodeGenOnly = 1;
6550b57cec5SDimitry Andric}
6560b57cec5SDimitry Andric
6570b57cec5SDimitry Andricdef LITERALS : R600WrapperInst <(outs),
6580b57cec5SDimitry Andric(ins LITERAL:$literal1, LITERAL:$literal2), "$literal1, $literal2", [] > {
6590b57cec5SDimitry Andric  let isCodeGenOnly = 1;
6600b57cec5SDimitry Andric
6610b57cec5SDimitry Andric  field bits<64> Inst;
6620b57cec5SDimitry Andric  bits<32> literal1;
6630b57cec5SDimitry Andric  bits<32> literal2;
6640b57cec5SDimitry Andric
6650b57cec5SDimitry Andric  let Inst{31-0} = literal1;
6660b57cec5SDimitry Andric  let Inst{63-32} = literal2;
6670b57cec5SDimitry Andric}
6680b57cec5SDimitry Andric
6690b57cec5SDimitry Andricdef PAD : R600WrapperInst <(outs), (ins), "PAD", [] > {
6700b57cec5SDimitry Andric  field bits<64> Inst;
6710b57cec5SDimitry Andric}
6720b57cec5SDimitry Andric
6730b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
6740b57cec5SDimitry Andric// Common Instructions R600, R700, Evergreen, Cayman
6750b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
6760b57cec5SDimitry Andric
6770b57cec5SDimitry Andriclet isCodeGenOnly = 1, isPseudo = 1 in {
6780b57cec5SDimitry Andric
6790b57cec5SDimitry Andriclet Namespace = "R600", usesCustomInserter = 1  in {
6800b57cec5SDimitry Andric
6810b57cec5SDimitry Andricclass FABS <RegisterClass rc> : AMDGPUShaderInst <
6820b57cec5SDimitry Andric  (outs rc:$dst),
6830b57cec5SDimitry Andric  (ins rc:$src0),
6840b57cec5SDimitry Andric  "FABS $dst, $src0",
6850b57cec5SDimitry Andric  [(set f32:$dst, (fabs f32:$src0))]
6860b57cec5SDimitry Andric>;
6870b57cec5SDimitry Andric
6880b57cec5SDimitry Andricclass FNEG <RegisterClass rc> : AMDGPUShaderInst <
6890b57cec5SDimitry Andric  (outs rc:$dst),
6900b57cec5SDimitry Andric  (ins rc:$src0),
6910b57cec5SDimitry Andric  "FNEG $dst, $src0",
6920b57cec5SDimitry Andric  [(set f32:$dst, (fneg f32:$src0))]
6930b57cec5SDimitry Andric>;
6940b57cec5SDimitry Andric
6950b57cec5SDimitry Andric} // usesCustomInserter = 1
6960b57cec5SDimitry Andric
6970b57cec5SDimitry Andricmulticlass RegisterLoadStore <RegisterClass dstClass, Operand addrClass,
6980b57cec5SDimitry Andric                    ComplexPattern addrPat> {
6990b57cec5SDimitry Andriclet UseNamedOperandTable = 1 in {
7000b57cec5SDimitry Andric
7010b57cec5SDimitry Andric  def RegisterLoad : AMDGPUShaderInst <
7020b57cec5SDimitry Andric    (outs dstClass:$dst),
7030b57cec5SDimitry Andric    (ins addrClass:$addr, i32imm:$chan),
7040b57cec5SDimitry Andric    "RegisterLoad $dst, $addr",
7050b57cec5SDimitry Andric    [(set i32:$dst, (AMDGPUregister_load addrPat:$addr, (i32 timm:$chan)))]
7060b57cec5SDimitry Andric  > {
7070b57cec5SDimitry Andric    let isRegisterLoad = 1;
7080b57cec5SDimitry Andric  }
7090b57cec5SDimitry Andric
7100b57cec5SDimitry Andric  def RegisterStore : AMDGPUShaderInst <
7110b57cec5SDimitry Andric    (outs),
7120b57cec5SDimitry Andric    (ins dstClass:$val, addrClass:$addr, i32imm:$chan),
7130b57cec5SDimitry Andric    "RegisterStore $val, $addr",
7140b57cec5SDimitry Andric    [(AMDGPUregister_store i32:$val, addrPat:$addr, (i32 timm:$chan))]
7150b57cec5SDimitry Andric  > {
7160b57cec5SDimitry Andric    let isRegisterStore = 1;
7170b57cec5SDimitry Andric  }
7180b57cec5SDimitry Andric}
7190b57cec5SDimitry Andric}
7200b57cec5SDimitry Andric
7210b57cec5SDimitry Andric} // End isCodeGenOnly = 1, isPseudo = 1
7220b57cec5SDimitry Andric
7230b57cec5SDimitry Andric
7240b57cec5SDimitry Andricdef ADD : R600_2OP_Helper <0x0, "ADD", fadd>;
7250b57cec5SDimitry Andric// Non-IEEE MUL: 0 * anything = 0
7260b57cec5SDimitry Andricdef MUL : R600_2OP_Helper <0x1, "MUL NON-IEEE">;
7270b57cec5SDimitry Andricdef MUL_IEEE : R600_2OP_Helper <0x2, "MUL_IEEE", fmul>;
7280b57cec5SDimitry Andric// TODO: Do these actually match the regular fmin/fmax behavior?
7290b57cec5SDimitry Andricdef MAX : R600_2OP_Helper <0x3, "MAX", AMDGPUfmax_legacy>;
7300b57cec5SDimitry Andricdef MIN : R600_2OP_Helper <0x4, "MIN", AMDGPUfmin_legacy>;
7310b57cec5SDimitry Andric// According to https://msdn.microsoft.com/en-us/library/windows/desktop/cc308050%28v=vs.85%29.aspx
7320b57cec5SDimitry Andric// DX10 min/max returns the other operand if one is NaN,
7330b57cec5SDimitry Andric// this matches http://llvm.org/docs/LangRef.html#llvm-minnum-intrinsic
7340b57cec5SDimitry Andricdef MAX_DX10 : R600_2OP_Helper <0x5, "MAX_DX10", fmaxnum>;
7350b57cec5SDimitry Andricdef MIN_DX10 : R600_2OP_Helper <0x6, "MIN_DX10", fminnum>;
7360b57cec5SDimitry Andric
7370b57cec5SDimitry Andric// For the SET* instructions there is a naming conflict in TargetSelectionDAG.td,
7380b57cec5SDimitry Andric// so some of the instruction names don't match the asm string.
7390b57cec5SDimitry Andric// XXX: Use the defs in TargetSelectionDAG.td instead of intrinsics.
7400b57cec5SDimitry Andricdef SETE : R600_2OP <
7410b57cec5SDimitry Andric  0x08, "SETE",
7420b57cec5SDimitry Andric  [(set f32:$dst, (selectcc f32:$src0, f32:$src1, FP_ONE, FP_ZERO, COND_OEQ))]
7430b57cec5SDimitry Andric>;
7440b57cec5SDimitry Andric
7450b57cec5SDimitry Andricdef SGT : R600_2OP <
7460b57cec5SDimitry Andric  0x09, "SETGT",
7470b57cec5SDimitry Andric  [(set f32:$dst, (selectcc f32:$src0, f32:$src1, FP_ONE, FP_ZERO, COND_OGT))]
7480b57cec5SDimitry Andric>;
7490b57cec5SDimitry Andric
7500b57cec5SDimitry Andricdef SGE : R600_2OP <
7510b57cec5SDimitry Andric  0xA, "SETGE",
7520b57cec5SDimitry Andric  [(set f32:$dst, (selectcc f32:$src0, f32:$src1, FP_ONE, FP_ZERO, COND_OGE))]
7530b57cec5SDimitry Andric>;
7540b57cec5SDimitry Andric
7550b57cec5SDimitry Andricdef SNE : R600_2OP <
7560b57cec5SDimitry Andric  0xB, "SETNE",
7570b57cec5SDimitry Andric  [(set f32:$dst, (selectcc f32:$src0, f32:$src1, FP_ONE, FP_ZERO, COND_UNE_NE))]
7580b57cec5SDimitry Andric>;
7590b57cec5SDimitry Andric
7600b57cec5SDimitry Andricdef SETE_DX10 : R600_2OP <
7610b57cec5SDimitry Andric  0xC, "SETE_DX10",
7620b57cec5SDimitry Andric  [(set i32:$dst, (selectcc f32:$src0, f32:$src1, -1, 0, COND_OEQ))]
7630b57cec5SDimitry Andric>;
7640b57cec5SDimitry Andric
7650b57cec5SDimitry Andricdef SETGT_DX10 : R600_2OP <
7660b57cec5SDimitry Andric  0xD, "SETGT_DX10",
7670b57cec5SDimitry Andric  [(set i32:$dst, (selectcc f32:$src0, f32:$src1, -1, 0, COND_OGT))]
7680b57cec5SDimitry Andric>;
7690b57cec5SDimitry Andric
7700b57cec5SDimitry Andricdef SETGE_DX10 : R600_2OP <
7710b57cec5SDimitry Andric  0xE, "SETGE_DX10",
7720b57cec5SDimitry Andric  [(set i32:$dst, (selectcc f32:$src0, f32:$src1, -1, 0, COND_OGE))]
7730b57cec5SDimitry Andric>;
7740b57cec5SDimitry Andric
7750b57cec5SDimitry Andric// FIXME: This should probably be COND_ONE
7760b57cec5SDimitry Andricdef SETNE_DX10 : R600_2OP <
7770b57cec5SDimitry Andric  0xF, "SETNE_DX10",
7780b57cec5SDimitry Andric  [(set i32:$dst, (selectcc f32:$src0, f32:$src1, -1, 0, COND_UNE_NE))]
7790b57cec5SDimitry Andric>;
7800b57cec5SDimitry Andric
7810b57cec5SDimitry Andric// FIXME: Need combine for AMDGPUfract
7820b57cec5SDimitry Andricdef FRACT : R600_1OP_Helper <0x10, "FRACT", AMDGPUfract>;
7830b57cec5SDimitry Andricdef TRUNC : R600_1OP_Helper <0x11, "TRUNC", ftrunc>;
7840b57cec5SDimitry Andricdef CEIL : R600_1OP_Helper <0x12, "CEIL", fceil>;
7855f757f3fSDimitry Andricdef RNDNE : R600_1OP_Helper <0x13, "RNDNE", froundeven>;
7860b57cec5SDimitry Andricdef FLOOR : R600_1OP_Helper <0x14, "FLOOR", ffloor>;
7870b57cec5SDimitry Andric
7880b57cec5SDimitry Andricdef MOV : R600_1OP <0x19, "MOV", []>;
7890b57cec5SDimitry Andric
7900b57cec5SDimitry Andric
7910b57cec5SDimitry Andric// This is a hack to get rid of DUMMY_CHAIN nodes.
7920b57cec5SDimitry Andric// Most DUMMY_CHAINs should be eliminated during legalization, but undef
7930b57cec5SDimitry Andric// values can sneak in some to selection.
7940b57cec5SDimitry Andriclet isPseudo = 1, isCodeGenOnly = 1 in {
7950b57cec5SDimitry Andricdef DUMMY_CHAIN : R600WrapperInst <
7960b57cec5SDimitry Andric  (outs),
7970b57cec5SDimitry Andric  (ins),
7980b57cec5SDimitry Andric  "DUMMY_CHAIN",
7990b57cec5SDimitry Andric  [(R600dummy_chain)]
8000b57cec5SDimitry Andric>;
8010b57cec5SDimitry Andric} // end let isPseudo = 1, isCodeGenOnly = 1
8020b57cec5SDimitry Andric
8030b57cec5SDimitry Andric
8040b57cec5SDimitry Andriclet isPseudo = 1, isCodeGenOnly = 1, usesCustomInserter = 1 in {
8050b57cec5SDimitry Andric
806349cc55cSDimitry Andricclass MOV_IMM <Operand immType> : R600WrapperInst <
8070b57cec5SDimitry Andric  (outs R600_Reg32:$dst),
8080b57cec5SDimitry Andric  (ins immType:$imm),
8090b57cec5SDimitry Andric  "",
8100b57cec5SDimitry Andric  []
8110b57cec5SDimitry Andric> {
8120b57cec5SDimitry Andric  let Namespace = "R600";
8130b57cec5SDimitry Andric}
8140b57cec5SDimitry Andric
8150b57cec5SDimitry Andric} // end let isPseudo = 1, isCodeGenOnly = 1, usesCustomInserter = 1
8160b57cec5SDimitry Andric
817349cc55cSDimitry Andricdef MOV_IMM_I32 : MOV_IMM<i32imm>;
8180b57cec5SDimitry Andricdef : R600Pat <
8190b57cec5SDimitry Andric  (imm:$val),
8200b57cec5SDimitry Andric  (MOV_IMM_I32 imm:$val)
8210b57cec5SDimitry Andric>;
8220b57cec5SDimitry Andric
823349cc55cSDimitry Andricdef MOV_IMM_GLOBAL_ADDR : MOV_IMM<i32imm>;
8240b57cec5SDimitry Andricdef : R600Pat <
8250b57cec5SDimitry Andric  (AMDGPUconstdata_ptr tglobaladdr:$addr),
8260b57cec5SDimitry Andric  (MOV_IMM_GLOBAL_ADDR tglobaladdr:$addr)
8270b57cec5SDimitry Andric>;
8280b57cec5SDimitry Andric
8290b57cec5SDimitry Andric
830349cc55cSDimitry Andricdef MOV_IMM_F32 : MOV_IMM<f32imm>;
8310b57cec5SDimitry Andricdef : R600Pat <
8320b57cec5SDimitry Andric  (fpimm:$val),
8330b57cec5SDimitry Andric  (MOV_IMM_F32  fpimm:$val)
8340b57cec5SDimitry Andric>;
8350b57cec5SDimitry Andric
8360b57cec5SDimitry Andricdef PRED_SETE : R600_2OP <0x20, "PRED_SETE", []>;
8370b57cec5SDimitry Andricdef PRED_SETGT : R600_2OP <0x21, "PRED_SETGT", []>;
8380b57cec5SDimitry Andricdef PRED_SETGE : R600_2OP <0x22, "PRED_SETGE", []>;
8390b57cec5SDimitry Andricdef PRED_SETNE : R600_2OP <0x23, "PRED_SETNE", []>;
8400b57cec5SDimitry Andric
8410b57cec5SDimitry Andriclet hasSideEffects = 1 in {
8420b57cec5SDimitry Andric
8430b57cec5SDimitry Andricdef KILLGT : R600_2OP <0x2D, "KILLGT", []>;
8440b57cec5SDimitry Andric
8450b57cec5SDimitry Andric} // end hasSideEffects
8460b57cec5SDimitry Andric
8470b57cec5SDimitry Andricdef AND_INT : R600_2OP_Helper <0x30, "AND_INT", and>;
8480b57cec5SDimitry Andricdef OR_INT : R600_2OP_Helper <0x31, "OR_INT", or>;
8490b57cec5SDimitry Andricdef XOR_INT : R600_2OP_Helper <0x32, "XOR_INT", xor>;
8500b57cec5SDimitry Andricdef NOT_INT : R600_1OP_Helper <0x33, "NOT_INT", not>;
8510b57cec5SDimitry Andricdef ADD_INT : R600_2OP_Helper <0x34, "ADD_INT", add>;
8520b57cec5SDimitry Andricdef SUB_INT : R600_2OP_Helper <0x35, "SUB_INT", sub>;
8530b57cec5SDimitry Andricdef MAX_INT : R600_2OP_Helper <0x36, "MAX_INT", smax>;
8540b57cec5SDimitry Andricdef MIN_INT : R600_2OP_Helper <0x37, "MIN_INT", smin>;
8550b57cec5SDimitry Andricdef MAX_UINT : R600_2OP_Helper <0x38, "MAX_UINT", umax>;
8560b57cec5SDimitry Andricdef MIN_UINT : R600_2OP_Helper <0x39, "MIN_UINT", umin>;
8570b57cec5SDimitry Andric
8580b57cec5SDimitry Andricdef SETE_INT : R600_2OP <
8590b57cec5SDimitry Andric  0x3A, "SETE_INT",
8600b57cec5SDimitry Andric  [(set i32:$dst, (selectcc i32:$src0, i32:$src1, -1, 0, SETEQ))]
8610b57cec5SDimitry Andric>;
8620b57cec5SDimitry Andric
8630b57cec5SDimitry Andricdef SETGT_INT : R600_2OP <
8640b57cec5SDimitry Andric  0x3B, "SETGT_INT",
8650b57cec5SDimitry Andric  [(set i32:$dst, (selectcc i32:$src0, i32:$src1, -1, 0, SETGT))]
8660b57cec5SDimitry Andric>;
8670b57cec5SDimitry Andric
8680b57cec5SDimitry Andricdef SETGE_INT : R600_2OP <
8690b57cec5SDimitry Andric  0x3C, "SETGE_INT",
8700b57cec5SDimitry Andric  [(set i32:$dst, (selectcc i32:$src0, i32:$src1, -1, 0, SETGE))]
8710b57cec5SDimitry Andric>;
8720b57cec5SDimitry Andric
8730b57cec5SDimitry Andricdef SETNE_INT : R600_2OP <
8740b57cec5SDimitry Andric  0x3D, "SETNE_INT",
8750b57cec5SDimitry Andric  [(set i32:$dst, (selectcc i32:$src0, i32:$src1, -1, 0, SETNE))]
8760b57cec5SDimitry Andric>;
8770b57cec5SDimitry Andric
8780b57cec5SDimitry Andricdef SETGT_UINT : R600_2OP <
8790b57cec5SDimitry Andric  0x3E, "SETGT_UINT",
8800b57cec5SDimitry Andric  [(set i32:$dst, (selectcc i32:$src0, i32:$src1, -1, 0, SETUGT))]
8810b57cec5SDimitry Andric>;
8820b57cec5SDimitry Andric
8830b57cec5SDimitry Andricdef SETGE_UINT : R600_2OP <
8840b57cec5SDimitry Andric  0x3F, "SETGE_UINT",
8850b57cec5SDimitry Andric  [(set i32:$dst, (selectcc i32:$src0, i32:$src1, -1, 0, SETUGE))]
8860b57cec5SDimitry Andric>;
8870b57cec5SDimitry Andric
8880b57cec5SDimitry Andricdef PRED_SETE_INT : R600_2OP <0x42, "PRED_SETE_INT", []>;
8890b57cec5SDimitry Andricdef PRED_SETGT_INT : R600_2OP <0x43, "PRED_SETGE_INT", []>;
8900b57cec5SDimitry Andricdef PRED_SETGE_INT : R600_2OP <0x44, "PRED_SETGE_INT", []>;
8910b57cec5SDimitry Andricdef PRED_SETNE_INT : R600_2OP <0x45, "PRED_SETNE_INT", []>;
8920b57cec5SDimitry Andric
8930b57cec5SDimitry Andricdef CNDE_INT : R600_3OP <
8940b57cec5SDimitry Andric  0x1C, "CNDE_INT",
8950b57cec5SDimitry Andric  [(set i32:$dst, (selectcc i32:$src0, 0, i32:$src1, i32:$src2, COND_EQ))]
8960b57cec5SDimitry Andric>;
8970b57cec5SDimitry Andric
8980b57cec5SDimitry Andricdef CNDGE_INT : R600_3OP <
8990b57cec5SDimitry Andric  0x1E, "CNDGE_INT",
9000b57cec5SDimitry Andric  [(set i32:$dst, (selectcc i32:$src0, 0, i32:$src1, i32:$src2, COND_SGE))]
9010b57cec5SDimitry Andric>;
9020b57cec5SDimitry Andric
9030b57cec5SDimitry Andricdef CNDGT_INT : R600_3OP <
9040b57cec5SDimitry Andric  0x1D, "CNDGT_INT",
9050b57cec5SDimitry Andric  [(set i32:$dst, (selectcc i32:$src0, 0, i32:$src1, i32:$src2, COND_SGT))]
9060b57cec5SDimitry Andric>;
9070b57cec5SDimitry Andric
9080b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
9090b57cec5SDimitry Andric// Texture instructions
9100b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
9110b57cec5SDimitry Andric
9120b57cec5SDimitry Andriclet mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
9130b57cec5SDimitry Andric
9140b57cec5SDimitry Andricclass R600_TEX <bits<11> inst, string opName> :
9150b57cec5SDimitry Andric  InstR600 <(outs R600_Reg128:$DST_GPR),
9160b57cec5SDimitry Andric          (ins R600_Reg128:$SRC_GPR,
9170b57cec5SDimitry Andric          RSel:$srcx, RSel:$srcy, RSel:$srcz, RSel:$srcw,
9180b57cec5SDimitry Andric          i32imm:$offsetx, i32imm:$offsety, i32imm:$offsetz,
9190b57cec5SDimitry Andric          RSel:$DST_SEL_X, RSel:$DST_SEL_Y, RSel:$DST_SEL_Z, RSel:$DST_SEL_W,
9200b57cec5SDimitry Andric          i32imm:$RESOURCE_ID, i32imm:$SAMPLER_ID,
9210b57cec5SDimitry Andric          CT:$COORD_TYPE_X, CT:$COORD_TYPE_Y, CT:$COORD_TYPE_Z,
9220b57cec5SDimitry Andric          CT:$COORD_TYPE_W),
9230b57cec5SDimitry Andric          !strconcat("  ", opName,
9240b57cec5SDimitry Andric          " $DST_GPR.$DST_SEL_X$DST_SEL_Y$DST_SEL_Z$DST_SEL_W, "
9250b57cec5SDimitry Andric          "$SRC_GPR.$srcx$srcy$srcz$srcw "
9260b57cec5SDimitry Andric          "RID:$RESOURCE_ID SID:$SAMPLER_ID "
9270b57cec5SDimitry Andric          "CT:$COORD_TYPE_X$COORD_TYPE_Y$COORD_TYPE_Z$COORD_TYPE_W"),
9280b57cec5SDimitry Andric          [],
9290b57cec5SDimitry Andric          NullALU>, TEX_WORD0, TEX_WORD1, TEX_WORD2 {
9300b57cec5SDimitry Andric  let Inst{31-0} = Word0;
9310b57cec5SDimitry Andric  let Inst{63-32} = Word1;
9320b57cec5SDimitry Andric
9330b57cec5SDimitry Andric  let TEX_INST = inst{4-0};
9340b57cec5SDimitry Andric  let SRC_REL = 0;
9350b57cec5SDimitry Andric  let DST_REL = 0;
9360b57cec5SDimitry Andric  let LOD_BIAS = 0;
9370b57cec5SDimitry Andric
9380b57cec5SDimitry Andric  let INST_MOD = 0;
9390b57cec5SDimitry Andric  let FETCH_WHOLE_QUAD = 0;
9400b57cec5SDimitry Andric  let ALT_CONST = 0;
9410b57cec5SDimitry Andric  let SAMPLER_INDEX_MODE = 0;
9420b57cec5SDimitry Andric  let RESOURCE_INDEX_MODE = 0;
9430b57cec5SDimitry Andric
9440b57cec5SDimitry Andric  let TEXInst = 1;
9450b57cec5SDimitry Andric}
9460b57cec5SDimitry Andric
9470b57cec5SDimitry Andric} // End mayLoad = 0, mayStore = 0, hasSideEffects = 0
9480b57cec5SDimitry Andric
9490b57cec5SDimitry Andric
9500b57cec5SDimitry Andric
9510b57cec5SDimitry Andricdef TEX_SAMPLE : R600_TEX <0x10, "TEX_SAMPLE">;
9520b57cec5SDimitry Andricdef TEX_SAMPLE_C : R600_TEX <0x18, "TEX_SAMPLE_C">;
9530b57cec5SDimitry Andricdef TEX_SAMPLE_L : R600_TEX <0x11, "TEX_SAMPLE_L">;
9540b57cec5SDimitry Andricdef TEX_SAMPLE_C_L : R600_TEX <0x19, "TEX_SAMPLE_C_L">;
9550b57cec5SDimitry Andricdef TEX_SAMPLE_LB : R600_TEX <0x12, "TEX_SAMPLE_LB">;
9560b57cec5SDimitry Andricdef TEX_SAMPLE_C_LB : R600_TEX <0x1A, "TEX_SAMPLE_C_LB">;
9570b57cec5SDimitry Andricdef TEX_LD : R600_TEX <0x03, "TEX_LD">;
9580b57cec5SDimitry Andricdef TEX_LDPTR : R600_TEX <0x03, "TEX_LDPTR"> {
9590b57cec5SDimitry Andric  let INST_MOD = 1;
9600b57cec5SDimitry Andric}
9610b57cec5SDimitry Andricdef TEX_GET_TEXTURE_RESINFO : R600_TEX <0x04, "TEX_GET_TEXTURE_RESINFO">;
9620b57cec5SDimitry Andricdef TEX_GET_GRADIENTS_H : R600_TEX <0x07, "TEX_GET_GRADIENTS_H">;
9630b57cec5SDimitry Andricdef TEX_GET_GRADIENTS_V : R600_TEX <0x08, "TEX_GET_GRADIENTS_V">;
9640b57cec5SDimitry Andricdef TEX_SET_GRADIENTS_H : R600_TEX <0x0B, "TEX_SET_GRADIENTS_H">;
9650b57cec5SDimitry Andricdef TEX_SET_GRADIENTS_V : R600_TEX <0x0C, "TEX_SET_GRADIENTS_V">;
9660b57cec5SDimitry Andricdef TEX_SAMPLE_G : R600_TEX <0x14, "TEX_SAMPLE_G">;
9670b57cec5SDimitry Andricdef TEX_SAMPLE_C_G : R600_TEX <0x1C, "TEX_SAMPLE_C_G">;
9680b57cec5SDimitry Andric
9690b57cec5SDimitry Andricdefm : TexPattern<0, TEX_SAMPLE>;
9700b57cec5SDimitry Andricdefm : TexPattern<1, TEX_SAMPLE_C>;
9710b57cec5SDimitry Andricdefm : TexPattern<2, TEX_SAMPLE_L>;
9720b57cec5SDimitry Andricdefm : TexPattern<3, TEX_SAMPLE_C_L>;
9730b57cec5SDimitry Andricdefm : TexPattern<4, TEX_SAMPLE_LB>;
9740b57cec5SDimitry Andricdefm : TexPattern<5, TEX_SAMPLE_C_LB>;
9750b57cec5SDimitry Andricdefm : TexPattern<6, TEX_LD, v4i32>;
9760b57cec5SDimitry Andricdefm : TexPattern<7, TEX_GET_TEXTURE_RESINFO, v4i32>;
9770b57cec5SDimitry Andricdefm : TexPattern<8, TEX_GET_GRADIENTS_H>;
9780b57cec5SDimitry Andricdefm : TexPattern<9, TEX_GET_GRADIENTS_V>;
9790b57cec5SDimitry Andricdefm : TexPattern<10, TEX_LDPTR, v4i32>;
9800b57cec5SDimitry Andric
9810b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
9820b57cec5SDimitry Andric// Helper classes for common instructions
9830b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
9840b57cec5SDimitry Andric
9850b57cec5SDimitry Andricclass MUL_LIT_Common <bits<5> inst> : R600_3OP <
9860b57cec5SDimitry Andric  inst, "MUL_LIT",
9870b57cec5SDimitry Andric  []
9880b57cec5SDimitry Andric>;
9890b57cec5SDimitry Andric
9900b57cec5SDimitry Andricclass MULADD_Common <bits<5> inst> : R600_3OP <
9910b57cec5SDimitry Andric  inst, "MULADD",
9920b57cec5SDimitry Andric  []
9930b57cec5SDimitry Andric>;
9940b57cec5SDimitry Andric
9950b57cec5SDimitry Andricclass MULADD_IEEE_Common <bits<5> inst> : R600_3OP <
9960b57cec5SDimitry Andric  inst, "MULADD_IEEE",
9975ffd83dbSDimitry Andric  [(set f32:$dst, (any_fmad f32:$src0, f32:$src1, f32:$src2))]
9980b57cec5SDimitry Andric>;
9990b57cec5SDimitry Andric
10000b57cec5SDimitry Andricclass FMA_Common <bits<5> inst> : R600_3OP <
10010b57cec5SDimitry Andric  inst, "FMA",
10020b57cec5SDimitry Andric  [(set f32:$dst, (fma f32:$src0, f32:$src1, f32:$src2))], VecALU
10030b57cec5SDimitry Andric>
10040b57cec5SDimitry Andric{
10050b57cec5SDimitry Andric  let OtherPredicates = [FMA];
10060b57cec5SDimitry Andric}
10070b57cec5SDimitry Andric
10080b57cec5SDimitry Andricclass CNDE_Common <bits<5> inst> : R600_3OP <
10090b57cec5SDimitry Andric  inst, "CNDE",
10100b57cec5SDimitry Andric  [(set f32:$dst, (selectcc f32:$src0, FP_ZERO, f32:$src1, f32:$src2, COND_OEQ))]
10110b57cec5SDimitry Andric>;
10120b57cec5SDimitry Andric
10130b57cec5SDimitry Andricclass CNDGT_Common <bits<5> inst> : R600_3OP <
10140b57cec5SDimitry Andric  inst, "CNDGT",
10150b57cec5SDimitry Andric  [(set f32:$dst, (selectcc f32:$src0, FP_ZERO, f32:$src1, f32:$src2, COND_OGT))]
10160b57cec5SDimitry Andric> {
10170b57cec5SDimitry Andric  let Itinerary = VecALU;
10180b57cec5SDimitry Andric}
10190b57cec5SDimitry Andric
10200b57cec5SDimitry Andricclass CNDGE_Common <bits<5> inst> : R600_3OP <
10210b57cec5SDimitry Andric  inst, "CNDGE",
10220b57cec5SDimitry Andric  [(set f32:$dst, (selectcc f32:$src0, FP_ZERO, f32:$src1, f32:$src2, COND_OGE))]
10230b57cec5SDimitry Andric> {
10240b57cec5SDimitry Andric  let Itinerary = VecALU;
10250b57cec5SDimitry Andric}
10260b57cec5SDimitry Andric
10270b57cec5SDimitry Andric
10280b57cec5SDimitry Andriclet isCodeGenOnly = 1, isPseudo = 1, Namespace = "R600"  in {
10290b57cec5SDimitry Andricclass R600_VEC2OP<list<dag> pattern> : InstR600 <(outs R600_Reg32:$dst), (ins
10300b57cec5SDimitry Andric// Slot X
10310b57cec5SDimitry Andric   UEM:$update_exec_mask_X, UP:$update_pred_X, WRITE:$write_X,
10320b57cec5SDimitry Andric   OMOD:$omod_X, REL:$dst_rel_X, CLAMP:$clamp_X,
10330b57cec5SDimitry Andric   R600_TReg32_X:$src0_X, NEG:$src0_neg_X, REL:$src0_rel_X, ABS:$src0_abs_X, SEL:$src0_sel_X,
10340b57cec5SDimitry Andric   R600_TReg32_X:$src1_X, NEG:$src1_neg_X, REL:$src1_rel_X, ABS:$src1_abs_X, SEL:$src1_sel_X,
10350b57cec5SDimitry Andric   R600_Pred:$pred_sel_X,
10360b57cec5SDimitry Andric// Slot Y
10370b57cec5SDimitry Andric   UEM:$update_exec_mask_Y, UP:$update_pred_Y, WRITE:$write_Y,
10380b57cec5SDimitry Andric   OMOD:$omod_Y, REL:$dst_rel_Y, CLAMP:$clamp_Y,
10390b57cec5SDimitry Andric   R600_TReg32_Y:$src0_Y, NEG:$src0_neg_Y, REL:$src0_rel_Y, ABS:$src0_abs_Y, SEL:$src0_sel_Y,
10400b57cec5SDimitry Andric   R600_TReg32_Y:$src1_Y, NEG:$src1_neg_Y, REL:$src1_rel_Y, ABS:$src1_abs_Y, SEL:$src1_sel_Y,
10410b57cec5SDimitry Andric   R600_Pred:$pred_sel_Y,
10420b57cec5SDimitry Andric// Slot Z
10430b57cec5SDimitry Andric   UEM:$update_exec_mask_Z, UP:$update_pred_Z, WRITE:$write_Z,
10440b57cec5SDimitry Andric   OMOD:$omod_Z, REL:$dst_rel_Z, CLAMP:$clamp_Z,
10450b57cec5SDimitry Andric   R600_TReg32_Z:$src0_Z, NEG:$src0_neg_Z, REL:$src0_rel_Z, ABS:$src0_abs_Z, SEL:$src0_sel_Z,
10460b57cec5SDimitry Andric   R600_TReg32_Z:$src1_Z, NEG:$src1_neg_Z, REL:$src1_rel_Z, ABS:$src1_abs_Z, SEL:$src1_sel_Z,
10470b57cec5SDimitry Andric   R600_Pred:$pred_sel_Z,
10480b57cec5SDimitry Andric// Slot W
10490b57cec5SDimitry Andric   UEM:$update_exec_mask_W, UP:$update_pred_W, WRITE:$write_W,
10500b57cec5SDimitry Andric   OMOD:$omod_W, REL:$dst_rel_W, CLAMP:$clamp_W,
10510b57cec5SDimitry Andric   R600_TReg32_W:$src0_W, NEG:$src0_neg_W, REL:$src0_rel_W, ABS:$src0_abs_W, SEL:$src0_sel_W,
10520b57cec5SDimitry Andric   R600_TReg32_W:$src1_W, NEG:$src1_neg_W, REL:$src1_rel_W, ABS:$src1_abs_W, SEL:$src1_sel_W,
10530b57cec5SDimitry Andric   R600_Pred:$pred_sel_W,
10540b57cec5SDimitry Andric   LITERAL:$literal0, LITERAL:$literal1),
10550b57cec5SDimitry Andric  "",
10560b57cec5SDimitry Andric  pattern,
10570b57cec5SDimitry Andric  AnyALU> {
10580b57cec5SDimitry Andric
10590b57cec5SDimitry Andric  let UseNamedOperandTable = 1;
10600b57cec5SDimitry Andric
10610b57cec5SDimitry Andric}
10620b57cec5SDimitry Andric}
10630b57cec5SDimitry Andric
10640b57cec5SDimitry Andricdef DOT_4 : R600_VEC2OP<[(set R600_Reg32:$dst, (DOT4
10650b57cec5SDimitry Andric  R600_TReg32_X:$src0_X, R600_TReg32_X:$src1_X,
10660b57cec5SDimitry Andric  R600_TReg32_Y:$src0_Y, R600_TReg32_Y:$src1_Y,
10670b57cec5SDimitry Andric  R600_TReg32_Z:$src0_Z, R600_TReg32_Z:$src1_Z,
10680b57cec5SDimitry Andric  R600_TReg32_W:$src0_W, R600_TReg32_W:$src1_W))]>;
10690b57cec5SDimitry Andric
10700b57cec5SDimitry Andric
10710b57cec5SDimitry Andricclass DOT4_Common <bits<11> inst> : R600_2OP <inst, "DOT4", []>;
10720b57cec5SDimitry Andric
10730b57cec5SDimitry Andric
10740b57cec5SDimitry Andriclet mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
10750b57cec5SDimitry Andricmulticlass CUBE_Common <bits<11> inst> {
10760b57cec5SDimitry Andric
10770b57cec5SDimitry Andric  def _pseudo : InstR600 <
10780b57cec5SDimitry Andric    (outs R600_Reg128:$dst),
10790b57cec5SDimitry Andric    (ins R600_Reg128:$src0),
10800b57cec5SDimitry Andric    "CUBE $dst $src0",
10810b57cec5SDimitry Andric    [(set v4f32:$dst, (int_r600_cube v4f32:$src0))],
10820b57cec5SDimitry Andric    VecALU
10830b57cec5SDimitry Andric  > {
10840b57cec5SDimitry Andric    let isPseudo = 1;
10850b57cec5SDimitry Andric    let UseNamedOperandTable = 1;
10860b57cec5SDimitry Andric  }
10870b57cec5SDimitry Andric
10880b57cec5SDimitry Andric  def _real : R600_2OP <inst, "CUBE", []>;
10890b57cec5SDimitry Andric}
10900b57cec5SDimitry Andric} // End mayLoad = 0, mayStore = 0, hasSideEffects = 0
10910b57cec5SDimitry Andric
10920b57cec5SDimitry Andricclass EXP_IEEE_Common <bits<11> inst> : R600_1OP_Helper <
109306c3fb27SDimitry Andric  inst, "EXP_IEEE", AMDGPUexp
10940b57cec5SDimitry Andric> {
10950b57cec5SDimitry Andric  let Itinerary = TransALU;
10960b57cec5SDimitry Andric}
10970b57cec5SDimitry Andric
10980b57cec5SDimitry Andricclass FLT_TO_INT_Common <bits<11> inst> : R600_1OP_Helper <
10990b57cec5SDimitry Andric  inst, "FLT_TO_INT", fp_to_sint
11000b57cec5SDimitry Andric> {
11010b57cec5SDimitry Andric  let Itinerary = TransALU;
11020b57cec5SDimitry Andric}
11030b57cec5SDimitry Andric
11040b57cec5SDimitry Andricclass INT_TO_FLT_Common <bits<11> inst> : R600_1OP_Helper <
11050b57cec5SDimitry Andric  inst, "INT_TO_FLT", sint_to_fp
11060b57cec5SDimitry Andric> {
11070b57cec5SDimitry Andric  let Itinerary = TransALU;
11080b57cec5SDimitry Andric}
11090b57cec5SDimitry Andric
11100b57cec5SDimitry Andricclass FLT_TO_UINT_Common <bits<11> inst> : R600_1OP_Helper <
11110b57cec5SDimitry Andric  inst, "FLT_TO_UINT", fp_to_uint
11120b57cec5SDimitry Andric> {
11130b57cec5SDimitry Andric  let Itinerary = TransALU;
11140b57cec5SDimitry Andric}
11150b57cec5SDimitry Andric
11160b57cec5SDimitry Andricclass UINT_TO_FLT_Common <bits<11> inst> : R600_1OP_Helper <
11170b57cec5SDimitry Andric  inst, "UINT_TO_FLT", uint_to_fp
11180b57cec5SDimitry Andric> {
11190b57cec5SDimitry Andric  let Itinerary = TransALU;
11200b57cec5SDimitry Andric}
11210b57cec5SDimitry Andric
11220b57cec5SDimitry Andricclass LOG_CLAMPED_Common <bits<11> inst> : R600_1OP <
11230b57cec5SDimitry Andric  inst, "LOG_CLAMPED", []
11240b57cec5SDimitry Andric>;
11250b57cec5SDimitry Andric
11260b57cec5SDimitry Andricclass LOG_IEEE_Common <bits<11> inst> : R600_1OP_Helper <
112706c3fb27SDimitry Andric  inst, "LOG_IEEE", AMDGPUlog
11280b57cec5SDimitry Andric> {
11290b57cec5SDimitry Andric  let Itinerary = TransALU;
11300b57cec5SDimitry Andric}
11310b57cec5SDimitry Andric
11320b57cec5SDimitry Andricclass LSHL_Common <bits<11> inst> : R600_2OP_Helper <inst, "LSHL", shl>;
11330b57cec5SDimitry Andricclass LSHR_Common <bits<11> inst> : R600_2OP_Helper <inst, "LSHR", srl>;
11340b57cec5SDimitry Andricclass ASHR_Common <bits<11> inst> : R600_2OP_Helper <inst, "ASHR", sra>;
11350b57cec5SDimitry Andricclass MULHI_INT_Common <bits<11> inst> : R600_2OP_Helper <
11360b57cec5SDimitry Andric  inst, "MULHI_INT", mulhs> {
11370b57cec5SDimitry Andric  let Itinerary = TransALU;
11380b57cec5SDimitry Andric}
11390b57cec5SDimitry Andric
11400b57cec5SDimitry Andricclass MULHI_INT24_Common <bits<11> inst> : R600_2OP_Helper <
11410b57cec5SDimitry Andric  inst, "MULHI_INT24", AMDGPUmulhi_i24> {
11420b57cec5SDimitry Andric  let Itinerary = VecALU;
11430b57cec5SDimitry Andric}
11440b57cec5SDimitry Andric
11450b57cec5SDimitry Andricclass MULHI_UINT_Common <bits<11> inst> : R600_2OP_Helper <
11460b57cec5SDimitry Andric  inst, "MULHI", mulhu> {
11470b57cec5SDimitry Andric  let Itinerary = TransALU;
11480b57cec5SDimitry Andric}
11490b57cec5SDimitry Andric
11500b57cec5SDimitry Andricclass MULHI_UINT24_Common <bits<11> inst> : R600_2OP_Helper <
11510b57cec5SDimitry Andric  inst, "MULHI_UINT24", AMDGPUmulhi_u24> {
11520b57cec5SDimitry Andric  let Itinerary = VecALU;
11530b57cec5SDimitry Andric}
11540b57cec5SDimitry Andric
11550b57cec5SDimitry Andricclass MULLO_INT_Common <bits<11> inst> : R600_2OP_Helper <
11560b57cec5SDimitry Andric  inst, "MULLO_INT", mul> {
11570b57cec5SDimitry Andric  let Itinerary = TransALU;
11580b57cec5SDimitry Andric}
11590b57cec5SDimitry Andricclass MULLO_UINT_Common <bits<11> inst> : R600_2OP <inst, "MULLO_UINT", []> {
11600b57cec5SDimitry Andric  let Itinerary = TransALU;
11610b57cec5SDimitry Andric}
11620b57cec5SDimitry Andric
11630b57cec5SDimitry Andricclass RECIP_CLAMPED_Common <bits<11> inst> : R600_1OP <
11640b57cec5SDimitry Andric  inst, "RECIP_CLAMPED", []
11650b57cec5SDimitry Andric> {
11660b57cec5SDimitry Andric  let Itinerary = TransALU;
11670b57cec5SDimitry Andric}
11680b57cec5SDimitry Andric
11690b57cec5SDimitry Andricclass RECIP_IEEE_Common <bits<11> inst> : R600_1OP <
11700b57cec5SDimitry Andric  inst, "RECIP_IEEE", [(set f32:$dst, (AMDGPUrcp f32:$src0))]
11710b57cec5SDimitry Andric> {
11720b57cec5SDimitry Andric  let Itinerary = TransALU;
11730b57cec5SDimitry Andric}
11740b57cec5SDimitry Andric
11750b57cec5SDimitry Andricclass RECIP_UINT_Common <bits<11> inst> : R600_1OP_Helper <
11760b57cec5SDimitry Andric  inst, "RECIP_UINT", AMDGPUurecip
11770b57cec5SDimitry Andric> {
11780b57cec5SDimitry Andric  let Itinerary = TransALU;
11790b57cec5SDimitry Andric}
11800b57cec5SDimitry Andric
11810b57cec5SDimitry Andric// Clamped to maximum.
11820b57cec5SDimitry Andricclass RECIPSQRT_CLAMPED_Common <bits<11> inst> : R600_1OP_Helper <
11830b57cec5SDimitry Andric  inst, "RECIPSQRT_CLAMPED", AMDGPUrsq_clamp
11840b57cec5SDimitry Andric> {
11850b57cec5SDimitry Andric  let Itinerary = TransALU;
11860b57cec5SDimitry Andric}
11870b57cec5SDimitry Andric
11880b57cec5SDimitry Andricclass RECIPSQRT_IEEE_Common <bits<11> inst> : R600_1OP_Helper <
11890b57cec5SDimitry Andric  inst, "RECIPSQRT_IEEE", AMDGPUrsq> {
11900b57cec5SDimitry Andric  let Itinerary = TransALU;
11910b57cec5SDimitry Andric}
11920b57cec5SDimitry Andric
11930b57cec5SDimitry Andric// TODO: There is also RECIPSQRT_FF which clamps to zero.
11940b57cec5SDimitry Andric
11950b57cec5SDimitry Andricclass SIN_Common <bits<11> inst> : R600_1OP <
11960b57cec5SDimitry Andric  inst, "SIN", [(set f32:$dst, (SIN_HW f32:$src0))]>{
11970b57cec5SDimitry Andric  let Trig = 1;
11980b57cec5SDimitry Andric  let Itinerary = TransALU;
11990b57cec5SDimitry Andric}
12000b57cec5SDimitry Andric
12010b57cec5SDimitry Andricclass COS_Common <bits<11> inst> : R600_1OP <
12020b57cec5SDimitry Andric  inst, "COS", [(set f32:$dst, (COS_HW f32:$src0))]> {
12030b57cec5SDimitry Andric  let Trig = 1;
12040b57cec5SDimitry Andric  let Itinerary = TransALU;
12050b57cec5SDimitry Andric}
12060b57cec5SDimitry Andric
12070b57cec5SDimitry Andricdef FABS_R600 : FABS<R600_Reg32>;
12080b57cec5SDimitry Andricdef FNEG_R600 : FNEG<R600_Reg32>;
12090b57cec5SDimitry Andric
12100b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
12110b57cec5SDimitry Andric// Helper patterns for complex intrinsics
12120b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
12130b57cec5SDimitry Andric
12140b57cec5SDimitry Andric// FIXME: Should be predicated on unsafe fp math.
12150b57cec5SDimitry Andricmulticlass DIV_Common <InstR600 recip_ieee> {
12160b57cec5SDimitry Andricdef : R600Pat<
12170b57cec5SDimitry Andric  (fdiv f32:$src0, f32:$src1),
12180b57cec5SDimitry Andric  (MUL_IEEE $src0, (recip_ieee $src1))
12190b57cec5SDimitry Andric>;
12200b57cec5SDimitry Andric
12210b57cec5SDimitry Andricdef : RcpPat<recip_ieee, f32>;
12220b57cec5SDimitry Andric}
12230b57cec5SDimitry Andric
122413138422SDimitry Andricclass SqrtPat<Instruction RsqInst, Instruction RecipInst> : R600Pat <
122513138422SDimitry Andric  (fsqrt f32:$src),
122613138422SDimitry Andric  (RecipInst (RsqInst $src))
122713138422SDimitry Andric>;
122813138422SDimitry Andric
12290b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
12300b57cec5SDimitry Andric// R600 / R700 Instructions
12310b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
12320b57cec5SDimitry Andric
12330b57cec5SDimitry Andriclet Predicates = [isR600] in {
12340b57cec5SDimitry Andric
12350b57cec5SDimitry Andric  def MUL_LIT_r600 : MUL_LIT_Common<0x0C>;
12360b57cec5SDimitry Andric  def MULADD_r600 : MULADD_Common<0x10>;
12370b57cec5SDimitry Andric  def MULADD_IEEE_r600 : MULADD_IEEE_Common<0x14>;
12380b57cec5SDimitry Andric  def CNDE_r600 : CNDE_Common<0x18>;
12390b57cec5SDimitry Andric  def CNDGT_r600 : CNDGT_Common<0x19>;
12400b57cec5SDimitry Andric  def CNDGE_r600 : CNDGE_Common<0x1A>;
12410b57cec5SDimitry Andric  def DOT4_r600 : DOT4_Common<0x50>;
12420b57cec5SDimitry Andric  defm CUBE_r600 : CUBE_Common<0x52>;
12430b57cec5SDimitry Andric  def EXP_IEEE_r600 : EXP_IEEE_Common<0x61>;
12440b57cec5SDimitry Andric  def LOG_CLAMPED_r600 : LOG_CLAMPED_Common<0x62>;
12450b57cec5SDimitry Andric  def LOG_IEEE_r600 : LOG_IEEE_Common<0x63>;
12460b57cec5SDimitry Andric  def RECIP_CLAMPED_r600 : RECIP_CLAMPED_Common<0x64>;
12470b57cec5SDimitry Andric  def RECIP_IEEE_r600 : RECIP_IEEE_Common<0x66>;
12480b57cec5SDimitry Andric  def RECIPSQRT_CLAMPED_r600 : RECIPSQRT_CLAMPED_Common<0x67>;
12490b57cec5SDimitry Andric  def RECIPSQRT_IEEE_r600 : RECIPSQRT_IEEE_Common<0x69>;
12500b57cec5SDimitry Andric  def FLT_TO_INT_r600 : FLT_TO_INT_Common<0x6b>;
12510b57cec5SDimitry Andric  def INT_TO_FLT_r600 : INT_TO_FLT_Common<0x6c>;
12520b57cec5SDimitry Andric  def FLT_TO_UINT_r600 : FLT_TO_UINT_Common<0x79>;
12530b57cec5SDimitry Andric  def UINT_TO_FLT_r600 : UINT_TO_FLT_Common<0x6d>;
12540b57cec5SDimitry Andric  def SIN_r600 : SIN_Common<0x6E>;
12550b57cec5SDimitry Andric  def COS_r600 : COS_Common<0x6F>;
12560b57cec5SDimitry Andric  def ASHR_r600 : ASHR_Common<0x70>;
12570b57cec5SDimitry Andric  def LSHR_r600 : LSHR_Common<0x71>;
12580b57cec5SDimitry Andric  def LSHL_r600 : LSHL_Common<0x72>;
12590b57cec5SDimitry Andric  def MULLO_INT_r600 : MULLO_INT_Common<0x73>;
12600b57cec5SDimitry Andric  def MULHI_INT_r600 : MULHI_INT_Common<0x74>;
12610b57cec5SDimitry Andric  def MULLO_UINT_r600 : MULLO_UINT_Common<0x75>;
12620b57cec5SDimitry Andric  def MULHI_UINT_r600 : MULHI_UINT_Common<0x76>;
12630b57cec5SDimitry Andric  def RECIP_UINT_r600 : RECIP_UINT_Common <0x78>;
12640b57cec5SDimitry Andric
12650b57cec5SDimitry Andric  defm DIV_r600 : DIV_Common<RECIP_IEEE_r600>;
12660b57cec5SDimitry Andric  def : POW_Common <LOG_IEEE_r600, EXP_IEEE_r600, MUL>;
12670b57cec5SDimitry Andric
126813138422SDimitry Andric  def : SqrtPat<RECIPSQRT_IEEE_r600, RECIP_IEEE_r600>;
12690b57cec5SDimitry Andric
12700b57cec5SDimitry Andric  def R600_ExportSwz : ExportSwzInst {
12710b57cec5SDimitry Andric    let Word1{20-17} = 0; // BURST_COUNT
12720b57cec5SDimitry Andric    let Word1{21} = eop;
12730b57cec5SDimitry Andric    let Word1{22} = 0; // VALID_PIXEL_MODE
12740b57cec5SDimitry Andric    let Word1{30-23} = inst;
12750b57cec5SDimitry Andric    let Word1{31} = 1; // BARRIER
12760b57cec5SDimitry Andric  }
12770b57cec5SDimitry Andric  defm : ExportPattern<R600_ExportSwz, 39>;
12780b57cec5SDimitry Andric
12790b57cec5SDimitry Andric  def R600_ExportBuf : ExportBufInst {
12800b57cec5SDimitry Andric    let Word1{20-17} = 0; // BURST_COUNT
12810b57cec5SDimitry Andric    let Word1{21} = eop;
12820b57cec5SDimitry Andric    let Word1{22} = 0; // VALID_PIXEL_MODE
12830b57cec5SDimitry Andric    let Word1{30-23} = inst;
12840b57cec5SDimitry Andric    let Word1{31} = 1; // BARRIER
12850b57cec5SDimitry Andric  }
12860b57cec5SDimitry Andric  defm : SteamOutputExportPattern<R600_ExportBuf, 0x20, 0x21, 0x22, 0x23>;
12870b57cec5SDimitry Andric
12880b57cec5SDimitry Andric  def CF_TC_R600 : CF_CLAUSE_R600<1, (ins i32imm:$ADDR, i32imm:$CNT),
12890b57cec5SDimitry Andric  "TEX $CNT @$ADDR"> {
12900b57cec5SDimitry Andric    let POP_COUNT = 0;
12910b57cec5SDimitry Andric  }
12920b57cec5SDimitry Andric  def CF_VC_R600 : CF_CLAUSE_R600<2, (ins i32imm:$ADDR, i32imm:$CNT),
12930b57cec5SDimitry Andric  "VTX $CNT @$ADDR"> {
12940b57cec5SDimitry Andric    let POP_COUNT = 0;
12950b57cec5SDimitry Andric  }
12960b57cec5SDimitry Andric  def WHILE_LOOP_R600 : CF_CLAUSE_R600<6, (ins i32imm:$ADDR),
12970b57cec5SDimitry Andric  "LOOP_START_DX10 @$ADDR"> {
12980b57cec5SDimitry Andric    let POP_COUNT = 0;
12990b57cec5SDimitry Andric    let CNT = 0;
13000b57cec5SDimitry Andric  }
13010b57cec5SDimitry Andric  def END_LOOP_R600 : CF_CLAUSE_R600<5, (ins i32imm:$ADDR), "END_LOOP @$ADDR"> {
13020b57cec5SDimitry Andric    let POP_COUNT = 0;
13030b57cec5SDimitry Andric    let CNT = 0;
13040b57cec5SDimitry Andric  }
13050b57cec5SDimitry Andric  def LOOP_BREAK_R600 : CF_CLAUSE_R600<9, (ins i32imm:$ADDR),
13060b57cec5SDimitry Andric  "LOOP_BREAK @$ADDR"> {
13070b57cec5SDimitry Andric    let POP_COUNT = 0;
13080b57cec5SDimitry Andric    let CNT = 0;
13090b57cec5SDimitry Andric  }
13100b57cec5SDimitry Andric  def CF_CONTINUE_R600 : CF_CLAUSE_R600<8, (ins i32imm:$ADDR),
13110b57cec5SDimitry Andric  "CONTINUE @$ADDR"> {
13120b57cec5SDimitry Andric    let POP_COUNT = 0;
13130b57cec5SDimitry Andric    let CNT = 0;
13140b57cec5SDimitry Andric  }
13150b57cec5SDimitry Andric  def CF_JUMP_R600 : CF_CLAUSE_R600<10, (ins i32imm:$ADDR, i32imm:$POP_COUNT),
13160b57cec5SDimitry Andric  "JUMP @$ADDR POP:$POP_COUNT"> {
13170b57cec5SDimitry Andric    let CNT = 0;
13180b57cec5SDimitry Andric  }
13190b57cec5SDimitry Andric  def CF_PUSH_ELSE_R600 : CF_CLAUSE_R600<12, (ins i32imm:$ADDR),
13200b57cec5SDimitry Andric  "PUSH_ELSE @$ADDR"> {
13210b57cec5SDimitry Andric    let CNT = 0;
13220b57cec5SDimitry Andric    let POP_COUNT = 0; // FIXME?
13230b57cec5SDimitry Andric  }
13240b57cec5SDimitry Andric  def CF_ELSE_R600 : CF_CLAUSE_R600<13, (ins i32imm:$ADDR, i32imm:$POP_COUNT),
13250b57cec5SDimitry Andric  "ELSE @$ADDR POP:$POP_COUNT"> {
13260b57cec5SDimitry Andric    let CNT = 0;
13270b57cec5SDimitry Andric  }
13280b57cec5SDimitry Andric  def CF_CALL_FS_R600 : CF_CLAUSE_R600<19, (ins), "CALL_FS"> {
13290b57cec5SDimitry Andric    let ADDR = 0;
13300b57cec5SDimitry Andric    let CNT = 0;
13310b57cec5SDimitry Andric    let POP_COUNT = 0;
13320b57cec5SDimitry Andric  }
13330b57cec5SDimitry Andric  def POP_R600 : CF_CLAUSE_R600<14, (ins i32imm:$ADDR, i32imm:$POP_COUNT),
13340b57cec5SDimitry Andric  "POP @$ADDR POP:$POP_COUNT"> {
13350b57cec5SDimitry Andric    let CNT = 0;
13360b57cec5SDimitry Andric  }
13370b57cec5SDimitry Andric  def CF_END_R600 : CF_CLAUSE_R600<0, (ins), "CF_END"> {
13380b57cec5SDimitry Andric    let CNT = 0;
13390b57cec5SDimitry Andric    let POP_COUNT = 0;
13400b57cec5SDimitry Andric    let ADDR = 0;
13410b57cec5SDimitry Andric    let END_OF_PROGRAM = 1;
13420b57cec5SDimitry Andric  }
13430b57cec5SDimitry Andric
13440b57cec5SDimitry Andric}
13450b57cec5SDimitry Andric
13460b57cec5SDimitry Andric
13470b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
1348349cc55cSDimitry Andric// Register loads and stores - for indirect addressing
13490b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
13500b57cec5SDimitry Andric
13510b57cec5SDimitry Andriclet Namespace = "R600" in {
13520b57cec5SDimitry Andricdefm R600_ : RegisterLoadStore <R600_Reg32, FRAMEri, ADDRIndirect>;
13530b57cec5SDimitry Andric}
13540b57cec5SDimitry Andric
13550b57cec5SDimitry Andric// Hardcode channel to 0
13560b57cec5SDimitry Andric// NOTE: LSHR is not available here. LSHR is per family instruction
13570b57cec5SDimitry Andricdef : R600Pat <
13580b57cec5SDimitry Andric  (i32 (load_private ADDRIndirect:$addr) ),
13590b57cec5SDimitry Andric  (R600_RegisterLoad FRAMEri:$addr, (i32 0))
13600b57cec5SDimitry Andric>;
13610b57cec5SDimitry Andricdef : R600Pat <
13620b57cec5SDimitry Andric  (store_private i32:$val, ADDRIndirect:$addr),
13630b57cec5SDimitry Andric  (R600_RegisterStore i32:$val, FRAMEri:$addr, (i32 0))
13640b57cec5SDimitry Andric>;
13650b57cec5SDimitry Andric
13660b57cec5SDimitry Andric
13670b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
13680b57cec5SDimitry Andric// Pseudo instructions
13690b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
13700b57cec5SDimitry Andric
13710b57cec5SDimitry Andriclet isPseudo = 1 in {
13720b57cec5SDimitry Andric
13730b57cec5SDimitry Andricdef PRED_X : InstR600 <
13740b57cec5SDimitry Andric  (outs R600_Predicate_Bit:$dst),
13750b57cec5SDimitry Andric  (ins R600_Reg32:$src0, i32imm:$src1, i32imm:$flags),
13760b57cec5SDimitry Andric  "", [], NullALU> {
13770b57cec5SDimitry Andric  let FlagOperandIdx = 3;
13780b57cec5SDimitry Andric}
13790b57cec5SDimitry Andric
13800b57cec5SDimitry Andriclet isTerminator = 1, isBranch = 1 in {
13810b57cec5SDimitry Andricdef JUMP_COND : InstR600 <
13820b57cec5SDimitry Andric          (outs),
13830b57cec5SDimitry Andric          (ins brtarget:$target, R600_Predicate_Bit:$p),
13840b57cec5SDimitry Andric          "JUMP $target ($p)",
13850b57cec5SDimitry Andric          [], AnyALU
13860b57cec5SDimitry Andric  >;
13870b57cec5SDimitry Andric
13880b57cec5SDimitry Andricdef JUMP : InstR600 <
13890b57cec5SDimitry Andric          (outs),
13900b57cec5SDimitry Andric          (ins brtarget:$target),
13910b57cec5SDimitry Andric          "JUMP $target",
13920b57cec5SDimitry Andric          [], AnyALU
13930b57cec5SDimitry Andric  >
13940b57cec5SDimitry Andric{
13950b57cec5SDimitry Andric  let isPredicable = 1;
13960b57cec5SDimitry Andric  let isBarrier = 1;
13970b57cec5SDimitry Andric}
13980b57cec5SDimitry Andric
13990b57cec5SDimitry Andric}  // End isTerminator = 1, isBranch = 1
14000b57cec5SDimitry Andric
14010b57cec5SDimitry Andriclet usesCustomInserter = 1 in {
14020b57cec5SDimitry Andric
14030b57cec5SDimitry Andriclet mayLoad = 0, mayStore = 0, hasSideEffects = 1 in {
14040b57cec5SDimitry Andric
14050b57cec5SDimitry Andricdef MASK_WRITE : InstR600 <
14060b57cec5SDimitry Andric    (outs),
14070b57cec5SDimitry Andric    (ins R600_Reg32:$src),
14080b57cec5SDimitry Andric    "MASK_WRITE $src",
14090b57cec5SDimitry Andric    [],
14100b57cec5SDimitry Andric    NullALU
14110b57cec5SDimitry Andric>;
14120b57cec5SDimitry Andric
14130b57cec5SDimitry Andric} // End mayLoad = 0, mayStore = 0, hasSideEffects = 1
14140b57cec5SDimitry Andric
14150b57cec5SDimitry Andric
14160b57cec5SDimitry Andricdef TXD: InstR600 <
14170b57cec5SDimitry Andric  (outs R600_Reg128:$dst),
14180b57cec5SDimitry Andric  (ins R600_Reg128:$src0, R600_Reg128:$src1, R600_Reg128:$src2,
14190b57cec5SDimitry Andric       i32imm:$resourceId, i32imm:$samplerId, i32imm:$textureTarget),
14200b57cec5SDimitry Andric  "TXD $dst, $src0, $src1, $src2, $resourceId, $samplerId, $textureTarget", [],
14210b57cec5SDimitry Andric  NullALU > {
14220b57cec5SDimitry Andric  let TEXInst = 1;
14230b57cec5SDimitry Andric}
14240b57cec5SDimitry Andric
14250b57cec5SDimitry Andricdef TXD_SHADOW: InstR600 <
14260b57cec5SDimitry Andric  (outs R600_Reg128:$dst),
14270b57cec5SDimitry Andric  (ins R600_Reg128:$src0, R600_Reg128:$src1, R600_Reg128:$src2,
14280b57cec5SDimitry Andric       i32imm:$resourceId, i32imm:$samplerId, i32imm:$textureTarget),
14290b57cec5SDimitry Andric  "TXD_SHADOW $dst, $src0, $src1, $src2, $resourceId, $samplerId, $textureTarget",
14300b57cec5SDimitry Andric  [], NullALU> {
14310b57cec5SDimitry Andric  let TEXInst = 1;
14320b57cec5SDimitry Andric}
14330b57cec5SDimitry Andric} // End isPseudo = 1
14340b57cec5SDimitry Andric} // End usesCustomInserter = 1
14350b57cec5SDimitry Andric
14360b57cec5SDimitry Andric
14370b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
14380b57cec5SDimitry Andric// Constant Buffer Addressing Support
14390b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
14400b57cec5SDimitry Andric
14410b57cec5SDimitry Andriclet usesCustomInserter = 1, isCodeGenOnly = 1, isPseudo = 1, Namespace = "R600"  in {
14420b57cec5SDimitry Andricdef CONST_COPY : Instruction {
14430b57cec5SDimitry Andric  let OutOperandList = (outs R600_Reg32:$dst);
14440b57cec5SDimitry Andric  let InOperandList = (ins i32imm:$src);
14450b57cec5SDimitry Andric  let Pattern =
14460b57cec5SDimitry Andric      [(set R600_Reg32:$dst, (CONST_ADDRESS ADDRGA_CONST_OFFSET:$src))];
14470b57cec5SDimitry Andric  let AsmString = "CONST_COPY";
14480b57cec5SDimitry Andric  let hasSideEffects = 0;
14490b57cec5SDimitry Andric  let isAsCheapAsAMove = 1;
14500b57cec5SDimitry Andric  let Itinerary = NullALU;
14510b57cec5SDimitry Andric}
14520b57cec5SDimitry Andric} // end usesCustomInserter = 1, isCodeGenOnly = 1, isPseudo = 1, Namespace = "AMDGPU"
14530b57cec5SDimitry Andric
14540b57cec5SDimitry Andricdef TEX_VTX_CONSTBUF :
1455bdd1243dSDimitry Andric  InstR600ISA <(outs R600_Reg128:$dst_gpr), (ins (MEMxi $src_gpr, $src_index):$src, i32imm:$buffer_id), "VTX_READ_eg $dst_gpr, $src",
1456bdd1243dSDimitry Andric      [(set v4i32:$dst_gpr, (CONST_ADDRESS ADDRGA_VAR_OFFSET:$src, (i32 imm:$buffer_id)))]>,
14570b57cec5SDimitry Andric  VTX_WORD1_GPR, VTX_WORD0_eg {
14580b57cec5SDimitry Andric
14590b57cec5SDimitry Andric  let VC_INST = 0;
14600b57cec5SDimitry Andric  let FETCH_TYPE = 2;
14610b57cec5SDimitry Andric  let FETCH_WHOLE_QUAD = 0;
14620b57cec5SDimitry Andric  let SRC_REL = 0;
14630b57cec5SDimitry Andric  let SRC_SEL_X = 0;
14640b57cec5SDimitry Andric  let DST_REL = 0;
14650b57cec5SDimitry Andric  let USE_CONST_FIELDS = 0;
14660b57cec5SDimitry Andric  let NUM_FORMAT_ALL = 2;
14670b57cec5SDimitry Andric  let FORMAT_COMP_ALL = 1;
14680b57cec5SDimitry Andric  let SRF_MODE_ALL = 1;
14690b57cec5SDimitry Andric  let MEGA_FETCH_COUNT = 16;
14700b57cec5SDimitry Andric  let DST_SEL_X        = 0;
14710b57cec5SDimitry Andric  let DST_SEL_Y        = 1;
14720b57cec5SDimitry Andric  let DST_SEL_Z        = 2;
14730b57cec5SDimitry Andric  let DST_SEL_W        = 3;
14740b57cec5SDimitry Andric  let DATA_FORMAT      = 35;
14750b57cec5SDimitry Andric
14760b57cec5SDimitry Andric  let Inst{31-0} = Word0;
14770b57cec5SDimitry Andric  let Inst{63-32} = Word1;
14780b57cec5SDimitry Andric
14790b57cec5SDimitry Andric// LLVM can only encode 64-bit instructions, so these fields are manually
14800b57cec5SDimitry Andric// encoded in R600CodeEmitter
14810b57cec5SDimitry Andric//
14820b57cec5SDimitry Andric// bits<16> OFFSET;
14830b57cec5SDimitry Andric// bits<2>  ENDIAN_SWAP = 0;
14840b57cec5SDimitry Andric// bits<1>  CONST_BUF_NO_STRIDE = 0;
14850b57cec5SDimitry Andric// bits<1>  MEGA_FETCH = 0;
14860b57cec5SDimitry Andric// bits<1>  ALT_CONST = 0;
14870b57cec5SDimitry Andric// bits<2>  BUFFER_INDEX_MODE = 0;
14880b57cec5SDimitry Andric
14890b57cec5SDimitry Andric
14900b57cec5SDimitry Andric
14910b57cec5SDimitry Andric// VTX_WORD2 (LLVM can only encode 64-bit instructions, so WORD2 encoding
14920b57cec5SDimitry Andric// is done in R600CodeEmitter
14930b57cec5SDimitry Andric//
14940b57cec5SDimitry Andric// Inst{79-64} = OFFSET;
14950b57cec5SDimitry Andric// Inst{81-80} = ENDIAN_SWAP;
14960b57cec5SDimitry Andric// Inst{82}    = CONST_BUF_NO_STRIDE;
14970b57cec5SDimitry Andric// Inst{83}    = MEGA_FETCH;
14980b57cec5SDimitry Andric// Inst{84}    = ALT_CONST;
14990b57cec5SDimitry Andric// Inst{86-85} = BUFFER_INDEX_MODE;
15000b57cec5SDimitry Andric// Inst{95-86} = 0; Reserved
15010b57cec5SDimitry Andric
15020b57cec5SDimitry Andric// VTX_WORD3 (Padding)
15030b57cec5SDimitry Andric//
15040b57cec5SDimitry Andric// Inst{127-96} = 0;
15050b57cec5SDimitry Andric  let VTXInst = 1;
15060b57cec5SDimitry Andric}
15070b57cec5SDimitry Andric
15080b57cec5SDimitry Andricdef TEX_VTX_TEXBUF:
1509bdd1243dSDimitry Andric  InstR600ISA <(outs R600_Reg128:$dst_gpr), (ins (MEMxi $src_gpr, $src_index):$src, i32imm:$buffer_id), "TEX_VTX_EXPLICIT_READ $dst_gpr, $src">,
15100b57cec5SDimitry AndricVTX_WORD1_GPR, VTX_WORD0_eg {
15110b57cec5SDimitry Andric
15120b57cec5SDimitry Andriclet VC_INST = 0;
15130b57cec5SDimitry Andriclet FETCH_TYPE = 2;
15140b57cec5SDimitry Andriclet FETCH_WHOLE_QUAD = 0;
15150b57cec5SDimitry Andriclet SRC_REL = 0;
15160b57cec5SDimitry Andriclet SRC_SEL_X = 0;
15170b57cec5SDimitry Andriclet DST_REL = 0;
15180b57cec5SDimitry Andriclet USE_CONST_FIELDS = 1;
15190b57cec5SDimitry Andriclet NUM_FORMAT_ALL = 0;
15200b57cec5SDimitry Andriclet FORMAT_COMP_ALL = 0;
15210b57cec5SDimitry Andriclet SRF_MODE_ALL = 1;
15220b57cec5SDimitry Andriclet MEGA_FETCH_COUNT = 16;
15230b57cec5SDimitry Andriclet DST_SEL_X        = 0;
15240b57cec5SDimitry Andriclet DST_SEL_Y        = 1;
15250b57cec5SDimitry Andriclet DST_SEL_Z        = 2;
15260b57cec5SDimitry Andriclet DST_SEL_W        = 3;
15270b57cec5SDimitry Andriclet DATA_FORMAT      = 0;
15280b57cec5SDimitry Andric
15290b57cec5SDimitry Andriclet Inst{31-0} = Word0;
15300b57cec5SDimitry Andriclet Inst{63-32} = Word1;
15310b57cec5SDimitry Andric
15320b57cec5SDimitry Andric// LLVM can only encode 64-bit instructions, so these fields are manually
15330b57cec5SDimitry Andric// encoded in R600CodeEmitter
15340b57cec5SDimitry Andric//
15350b57cec5SDimitry Andric// bits<16> OFFSET;
15360b57cec5SDimitry Andric// bits<2>  ENDIAN_SWAP = 0;
15370b57cec5SDimitry Andric// bits<1>  CONST_BUF_NO_STRIDE = 0;
15380b57cec5SDimitry Andric// bits<1>  MEGA_FETCH = 0;
15390b57cec5SDimitry Andric// bits<1>  ALT_CONST = 0;
15400b57cec5SDimitry Andric// bits<2>  BUFFER_INDEX_MODE = 0;
15410b57cec5SDimitry Andric
15420b57cec5SDimitry Andric
15430b57cec5SDimitry Andric
15440b57cec5SDimitry Andric// VTX_WORD2 (LLVM can only encode 64-bit instructions, so WORD2 encoding
15450b57cec5SDimitry Andric// is done in R600CodeEmitter
15460b57cec5SDimitry Andric//
15470b57cec5SDimitry Andric// Inst{79-64} = OFFSET;
15480b57cec5SDimitry Andric// Inst{81-80} = ENDIAN_SWAP;
15490b57cec5SDimitry Andric// Inst{82}    = CONST_BUF_NO_STRIDE;
15500b57cec5SDimitry Andric// Inst{83}    = MEGA_FETCH;
15510b57cec5SDimitry Andric// Inst{84}    = ALT_CONST;
15520b57cec5SDimitry Andric// Inst{86-85} = BUFFER_INDEX_MODE;
15530b57cec5SDimitry Andric// Inst{95-86} = 0; Reserved
15540b57cec5SDimitry Andric
15550b57cec5SDimitry Andric// VTX_WORD3 (Padding)
15560b57cec5SDimitry Andric//
15570b57cec5SDimitry Andric// Inst{127-96} = 0;
15580b57cec5SDimitry Andric  let VTXInst = 1;
15590b57cec5SDimitry Andric}
15600b57cec5SDimitry Andric
15610b57cec5SDimitry Andric//===---------------------------------------------------------------------===//
15620b57cec5SDimitry Andric// Flow and Program control Instructions
15630b57cec5SDimitry Andric//===---------------------------------------------------------------------===//
15640b57cec5SDimitry Andric
15650b57cec5SDimitry Andricmulticlass BranchConditional<SDNode Op, RegisterClass rci, RegisterClass rcf> {
15660b57cec5SDimitry Andric    def _i32 : ILFormat<(outs),
15670b57cec5SDimitry Andric  (ins brtarget:$target, rci:$src0),
15680b57cec5SDimitry Andric        "; i32 Pseudo branch instruction",
15690b57cec5SDimitry Andric  [(Op bb:$target, (i32 rci:$src0))]>;
15700b57cec5SDimitry Andric    def _f32 : ILFormat<(outs),
15710b57cec5SDimitry Andric  (ins brtarget:$target, rcf:$src0),
15720b57cec5SDimitry Andric        "; f32 Pseudo branch instruction",
15730b57cec5SDimitry Andric  [(Op bb:$target, (f32 rcf:$src0))]>;
15740b57cec5SDimitry Andric}
15750b57cec5SDimitry Andric
15760b57cec5SDimitry Andric// Only scalar types should generate flow control
15770b57cec5SDimitry Andricmulticlass BranchInstr<string name> {
15780b57cec5SDimitry Andric  def _i32 : ILFormat<(outs), (ins R600_Reg32:$src),
15790b57cec5SDimitry Andric      !strconcat(name, " $src"), []>;
15800b57cec5SDimitry Andric  def _f32 : ILFormat<(outs), (ins R600_Reg32:$src),
15810b57cec5SDimitry Andric      !strconcat(name, " $src"), []>;
15820b57cec5SDimitry Andric}
15830b57cec5SDimitry Andric// Only scalar types should generate flow control
15840b57cec5SDimitry Andricmulticlass BranchInstr2<string name> {
15850b57cec5SDimitry Andric  def _i32 : ILFormat<(outs), (ins R600_Reg32:$src0, R600_Reg32:$src1),
15860b57cec5SDimitry Andric      !strconcat(name, " $src0, $src1"), []>;
15870b57cec5SDimitry Andric  def _f32 : ILFormat<(outs), (ins R600_Reg32:$src0, R600_Reg32:$src1),
15880b57cec5SDimitry Andric      !strconcat(name, " $src0, $src1"), []>;
15890b57cec5SDimitry Andric}
15900b57cec5SDimitry Andric
15910b57cec5SDimitry Andric//===---------------------------------------------------------------------===//
15920b57cec5SDimitry Andric// Custom Inserter for Branches and returns, this eventually will be a
15930b57cec5SDimitry Andric// separate pass
15940b57cec5SDimitry Andric//===---------------------------------------------------------------------===//
15950b57cec5SDimitry Andriclet isTerminator = 1, usesCustomInserter = 1, isBranch = 1, isBarrier = 1,
15960b57cec5SDimitry Andric    Namespace = "R600" in {
15970b57cec5SDimitry Andric  def BRANCH : ILFormat<(outs), (ins brtarget:$target),
15980b57cec5SDimitry Andric      "; Pseudo unconditional branch instruction",
15990b57cec5SDimitry Andric      [(br bb:$target)]>;
16000b57cec5SDimitry Andric  defm BRANCH_COND : BranchConditional<IL_brcond, R600_Reg32, R600_Reg32>;
16010b57cec5SDimitry Andric}
16020b57cec5SDimitry Andric
16030b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
16040b57cec5SDimitry Andric// Branch Instructions
16050b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
16060b57cec5SDimitry Andric
16070b57cec5SDimitry Andricdef IF_PREDICATE_SET  : ILFormat<(outs), (ins R600_Reg32:$src),
16080b57cec5SDimitry Andric  "IF_PREDICATE_SET $src", []>;
16090b57cec5SDimitry Andric
16100b57cec5SDimitry Andriclet isTerminator=1 in {
16110b57cec5SDimitry Andric  def BREAK       : ILFormat< (outs), (ins),
16120b57cec5SDimitry Andric      "BREAK", []>;
16130b57cec5SDimitry Andric  def CONTINUE    : ILFormat< (outs), (ins),
16140b57cec5SDimitry Andric      "CONTINUE", []>;
16150b57cec5SDimitry Andric  def DEFAULT     : ILFormat< (outs), (ins),
16160b57cec5SDimitry Andric      "DEFAULT", []>;
16170b57cec5SDimitry Andric  def ELSE        : ILFormat< (outs), (ins),
16180b57cec5SDimitry Andric      "ELSE", []>;
16190b57cec5SDimitry Andric  def ENDSWITCH   : ILFormat< (outs), (ins),
16200b57cec5SDimitry Andric      "ENDSWITCH", []>;
16210b57cec5SDimitry Andric  def ENDMAIN     : ILFormat< (outs), (ins),
16220b57cec5SDimitry Andric      "ENDMAIN", []>;
16230b57cec5SDimitry Andric  def END         : ILFormat< (outs), (ins),
16240b57cec5SDimitry Andric      "END", []>;
16250b57cec5SDimitry Andric  def ENDFUNC     : ILFormat< (outs), (ins),
16260b57cec5SDimitry Andric      "ENDFUNC", []>;
16270b57cec5SDimitry Andric  def ENDIF       : ILFormat< (outs), (ins),
16280b57cec5SDimitry Andric      "ENDIF", []>;
16290b57cec5SDimitry Andric  def WHILELOOP   : ILFormat< (outs), (ins),
16300b57cec5SDimitry Andric      "WHILE", []>;
16310b57cec5SDimitry Andric  def ENDLOOP     : ILFormat< (outs), (ins),
16320b57cec5SDimitry Andric      "ENDLOOP", []>;
16330b57cec5SDimitry Andric  def FUNC        : ILFormat< (outs), (ins),
16340b57cec5SDimitry Andric      "FUNC", []>;
16350b57cec5SDimitry Andric  def RETDYN      : ILFormat< (outs), (ins),
16360b57cec5SDimitry Andric      "RET_DYN", []>;
16370b57cec5SDimitry Andric  // This opcode has custom swizzle pattern encoded in Swizzle Encoder
16380b57cec5SDimitry Andric  defm IF_LOGICALNZ  : BranchInstr<"IF_LOGICALNZ">;
16390b57cec5SDimitry Andric  // This opcode has custom swizzle pattern encoded in Swizzle Encoder
16400b57cec5SDimitry Andric  defm IF_LOGICALZ   : BranchInstr<"IF_LOGICALZ">;
16410b57cec5SDimitry Andric  // This opcode has custom swizzle pattern encoded in Swizzle Encoder
16420b57cec5SDimitry Andric  defm BREAK_LOGICALNZ : BranchInstr<"BREAK_LOGICALNZ">;
16430b57cec5SDimitry Andric  // This opcode has custom swizzle pattern encoded in Swizzle Encoder
16440b57cec5SDimitry Andric  defm BREAK_LOGICALZ : BranchInstr<"BREAK_LOGICALZ">;
16450b57cec5SDimitry Andric  // This opcode has custom swizzle pattern encoded in Swizzle Encoder
16460b57cec5SDimitry Andric  defm CONTINUE_LOGICALNZ : BranchInstr<"CONTINUE_LOGICALNZ">;
16470b57cec5SDimitry Andric  // This opcode has custom swizzle pattern encoded in Swizzle Encoder
16480b57cec5SDimitry Andric  defm CONTINUE_LOGICALZ : BranchInstr<"CONTINUE_LOGICALZ">;
16490b57cec5SDimitry Andric  defm IFC         : BranchInstr2<"IFC">;
16500b57cec5SDimitry Andric  defm BREAKC      : BranchInstr2<"BREAKC">;
16510b57cec5SDimitry Andric  defm CONTINUEC   : BranchInstr2<"CONTINUEC">;
16520b57cec5SDimitry Andric}
16530b57cec5SDimitry Andric
16540b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
16550b57cec5SDimitry Andric// Indirect addressing pseudo instructions
16560b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
16570b57cec5SDimitry Andric
16580b57cec5SDimitry Andriclet isPseudo = 1 in {
16590b57cec5SDimitry Andric
16600b57cec5SDimitry Andricclass ExtractVertical <RegisterClass vec_rc> : InstR600 <
16610b57cec5SDimitry Andric  (outs R600_Reg32:$dst),
16620b57cec5SDimitry Andric  (ins vec_rc:$vec, R600_Reg32:$index), "",
16630b57cec5SDimitry Andric  [],
16640b57cec5SDimitry Andric  AnyALU
16650b57cec5SDimitry Andric>;
16660b57cec5SDimitry Andric
16670b57cec5SDimitry Andriclet Constraints = "$dst = $vec" in {
16680b57cec5SDimitry Andric
16690b57cec5SDimitry Andricclass InsertVertical <RegisterClass vec_rc> : InstR600 <
16700b57cec5SDimitry Andric  (outs vec_rc:$dst),
16710b57cec5SDimitry Andric  (ins vec_rc:$vec, R600_Reg32:$value, R600_Reg32:$index), "",
16720b57cec5SDimitry Andric  [],
16730b57cec5SDimitry Andric  AnyALU
16740b57cec5SDimitry Andric>;
16750b57cec5SDimitry Andric
16760b57cec5SDimitry Andric} // End Constraints = "$dst = $vec"
16770b57cec5SDimitry Andric
16780b57cec5SDimitry Andric} // End isPseudo = 1
16790b57cec5SDimitry Andric
16800b57cec5SDimitry Andricdef R600_EXTRACT_ELT_V2 : ExtractVertical <R600_Reg64Vertical>;
16810b57cec5SDimitry Andricdef R600_EXTRACT_ELT_V4 : ExtractVertical <R600_Reg128Vertical>;
16820b57cec5SDimitry Andric
16830b57cec5SDimitry Andricdef R600_INSERT_ELT_V2 : InsertVertical <R600_Reg64Vertical>;
16840b57cec5SDimitry Andricdef R600_INSERT_ELT_V4 : InsertVertical <R600_Reg128Vertical>;
16850b57cec5SDimitry Andric
16860b57cec5SDimitry Andricclass ExtractVerticalPat <Instruction inst, ValueType vec_ty,
16870b57cec5SDimitry Andric                          ValueType scalar_ty> : R600Pat <
16880b57cec5SDimitry Andric  (scalar_ty (extractelt vec_ty:$vec, i32:$index)),
16890b57cec5SDimitry Andric  (inst $vec, $index)
16900b57cec5SDimitry Andric>;
16910b57cec5SDimitry Andric
16920b57cec5SDimitry Andricdef : ExtractVerticalPat <R600_EXTRACT_ELT_V2, v2i32, i32>;
16930b57cec5SDimitry Andricdef : ExtractVerticalPat <R600_EXTRACT_ELT_V2, v2f32, f32>;
16940b57cec5SDimitry Andricdef : ExtractVerticalPat <R600_EXTRACT_ELT_V4, v4i32, i32>;
16950b57cec5SDimitry Andricdef : ExtractVerticalPat <R600_EXTRACT_ELT_V4, v4f32, f32>;
16960b57cec5SDimitry Andric
16970b57cec5SDimitry Andricclass InsertVerticalPat <Instruction inst, ValueType vec_ty,
16980b57cec5SDimitry Andric                         ValueType scalar_ty> : R600Pat <
16990b57cec5SDimitry Andric  (vec_ty (insertelt vec_ty:$vec, scalar_ty:$value, i32:$index)),
17000b57cec5SDimitry Andric  (inst $vec, $value, $index)
17010b57cec5SDimitry Andric>;
17020b57cec5SDimitry Andric
17030b57cec5SDimitry Andricdef : InsertVerticalPat <R600_INSERT_ELT_V2, v2i32, i32>;
17040b57cec5SDimitry Andricdef : InsertVerticalPat <R600_INSERT_ELT_V2, v2f32, f32>;
17050b57cec5SDimitry Andricdef : InsertVerticalPat <R600_INSERT_ELT_V4, v4i32, i32>;
17060b57cec5SDimitry Andricdef : InsertVerticalPat <R600_INSERT_ELT_V4, v4f32, f32>;
17070b57cec5SDimitry Andric
17080b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
17090b57cec5SDimitry Andric// ISel Patterns
17100b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
17110b57cec5SDimitry Andric
17120b57cec5SDimitry Andriclet SubtargetPredicate = isR600toCayman in {
17130b57cec5SDimitry Andric
17140b57cec5SDimitry Andric// CND*_INT Patterns for f32 True / False values
17150b57cec5SDimitry Andric
17160b57cec5SDimitry Andricclass CND_INT_f32 <InstR600 cnd, CondCode cc> : R600Pat <
17170b57cec5SDimitry Andric  (selectcc i32:$src0, 0, f32:$src1, f32:$src2, cc),
17180b57cec5SDimitry Andric  (cnd $src0, $src1, $src2)
17190b57cec5SDimitry Andric>;
17200b57cec5SDimitry Andric
17210b57cec5SDimitry Andricdef : CND_INT_f32 <CNDE_INT,  SETEQ>;
17220b57cec5SDimitry Andricdef : CND_INT_f32 <CNDGT_INT, SETGT>;
17230b57cec5SDimitry Andricdef : CND_INT_f32 <CNDGE_INT, SETGE>;
17240b57cec5SDimitry Andric
17250b57cec5SDimitry Andric//CNDGE_INT extra pattern
17260b57cec5SDimitry Andricdef : R600Pat <
17270b57cec5SDimitry Andric  (selectcc i32:$src0, -1, i32:$src1, i32:$src2, COND_SGT),
17280b57cec5SDimitry Andric  (CNDGE_INT $src0, $src1, $src2)
17290b57cec5SDimitry Andric>;
17300b57cec5SDimitry Andric
17310b57cec5SDimitry Andric// KIL Patterns
17320b57cec5SDimitry Andricdef KIL : R600Pat <
17330b57cec5SDimitry Andric  (int_r600_kill f32:$src0),
17340b57cec5SDimitry Andric  (MASK_WRITE (KILLGT (f32 ZERO), $src0))
17350b57cec5SDimitry Andric>;
17360b57cec5SDimitry Andric
17370b57cec5SDimitry Andricdef : Extract_Element <f32, v4f32, 0, sub0>;
17380b57cec5SDimitry Andricdef : Extract_Element <f32, v4f32, 1, sub1>;
17390b57cec5SDimitry Andricdef : Extract_Element <f32, v4f32, 2, sub2>;
17400b57cec5SDimitry Andricdef : Extract_Element <f32, v4f32, 3, sub3>;
17410b57cec5SDimitry Andric
17420b57cec5SDimitry Andricdef : Insert_Element <f32, v4f32, 0, sub0>;
17430b57cec5SDimitry Andricdef : Insert_Element <f32, v4f32, 1, sub1>;
17440b57cec5SDimitry Andricdef : Insert_Element <f32, v4f32, 2, sub2>;
17450b57cec5SDimitry Andricdef : Insert_Element <f32, v4f32, 3, sub3>;
17460b57cec5SDimitry Andric
17470b57cec5SDimitry Andricdef : Extract_Element <i32, v4i32, 0, sub0>;
17480b57cec5SDimitry Andricdef : Extract_Element <i32, v4i32, 1, sub1>;
17490b57cec5SDimitry Andricdef : Extract_Element <i32, v4i32, 2, sub2>;
17500b57cec5SDimitry Andricdef : Extract_Element <i32, v4i32, 3, sub3>;
17510b57cec5SDimitry Andric
17520b57cec5SDimitry Andricdef : Insert_Element <i32, v4i32, 0, sub0>;
17530b57cec5SDimitry Andricdef : Insert_Element <i32, v4i32, 1, sub1>;
17540b57cec5SDimitry Andricdef : Insert_Element <i32, v4i32, 2, sub2>;
17550b57cec5SDimitry Andricdef : Insert_Element <i32, v4i32, 3, sub3>;
17560b57cec5SDimitry Andric
17570b57cec5SDimitry Andricdef : Extract_Element <f32, v2f32, 0, sub0>;
17580b57cec5SDimitry Andricdef : Extract_Element <f32, v2f32, 1, sub1>;
17590b57cec5SDimitry Andric
17600b57cec5SDimitry Andricdef : Insert_Element <f32, v2f32, 0, sub0>;
17610b57cec5SDimitry Andricdef : Insert_Element <f32, v2f32, 1, sub1>;
17620b57cec5SDimitry Andric
17630b57cec5SDimitry Andricdef : Extract_Element <i32, v2i32, 0, sub0>;
17640b57cec5SDimitry Andricdef : Extract_Element <i32, v2i32, 1, sub1>;
17650b57cec5SDimitry Andric
17660b57cec5SDimitry Andricdef : Insert_Element <i32, v2i32, 0, sub0>;
17670b57cec5SDimitry Andricdef : Insert_Element <i32, v2i32, 1, sub1>;
17680b57cec5SDimitry Andric
17690b57cec5SDimitry Andric// bitconvert patterns
17700b57cec5SDimitry Andric
17710b57cec5SDimitry Andricdef : BitConvert <i32, f32, R600_Reg32>;
17720b57cec5SDimitry Andricdef : BitConvert <f32, i32, R600_Reg32>;
17730b57cec5SDimitry Andricdef : BitConvert <v2f32, v2i32, R600_Reg64>;
17740b57cec5SDimitry Andricdef : BitConvert <v2i32, v2f32, R600_Reg64>;
17750b57cec5SDimitry Andricdef : BitConvert <v4f32, v4i32, R600_Reg128>;
17760b57cec5SDimitry Andricdef : BitConvert <v4i32, v4f32, R600_Reg128>;
17770b57cec5SDimitry Andric
17780b57cec5SDimitry Andric// DWORDADDR pattern
17790b57cec5SDimitry Andricdef : DwordAddrPat  <i32, R600_Reg32>;
17800b57cec5SDimitry Andric
17810b57cec5SDimitry Andric} // End SubtargetPredicate = isR600toCayman
17820b57cec5SDimitry Andric
17830b57cec5SDimitry Andricdef getLDSNoRetOp : InstrMapping {
17840b57cec5SDimitry Andric  let FilterClass = "R600_LDS_1A1D";
17850b57cec5SDimitry Andric  let RowFields = ["BaseOp"];
17860b57cec5SDimitry Andric  let ColFields = ["DisableEncoding"];
17870b57cec5SDimitry Andric  let KeyCol = ["$dst"];
17880b57cec5SDimitry Andric  let ValueCols = [[""""]];
17890b57cec5SDimitry Andric}
1790