106f32e7eSjoerg//===-- R600Instructions.td - R600 Instruction defs -------*- tablegen -*-===// 206f32e7eSjoerg// 306f32e7eSjoerg// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 406f32e7eSjoerg// See https://llvm.org/LICENSE.txt for license information. 506f32e7eSjoerg// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 606f32e7eSjoerg// 706f32e7eSjoerg//===----------------------------------------------------------------------===// 806f32e7eSjoerg// 906f32e7eSjoerg// TableGen definitions for instructions which are available on R600 family 1006f32e7eSjoerg// GPUs. 1106f32e7eSjoerg// 1206f32e7eSjoerg//===----------------------------------------------------------------------===// 1306f32e7eSjoerg 1406f32e7eSjoerginclude "R600InstrFormats.td" 1506f32e7eSjoerg 1606f32e7eSjoerg// FIXME: Should not be arbitrarily split from other R600 inst classes. 1706f32e7eSjoergclass R600WrapperInst <dag outs, dag ins, string asm = "", list<dag> pattern = []> : 1806f32e7eSjoerg AMDGPUInst<outs, ins, asm, pattern>, PredicateControl { 1906f32e7eSjoerg let SubtargetPredicate = isR600toCayman; 2006f32e7eSjoerg let Namespace = "R600"; 2106f32e7eSjoerg} 2206f32e7eSjoerg 2306f32e7eSjoerg 2406f32e7eSjoergclass InstR600ISA <dag outs, dag ins, string asm, list<dag> pattern = []> : 2506f32e7eSjoerg InstR600 <outs, ins, asm, pattern, NullALU> { 2606f32e7eSjoerg 2706f32e7eSjoerg} 2806f32e7eSjoerg 2906f32e7eSjoergdef MEMxi : Operand<iPTR> { 3006f32e7eSjoerg let MIOperandInfo = (ops R600_TReg32_X:$ptr, i32imm:$index); 3106f32e7eSjoerg let PrintMethod = "printMemOperand"; 3206f32e7eSjoerg} 3306f32e7eSjoerg 3406f32e7eSjoergdef MEMrr : Operand<iPTR> { 3506f32e7eSjoerg let MIOperandInfo = (ops R600_Reg32:$ptr, R600_Reg32:$index); 3606f32e7eSjoerg} 3706f32e7eSjoerg 3806f32e7eSjoerg// Operands for non-registers 3906f32e7eSjoerg 4006f32e7eSjoergclass InstFlag<string PM = "printOperand", int Default = 0> 4106f32e7eSjoerg : OperandWithDefaultOps <i32, (ops (i32 Default))> { 4206f32e7eSjoerg let PrintMethod = PM; 4306f32e7eSjoerg} 4406f32e7eSjoerg 4506f32e7eSjoerg// src_sel for ALU src operands, see also ALU_CONST, ALU_PARAM registers 4606f32e7eSjoergdef SEL : OperandWithDefaultOps <i32, (ops (i32 -1))>; 4706f32e7eSjoergdef BANK_SWIZZLE : OperandWithDefaultOps <i32, (ops (i32 0))> { 4806f32e7eSjoerg let PrintMethod = "printBankSwizzle"; 4906f32e7eSjoerg} 5006f32e7eSjoerg 5106f32e7eSjoergdef LITERAL : InstFlag<"printLiteral">; 5206f32e7eSjoerg 5306f32e7eSjoergdef WRITE : InstFlag <"printWrite", 1>; 5406f32e7eSjoergdef OMOD : InstFlag <"printOMOD">; 5506f32e7eSjoergdef REL : InstFlag <"printRel">; 5606f32e7eSjoergdef CLAMP : InstFlag <"printClamp">; 5706f32e7eSjoergdef NEG : InstFlag <"printNeg">; 5806f32e7eSjoergdef ABS : InstFlag <"printAbs">; 5906f32e7eSjoergdef UEM : InstFlag <"printUpdateExecMask">; 6006f32e7eSjoergdef UP : InstFlag <"printUpdatePred">; 6106f32e7eSjoerg 6206f32e7eSjoerg// XXX: The r600g finalizer in Mesa expects last to be one in most cases. 6306f32e7eSjoerg// Once we start using the packetizer in this backend we should have this 6406f32e7eSjoerg// default to 0. 6506f32e7eSjoergdef LAST : InstFlag<"printLast", 1>; 6606f32e7eSjoergdef RSel : Operand<i32> { 6706f32e7eSjoerg let PrintMethod = "printRSel"; 6806f32e7eSjoerg} 6906f32e7eSjoergdef CT: Operand<i32> { 7006f32e7eSjoerg let PrintMethod = "printCT"; 7106f32e7eSjoerg} 7206f32e7eSjoerg 7306f32e7eSjoergdef FRAMEri : Operand<iPTR> { 7406f32e7eSjoerg let MIOperandInfo = (ops R600_Reg32:$ptr, i32imm:$index); 7506f32e7eSjoerg} 7606f32e7eSjoerg 7706f32e7eSjoergdef ADDRParam : ComplexPattern<i32, 2, "SelectADDRParam", [], []>; 7806f32e7eSjoergdef ADDRDWord : ComplexPattern<i32, 1, "SelectADDRDWord", [], []>; 7906f32e7eSjoergdef ADDRVTX_READ : ComplexPattern<i32, 2, "SelectADDRVTX_READ", [], []>; 8006f32e7eSjoergdef ADDRGA_CONST_OFFSET : ComplexPattern<i32, 1, "SelectGlobalValueConstantOffset", [], []>; 8106f32e7eSjoergdef ADDRGA_VAR_OFFSET : ComplexPattern<i32, 2, "SelectGlobalValueVariableOffset", [], []>; 8206f32e7eSjoergdef ADDRIndirect : ComplexPattern<iPTR, 2, "SelectADDRIndirect", [], []>; 8306f32e7eSjoerg 8406f32e7eSjoerg 8506f32e7eSjoergdef R600_Pred : PredicateOperand<i32, (ops R600_Predicate), 8606f32e7eSjoerg (ops PRED_SEL_OFF)>; 8706f32e7eSjoerg 8806f32e7eSjoerglet isTerminator = 1, isReturn = 1, hasCtrlDep = 1, 8906f32e7eSjoerg usesCustomInserter = 1, Namespace = "R600" in { 9006f32e7eSjoerg def RETURN : ILFormat<(outs), (ins variable_ops), 9106f32e7eSjoerg "RETURN", [(AMDGPUendpgm)] 9206f32e7eSjoerg >; 9306f32e7eSjoerg} 9406f32e7eSjoerg 9506f32e7eSjoerglet mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 9606f32e7eSjoerg 9706f32e7eSjoerg// Class for instructions with only one source register. 9806f32e7eSjoerg// If you add new ins to this instruction, make sure they are listed before 9906f32e7eSjoerg// $literal, because the backend currently assumes that the last operand is 10006f32e7eSjoerg// a literal. Also be sure to update the enum R600Op1OperandIndex::ROI in 10106f32e7eSjoerg// R600Defines.h, R600InstrInfo::buildDefaultInstruction(), 10206f32e7eSjoerg// and R600InstrInfo::getOperandIdx(). 10306f32e7eSjoergclass R600_1OP <bits<11> inst, string opName, list<dag> pattern, 10406f32e7eSjoerg InstrItinClass itin = AnyALU> : 10506f32e7eSjoerg InstR600 <(outs R600_Reg32:$dst), 10606f32e7eSjoerg (ins WRITE:$write, OMOD:$omod, REL:$dst_rel, CLAMP:$clamp, 10706f32e7eSjoerg R600_Reg32:$src0, NEG:$src0_neg, REL:$src0_rel, ABS:$src0_abs, SEL:$src0_sel, 10806f32e7eSjoerg LAST:$last, R600_Pred:$pred_sel, LITERAL:$literal, 10906f32e7eSjoerg BANK_SWIZZLE:$bank_swizzle), 11006f32e7eSjoerg !strconcat(" ", opName, 11106f32e7eSjoerg "$clamp $last $dst$write$dst_rel$omod, " 11206f32e7eSjoerg "$src0_neg$src0_abs$src0$src0_abs$src0_rel, " 11306f32e7eSjoerg "$pred_sel $bank_swizzle"), 11406f32e7eSjoerg pattern, 11506f32e7eSjoerg itin>, 11606f32e7eSjoerg R600ALU_Word0, 11706f32e7eSjoerg R600ALU_Word1_OP2 <inst> { 11806f32e7eSjoerg 11906f32e7eSjoerg let src1 = 0; 12006f32e7eSjoerg let src1_rel = 0; 12106f32e7eSjoerg let src1_neg = 0; 12206f32e7eSjoerg let src1_abs = 0; 12306f32e7eSjoerg let update_exec_mask = 0; 12406f32e7eSjoerg let update_pred = 0; 12506f32e7eSjoerg let HasNativeOperands = 1; 12606f32e7eSjoerg let Op1 = 1; 12706f32e7eSjoerg let ALUInst = 1; 12806f32e7eSjoerg let DisableEncoding = "$literal"; 12906f32e7eSjoerg let UseNamedOperandTable = 1; 13006f32e7eSjoerg 13106f32e7eSjoerg let Inst{31-0} = Word0; 13206f32e7eSjoerg let Inst{63-32} = Word1; 13306f32e7eSjoerg} 13406f32e7eSjoerg 13506f32e7eSjoergclass R600_1OP_Helper <bits<11> inst, string opName, SDPatternOperator node, 13606f32e7eSjoerg InstrItinClass itin = AnyALU> : 13706f32e7eSjoerg R600_1OP <inst, opName, 13806f32e7eSjoerg [(set R600_Reg32:$dst, (node R600_Reg32:$src0))], itin 13906f32e7eSjoerg>; 14006f32e7eSjoerg 14106f32e7eSjoerg// If you add or change the operands for R600_2OP instructions, you must 14206f32e7eSjoerg// also update the R600Op2OperandIndex::ROI enum in R600Defines.h, 14306f32e7eSjoerg// R600InstrInfo::buildDefaultInstruction(), and R600InstrInfo::getOperandIdx(). 14406f32e7eSjoergclass R600_2OP <bits<11> inst, string opName, list<dag> pattern, 14506f32e7eSjoerg InstrItinClass itin = AnyALU> : 14606f32e7eSjoerg InstR600 <(outs R600_Reg32:$dst), 14706f32e7eSjoerg (ins UEM:$update_exec_mask, UP:$update_pred, WRITE:$write, 14806f32e7eSjoerg OMOD:$omod, REL:$dst_rel, CLAMP:$clamp, 14906f32e7eSjoerg R600_Reg32:$src0, NEG:$src0_neg, REL:$src0_rel, ABS:$src0_abs, SEL:$src0_sel, 15006f32e7eSjoerg R600_Reg32:$src1, NEG:$src1_neg, REL:$src1_rel, ABS:$src1_abs, SEL:$src1_sel, 15106f32e7eSjoerg LAST:$last, R600_Pred:$pred_sel, LITERAL:$literal, 15206f32e7eSjoerg BANK_SWIZZLE:$bank_swizzle), 15306f32e7eSjoerg !strconcat(" ", opName, 15406f32e7eSjoerg "$clamp $last $update_exec_mask$update_pred$dst$write$dst_rel$omod, " 15506f32e7eSjoerg "$src0_neg$src0_abs$src0$src0_abs$src0_rel, " 15606f32e7eSjoerg "$src1_neg$src1_abs$src1$src1_abs$src1_rel, " 15706f32e7eSjoerg "$pred_sel $bank_swizzle"), 15806f32e7eSjoerg pattern, 15906f32e7eSjoerg itin>, 16006f32e7eSjoerg R600ALU_Word0, 16106f32e7eSjoerg R600ALU_Word1_OP2 <inst> { 16206f32e7eSjoerg 16306f32e7eSjoerg let HasNativeOperands = 1; 16406f32e7eSjoerg let Op2 = 1; 16506f32e7eSjoerg let ALUInst = 1; 16606f32e7eSjoerg let DisableEncoding = "$literal"; 16706f32e7eSjoerg let UseNamedOperandTable = 1; 16806f32e7eSjoerg 16906f32e7eSjoerg let Inst{31-0} = Word0; 17006f32e7eSjoerg let Inst{63-32} = Word1; 17106f32e7eSjoerg} 17206f32e7eSjoerg 17306f32e7eSjoergclass R600_2OP_Helper <bits<11> inst, string opName, 17406f32e7eSjoerg SDPatternOperator node = null_frag, 17506f32e7eSjoerg InstrItinClass itin = AnyALU> : 17606f32e7eSjoerg R600_2OP <inst, opName, 17706f32e7eSjoerg [(set R600_Reg32:$dst, (node R600_Reg32:$src0, 17806f32e7eSjoerg R600_Reg32:$src1))], itin 17906f32e7eSjoerg>; 18006f32e7eSjoerg 18106f32e7eSjoerg// If you add our change the operands for R600_3OP instructions, you must 18206f32e7eSjoerg// also update the R600Op3OperandIndex::ROI enum in R600Defines.h, 18306f32e7eSjoerg// R600InstrInfo::buildDefaultInstruction(), and 18406f32e7eSjoerg// R600InstrInfo::getOperandIdx(). 18506f32e7eSjoergclass R600_3OP <bits<5> inst, string opName, list<dag> pattern, 18606f32e7eSjoerg InstrItinClass itin = AnyALU> : 18706f32e7eSjoerg InstR600 <(outs R600_Reg32:$dst), 18806f32e7eSjoerg (ins REL:$dst_rel, CLAMP:$clamp, 18906f32e7eSjoerg R600_Reg32:$src0, NEG:$src0_neg, REL:$src0_rel, SEL:$src0_sel, 19006f32e7eSjoerg R600_Reg32:$src1, NEG:$src1_neg, REL:$src1_rel, SEL:$src1_sel, 19106f32e7eSjoerg R600_Reg32:$src2, NEG:$src2_neg, REL:$src2_rel, SEL:$src2_sel, 19206f32e7eSjoerg LAST:$last, R600_Pred:$pred_sel, LITERAL:$literal, 19306f32e7eSjoerg BANK_SWIZZLE:$bank_swizzle), 19406f32e7eSjoerg !strconcat(" ", opName, "$clamp $last $dst$dst_rel, " 19506f32e7eSjoerg "$src0_neg$src0$src0_rel, " 19606f32e7eSjoerg "$src1_neg$src1$src1_rel, " 19706f32e7eSjoerg "$src2_neg$src2$src2_rel, " 19806f32e7eSjoerg "$pred_sel" 19906f32e7eSjoerg "$bank_swizzle"), 20006f32e7eSjoerg pattern, 20106f32e7eSjoerg itin>, 20206f32e7eSjoerg R600ALU_Word0, 20306f32e7eSjoerg R600ALU_Word1_OP3<inst>{ 20406f32e7eSjoerg 20506f32e7eSjoerg let HasNativeOperands = 1; 20606f32e7eSjoerg let DisableEncoding = "$literal"; 20706f32e7eSjoerg let Op3 = 1; 20806f32e7eSjoerg let UseNamedOperandTable = 1; 20906f32e7eSjoerg let ALUInst = 1; 21006f32e7eSjoerg 21106f32e7eSjoerg let Inst{31-0} = Word0; 21206f32e7eSjoerg let Inst{63-32} = Word1; 21306f32e7eSjoerg} 21406f32e7eSjoerg 21506f32e7eSjoergclass R600_REDUCTION <bits<11> inst, dag ins, string asm, list<dag> pattern, 21606f32e7eSjoerg InstrItinClass itin = VecALU> : 21706f32e7eSjoerg InstR600 <(outs R600_Reg32:$dst), 21806f32e7eSjoerg ins, 21906f32e7eSjoerg asm, 22006f32e7eSjoerg pattern, 22106f32e7eSjoerg itin>; 22206f32e7eSjoerg 22306f32e7eSjoerg 22406f32e7eSjoerg 22506f32e7eSjoerg} // End mayLoad = 1, mayStore = 0, hasSideEffects = 0 22606f32e7eSjoerg 22706f32e7eSjoergclass EG_CF_RAT <bits <8> cfinst, bits <6> ratinst, bits<4> ratid, bits<4> mask, 22806f32e7eSjoerg dag outs, dag ins, string asm, list<dag> pattern> : 22906f32e7eSjoerg InstR600ISA <outs, ins, asm, pattern>, 23006f32e7eSjoerg CF_ALLOC_EXPORT_WORD0_RAT, CF_ALLOC_EXPORT_WORD1_BUF { 23106f32e7eSjoerg 23206f32e7eSjoerg let rat_id = ratid; 23306f32e7eSjoerg let rat_inst = ratinst; 23406f32e7eSjoerg let rim = 0; 23506f32e7eSjoerg // XXX: Have a separate instruction for non-indexed writes. 23606f32e7eSjoerg let type = 1; 23706f32e7eSjoerg let rw_rel = 0; 23806f32e7eSjoerg let elem_size = 0; 23906f32e7eSjoerg 24006f32e7eSjoerg let array_size = 0; 24106f32e7eSjoerg let comp_mask = mask; 24206f32e7eSjoerg let burst_count = 0; 24306f32e7eSjoerg let vpm = 0; 24406f32e7eSjoerg let cf_inst = cfinst; 24506f32e7eSjoerg let mark = 0; 24606f32e7eSjoerg let barrier = 1; 24706f32e7eSjoerg 24806f32e7eSjoerg let Inst{31-0} = Word0; 24906f32e7eSjoerg let Inst{63-32} = Word1; 25006f32e7eSjoerg let IsExport = 1; 25106f32e7eSjoerg 25206f32e7eSjoerg} 25306f32e7eSjoerg 25406f32e7eSjoergclass VTX_READ <string name, dag outs, list<dag> pattern> 25506f32e7eSjoerg : InstR600ISA <outs, (ins MEMxi:$src_gpr, i8imm:$buffer_id), !strconcat(" ", name, ", #$buffer_id"), pattern>, 25606f32e7eSjoerg VTX_WORD1_GPR { 25706f32e7eSjoerg 25806f32e7eSjoerg // Static fields 25906f32e7eSjoerg let DST_REL = 0; 26006f32e7eSjoerg // The docs say that if this bit is set, then DATA_FORMAT, NUM_FORMAT_ALL, 26106f32e7eSjoerg // FORMAT_COMP_ALL, SRF_MODE_ALL, and ENDIAN_SWAP fields will be ignored, 26206f32e7eSjoerg // however, based on my testing if USE_CONST_FIELDS is set, then all 26306f32e7eSjoerg // these fields need to be set to 0. 26406f32e7eSjoerg let USE_CONST_FIELDS = 0; 26506f32e7eSjoerg let NUM_FORMAT_ALL = 1; 26606f32e7eSjoerg let FORMAT_COMP_ALL = 0; 26706f32e7eSjoerg let SRF_MODE_ALL = 0; 26806f32e7eSjoerg 26906f32e7eSjoerg let Inst{63-32} = Word1; 27006f32e7eSjoerg // LLVM can only encode 64-bit instructions, so these fields are manually 27106f32e7eSjoerg // encoded in R600CodeEmitter 27206f32e7eSjoerg // 27306f32e7eSjoerg // bits<16> OFFSET; 27406f32e7eSjoerg // bits<2> ENDIAN_SWAP = 0; 27506f32e7eSjoerg // bits<1> CONST_BUF_NO_STRIDE = 0; 27606f32e7eSjoerg // bits<1> MEGA_FETCH = 0; 27706f32e7eSjoerg // bits<1> ALT_CONST = 0; 27806f32e7eSjoerg // bits<2> BUFFER_INDEX_MODE = 0; 27906f32e7eSjoerg 28006f32e7eSjoerg // VTX_WORD2 (LLVM can only encode 64-bit instructions, so WORD2 encoding 28106f32e7eSjoerg // is done in R600CodeEmitter 28206f32e7eSjoerg // 28306f32e7eSjoerg // Inst{79-64} = OFFSET; 28406f32e7eSjoerg // Inst{81-80} = ENDIAN_SWAP; 28506f32e7eSjoerg // Inst{82} = CONST_BUF_NO_STRIDE; 28606f32e7eSjoerg // Inst{83} = MEGA_FETCH; 28706f32e7eSjoerg // Inst{84} = ALT_CONST; 28806f32e7eSjoerg // Inst{86-85} = BUFFER_INDEX_MODE; 28906f32e7eSjoerg // Inst{95-86} = 0; Reserved 29006f32e7eSjoerg 29106f32e7eSjoerg // VTX_WORD3 (Padding) 29206f32e7eSjoerg // 29306f32e7eSjoerg // Inst{127-96} = 0; 29406f32e7eSjoerg 29506f32e7eSjoerg let VTXInst = 1; 29606f32e7eSjoerg} 29706f32e7eSjoerg 298*da58b97aSjoerg// Legacy. 299*da58b97aSjoergdef atomic_cmp_swap_global_noret : PatFrag< 300*da58b97aSjoerg (ops node:$ptr, node:$cmp, node:$value), 301*da58b97aSjoerg (atomic_cmp_swap node:$ptr, node:$cmp, node:$value), 302*da58b97aSjoerg [{return cast<MemSDNode>(N)->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS && (SDValue(N, 0).use_empty());}]>; 30306f32e7eSjoerg 304*da58b97aSjoergdef atomic_cmp_swap_global_ret : PatFrag< 305*da58b97aSjoerg (ops node:$ptr, node:$cmp, node:$value), 306*da58b97aSjoerg (atomic_cmp_swap node:$ptr, node:$cmp, node:$value), 307*da58b97aSjoerg [{return cast<MemSDNode>(N)->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS && (!SDValue(N, 0).use_empty());}]>; 308*da58b97aSjoerg 309*da58b97aSjoergdef mskor_global : PatFrag<(ops node:$val, node:$ptr), 310*da58b97aSjoerg (AMDGPUstore_mskor node:$val, node:$ptr), [{ 311*da58b97aSjoerg return cast<MemSDNode>(N)->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS; 312*da58b97aSjoerg}]>; 313*da58b97aSjoerg 314*da58b97aSjoerg// FIXME: These are deprecated 31506f32e7eSjoergclass AZExtLoadBase <SDPatternOperator ld_node>: PatFrag<(ops node:$ptr), 31606f32e7eSjoerg (ld_node node:$ptr), [{ 31706f32e7eSjoerg LoadSDNode *L = cast<LoadSDNode>(N); 31806f32e7eSjoerg return L->getExtensionType() == ISD::ZEXTLOAD || 31906f32e7eSjoerg L->getExtensionType() == ISD::EXTLOAD; 32006f32e7eSjoerg}]>; 32106f32e7eSjoerg 32206f32e7eSjoergdef az_extload : AZExtLoadBase <unindexedload>; 32306f32e7eSjoerg 32406f32e7eSjoergdef az_extloadi8 : PatFrag<(ops node:$ptr), (az_extload node:$ptr), [{ 32506f32e7eSjoerg return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8; 32606f32e7eSjoerg}]>; 32706f32e7eSjoerg 32806f32e7eSjoergdef az_extloadi16 : PatFrag<(ops node:$ptr), (az_extload node:$ptr), [{ 32906f32e7eSjoerg return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16; 33006f32e7eSjoerg}]>; 33106f32e7eSjoerg 33206f32e7eSjoergdef az_extloadi32 : PatFrag<(ops node:$ptr), (az_extload node:$ptr), [{ 33306f32e7eSjoerg return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32; 33406f32e7eSjoerg}]>; 33506f32e7eSjoerg 336*da58b97aSjoerglet AddressSpaces = LoadAddress_local.AddrSpaces in { 337*da58b97aSjoergdef az_extloadi8_local : PatFrag<(ops node:$ptr), (az_extloadi8 node:$ptr)>; 338*da58b97aSjoergdef az_extloadi16_local : PatFrag<(ops node:$ptr), (az_extloadi16 node:$ptr)>; 339*da58b97aSjoerg} 34006f32e7eSjoerg 34106f32e7eSjoergclass LoadParamFrag <PatFrag load_type> : PatFrag < 34206f32e7eSjoerg (ops node:$ptr), (load_type node:$ptr), 34306f32e7eSjoerg [{ return isConstantLoad(cast<LoadSDNode>(N), 0) || 34406f32e7eSjoerg (cast<LoadSDNode>(N)->getAddressSpace() == AMDGPUAS::PARAM_I_ADDRESS); }] 34506f32e7eSjoerg>; 34606f32e7eSjoerg 34706f32e7eSjoergdef vtx_id3_az_extloadi8 : LoadParamFrag<az_extloadi8>; 34806f32e7eSjoergdef vtx_id3_az_extloadi16 : LoadParamFrag<az_extloadi16>; 34906f32e7eSjoergdef vtx_id3_load : LoadParamFrag<load>; 35006f32e7eSjoerg 35106f32e7eSjoergclass LoadVtxId1 <PatFrag load> : PatFrag < 35206f32e7eSjoerg (ops node:$ptr), (load node:$ptr), [{ 35306f32e7eSjoerg const MemSDNode *LD = cast<MemSDNode>(N); 35406f32e7eSjoerg return LD->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS || 35506f32e7eSjoerg (LD->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS && 356*da58b97aSjoerg !isa<GlobalValue>(getUnderlyingObject( 357*da58b97aSjoerg LD->getMemOperand()->getValue()))); 35806f32e7eSjoerg}]>; 35906f32e7eSjoerg 36006f32e7eSjoergdef vtx_id1_az_extloadi8 : LoadVtxId1 <az_extloadi8>; 36106f32e7eSjoergdef vtx_id1_az_extloadi16 : LoadVtxId1 <az_extloadi16>; 36206f32e7eSjoergdef vtx_id1_load : LoadVtxId1 <load>; 36306f32e7eSjoerg 36406f32e7eSjoergclass LoadVtxId2 <PatFrag load> : PatFrag < 36506f32e7eSjoerg (ops node:$ptr), (load node:$ptr), [{ 36606f32e7eSjoerg const MemSDNode *LD = cast<MemSDNode>(N); 36706f32e7eSjoerg return LD->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS && 368*da58b97aSjoerg isa<GlobalValue>(getUnderlyingObject( 369*da58b97aSjoerg LD->getMemOperand()->getValue())); 37006f32e7eSjoerg}]>; 37106f32e7eSjoerg 37206f32e7eSjoergdef vtx_id2_az_extloadi8 : LoadVtxId2 <az_extloadi8>; 37306f32e7eSjoergdef vtx_id2_az_extloadi16 : LoadVtxId2 <az_extloadi16>; 37406f32e7eSjoergdef vtx_id2_load : LoadVtxId2 <load>; 37506f32e7eSjoerg 37606f32e7eSjoerg//===----------------------------------------------------------------------===// 37706f32e7eSjoerg// R600 SDNodes 37806f32e7eSjoerg//===----------------------------------------------------------------------===// 37906f32e7eSjoerg 38006f32e7eSjoerglet Namespace = "R600" in { 38106f32e7eSjoerg 38206f32e7eSjoergdef INTERP_PAIR_XY : AMDGPUShaderInst < 38306f32e7eSjoerg (outs R600_TReg32_X:$dst0, R600_TReg32_Y:$dst1), 38406f32e7eSjoerg (ins i32imm:$src0, R600_TReg32_Y:$src1, R600_TReg32_X:$src2), 38506f32e7eSjoerg "INTERP_PAIR_XY $src0 $src1 $src2 : $dst0 dst1", 38606f32e7eSjoerg []>; 38706f32e7eSjoerg 38806f32e7eSjoergdef INTERP_PAIR_ZW : AMDGPUShaderInst < 38906f32e7eSjoerg (outs R600_TReg32_Z:$dst0, R600_TReg32_W:$dst1), 39006f32e7eSjoerg (ins i32imm:$src0, R600_TReg32_Y:$src1, R600_TReg32_X:$src2), 39106f32e7eSjoerg "INTERP_PAIR_ZW $src0 $src1 $src2 : $dst0 dst1", 39206f32e7eSjoerg []>; 39306f32e7eSjoerg 39406f32e7eSjoerg} 39506f32e7eSjoerg 39606f32e7eSjoergdef CONST_ADDRESS: SDNode<"AMDGPUISD::CONST_ADDRESS", 39706f32e7eSjoerg SDTypeProfile<1, -1, [SDTCisInt<0>, SDTCisPtrTy<1>]>, 39806f32e7eSjoerg [SDNPVariadic] 39906f32e7eSjoerg>; 40006f32e7eSjoerg 40106f32e7eSjoergdef DOT4 : SDNode<"AMDGPUISD::DOT4", 40206f32e7eSjoerg SDTypeProfile<1, 8, [SDTCisFP<0>, SDTCisVT<1, f32>, SDTCisVT<2, f32>, 40306f32e7eSjoerg SDTCisVT<3, f32>, SDTCisVT<4, f32>, SDTCisVT<5, f32>, 40406f32e7eSjoerg SDTCisVT<6, f32>, SDTCisVT<7, f32>, SDTCisVT<8, f32>]>, 40506f32e7eSjoerg [] 40606f32e7eSjoerg>; 40706f32e7eSjoerg 40806f32e7eSjoergdef COS_HW : SDNode<"AMDGPUISD::COS_HW", 40906f32e7eSjoerg SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisFP<1>]> 41006f32e7eSjoerg>; 41106f32e7eSjoerg 41206f32e7eSjoergdef SIN_HW : SDNode<"AMDGPUISD::SIN_HW", 41306f32e7eSjoerg SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisFP<1>]> 41406f32e7eSjoerg>; 41506f32e7eSjoerg 41606f32e7eSjoergdef TEXTURE_FETCH_Type : SDTypeProfile<1, 19, [SDTCisFP<0>]>; 41706f32e7eSjoerg 41806f32e7eSjoergdef TEXTURE_FETCH: SDNode<"AMDGPUISD::TEXTURE_FETCH", TEXTURE_FETCH_Type, []>; 41906f32e7eSjoerg 42006f32e7eSjoergmulticlass TexPattern<bits<32> TextureOp, Instruction inst, ValueType vt = v4f32> { 42106f32e7eSjoergdef : R600Pat<(TEXTURE_FETCH (i32 TextureOp), vt:$SRC_GPR, 42206f32e7eSjoerg (i32 imm:$srcx), (i32 imm:$srcy), (i32 imm:$srcz), (i32 imm:$srcw), 42306f32e7eSjoerg (i32 imm:$offsetx), (i32 imm:$offsety), (i32 imm:$offsetz), 42406f32e7eSjoerg (i32 imm:$DST_SEL_X), (i32 imm:$DST_SEL_Y), (i32 imm:$DST_SEL_Z), 42506f32e7eSjoerg (i32 imm:$DST_SEL_W), 42606f32e7eSjoerg (i32 imm:$RESOURCE_ID), (i32 imm:$SAMPLER_ID), 42706f32e7eSjoerg (i32 imm:$COORD_TYPE_X), (i32 imm:$COORD_TYPE_Y), (i32 imm:$COORD_TYPE_Z), 42806f32e7eSjoerg (i32 imm:$COORD_TYPE_W)), 42906f32e7eSjoerg (inst R600_Reg128:$SRC_GPR, 43006f32e7eSjoerg imm:$srcx, imm:$srcy, imm:$srcz, imm:$srcw, 43106f32e7eSjoerg imm:$offsetx, imm:$offsety, imm:$offsetz, 43206f32e7eSjoerg imm:$DST_SEL_X, imm:$DST_SEL_Y, imm:$DST_SEL_Z, 43306f32e7eSjoerg imm:$DST_SEL_W, 43406f32e7eSjoerg imm:$RESOURCE_ID, imm:$SAMPLER_ID, 43506f32e7eSjoerg imm:$COORD_TYPE_X, imm:$COORD_TYPE_Y, imm:$COORD_TYPE_Z, 43606f32e7eSjoerg imm:$COORD_TYPE_W)>; 43706f32e7eSjoerg} 43806f32e7eSjoerg 43906f32e7eSjoerg//===----------------------------------------------------------------------===// 44006f32e7eSjoerg// Interpolation Instructions 44106f32e7eSjoerg//===----------------------------------------------------------------------===// 44206f32e7eSjoerg 44306f32e7eSjoerglet Namespace = "R600" in { 44406f32e7eSjoerg 44506f32e7eSjoergdef INTERP_VEC_LOAD : AMDGPUShaderInst < 44606f32e7eSjoerg (outs R600_Reg128:$dst), 44706f32e7eSjoerg (ins i32imm:$src0), 44806f32e7eSjoerg "INTERP_LOAD $src0 : $dst">; 44906f32e7eSjoerg 45006f32e7eSjoerg} 45106f32e7eSjoerg 45206f32e7eSjoergdef INTERP_XY : R600_2OP <0xD6, "INTERP_XY", []> { 45306f32e7eSjoerg let bank_swizzle = 5; 45406f32e7eSjoerg} 45506f32e7eSjoerg 45606f32e7eSjoergdef INTERP_ZW : R600_2OP <0xD7, "INTERP_ZW", []> { 45706f32e7eSjoerg let bank_swizzle = 5; 45806f32e7eSjoerg} 45906f32e7eSjoerg 46006f32e7eSjoergdef INTERP_LOAD_P0 : R600_1OP <0xE0, "INTERP_LOAD_P0", []>; 46106f32e7eSjoerg 46206f32e7eSjoerg//===----------------------------------------------------------------------===// 46306f32e7eSjoerg// Export Instructions 46406f32e7eSjoerg//===----------------------------------------------------------------------===// 46506f32e7eSjoerg 46606f32e7eSjoergclass ExportWord0 { 46706f32e7eSjoerg field bits<32> Word0; 46806f32e7eSjoerg 46906f32e7eSjoerg bits<13> arraybase; 47006f32e7eSjoerg bits<2> type; 47106f32e7eSjoerg bits<7> gpr; 47206f32e7eSjoerg bits<2> elem_size; 47306f32e7eSjoerg 47406f32e7eSjoerg let Word0{12-0} = arraybase; 47506f32e7eSjoerg let Word0{14-13} = type; 47606f32e7eSjoerg let Word0{21-15} = gpr; 47706f32e7eSjoerg let Word0{22} = 0; // RW_REL 47806f32e7eSjoerg let Word0{29-23} = 0; // INDEX_GPR 47906f32e7eSjoerg let Word0{31-30} = elem_size; 48006f32e7eSjoerg} 48106f32e7eSjoerg 48206f32e7eSjoergclass ExportSwzWord1 { 48306f32e7eSjoerg field bits<32> Word1; 48406f32e7eSjoerg 48506f32e7eSjoerg bits<3> sw_x; 48606f32e7eSjoerg bits<3> sw_y; 48706f32e7eSjoerg bits<3> sw_z; 48806f32e7eSjoerg bits<3> sw_w; 48906f32e7eSjoerg bits<1> eop; 49006f32e7eSjoerg bits<8> inst; 49106f32e7eSjoerg 49206f32e7eSjoerg let Word1{2-0} = sw_x; 49306f32e7eSjoerg let Word1{5-3} = sw_y; 49406f32e7eSjoerg let Word1{8-6} = sw_z; 49506f32e7eSjoerg let Word1{11-9} = sw_w; 49606f32e7eSjoerg} 49706f32e7eSjoerg 49806f32e7eSjoergclass ExportBufWord1 { 49906f32e7eSjoerg field bits<32> Word1; 50006f32e7eSjoerg 50106f32e7eSjoerg bits<12> arraySize; 50206f32e7eSjoerg bits<4> compMask; 50306f32e7eSjoerg bits<1> eop; 50406f32e7eSjoerg bits<8> inst; 50506f32e7eSjoerg 50606f32e7eSjoerg let Word1{11-0} = arraySize; 50706f32e7eSjoerg let Word1{15-12} = compMask; 50806f32e7eSjoerg} 50906f32e7eSjoerg 51006f32e7eSjoergmulticlass ExportPattern<Instruction ExportInst, bits<8> cf_inst> { 51106f32e7eSjoerg def : R600Pat<(R600_EXPORT (v4f32 R600_Reg128:$src), (i32 imm:$base), (i32 imm:$type), 51206f32e7eSjoerg (i32 imm:$swz_x), (i32 imm:$swz_y), (i32 imm:$swz_z), (i32 imm:$swz_w)), 51306f32e7eSjoerg (ExportInst R600_Reg128:$src, imm:$type, imm:$base, 51406f32e7eSjoerg imm:$swz_x, imm:$swz_y, imm:$swz_z, imm:$swz_w, cf_inst, 0) 51506f32e7eSjoerg >; 51606f32e7eSjoerg 51706f32e7eSjoerg} 51806f32e7eSjoerg 51906f32e7eSjoergmulticlass SteamOutputExportPattern<Instruction ExportInst, 52006f32e7eSjoerg bits<8> buf0inst, bits<8> buf1inst, bits<8> buf2inst, bits<8> buf3inst> { 52106f32e7eSjoerg// Stream0 52206f32e7eSjoerg def : R600Pat<(int_r600_store_stream_output (v4f32 R600_Reg128:$src), 52306f32e7eSjoerg (i32 imm:$arraybase), (i32 0), (i32 imm:$mask)), 52406f32e7eSjoerg (ExportInst R600_Reg128:$src, 0, imm:$arraybase, 52506f32e7eSjoerg 4095, imm:$mask, buf0inst, 0)>; 52606f32e7eSjoerg// Stream1 52706f32e7eSjoerg def : R600Pat<(int_r600_store_stream_output (v4f32 R600_Reg128:$src), 52806f32e7eSjoerg (i32 imm:$arraybase), (i32 1), (i32 imm:$mask)), 52906f32e7eSjoerg (ExportInst $src, 0, imm:$arraybase, 53006f32e7eSjoerg 4095, imm:$mask, buf1inst, 0)>; 53106f32e7eSjoerg// Stream2 53206f32e7eSjoerg def : R600Pat<(int_r600_store_stream_output (v4f32 R600_Reg128:$src), 53306f32e7eSjoerg (i32 imm:$arraybase), (i32 2), (i32 imm:$mask)), 53406f32e7eSjoerg (ExportInst $src, 0, imm:$arraybase, 53506f32e7eSjoerg 4095, imm:$mask, buf2inst, 0)>; 53606f32e7eSjoerg// Stream3 53706f32e7eSjoerg def : R600Pat<(int_r600_store_stream_output (v4f32 R600_Reg128:$src), 53806f32e7eSjoerg (i32 imm:$arraybase), (i32 3), (i32 imm:$mask)), 53906f32e7eSjoerg (ExportInst $src, 0, imm:$arraybase, 54006f32e7eSjoerg 4095, imm:$mask, buf3inst, 0)>; 54106f32e7eSjoerg} 54206f32e7eSjoerg 54306f32e7eSjoerg// Export Instructions should not be duplicated by TailDuplication pass 54406f32e7eSjoerg// (which assumes that duplicable instruction are affected by exec mask) 54506f32e7eSjoerglet usesCustomInserter = 1, isNotDuplicable = 1 in { 54606f32e7eSjoerg 54706f32e7eSjoergclass ExportSwzInst : InstR600ISA<( 54806f32e7eSjoerg outs), 54906f32e7eSjoerg (ins R600_Reg128:$gpr, i32imm:$type, i32imm:$arraybase, 55006f32e7eSjoerg RSel:$sw_x, RSel:$sw_y, RSel:$sw_z, RSel:$sw_w, i32imm:$inst, 55106f32e7eSjoerg i32imm:$eop), 55206f32e7eSjoerg !strconcat("EXPORT", " $gpr.$sw_x$sw_y$sw_z$sw_w"), 55306f32e7eSjoerg []>, ExportWord0, ExportSwzWord1 { 55406f32e7eSjoerg let elem_size = 3; 55506f32e7eSjoerg let Inst{31-0} = Word0; 55606f32e7eSjoerg let Inst{63-32} = Word1; 55706f32e7eSjoerg let IsExport = 1; 55806f32e7eSjoerg} 55906f32e7eSjoerg 56006f32e7eSjoerg} // End usesCustomInserter = 1 56106f32e7eSjoerg 56206f32e7eSjoergclass ExportBufInst : InstR600ISA<( 56306f32e7eSjoerg outs), 56406f32e7eSjoerg (ins R600_Reg128:$gpr, i32imm:$type, i32imm:$arraybase, 56506f32e7eSjoerg i32imm:$arraySize, i32imm:$compMask, i32imm:$inst, i32imm:$eop), 56606f32e7eSjoerg !strconcat("EXPORT", " $gpr"), 56706f32e7eSjoerg []>, ExportWord0, ExportBufWord1 { 56806f32e7eSjoerg let elem_size = 0; 56906f32e7eSjoerg let Inst{31-0} = Word0; 57006f32e7eSjoerg let Inst{63-32} = Word1; 57106f32e7eSjoerg let IsExport = 1; 57206f32e7eSjoerg} 57306f32e7eSjoerg 57406f32e7eSjoerg//===----------------------------------------------------------------------===// 57506f32e7eSjoerg// Control Flow Instructions 57606f32e7eSjoerg//===----------------------------------------------------------------------===// 57706f32e7eSjoerg 57806f32e7eSjoerg 57906f32e7eSjoergdef KCACHE : InstFlag<"printKCache">; 58006f32e7eSjoerg 58106f32e7eSjoergclass ALU_CLAUSE<bits<4> inst, string OpName> : R600WrapperInst <(outs), 58206f32e7eSjoerg(ins i32imm:$ADDR, i32imm:$KCACHE_BANK0, i32imm:$KCACHE_BANK1, 58306f32e7eSjoergKCACHE:$KCACHE_MODE0, KCACHE:$KCACHE_MODE1, 58406f32e7eSjoergi32imm:$KCACHE_ADDR0, i32imm:$KCACHE_ADDR1, 58506f32e7eSjoergi32imm:$COUNT, i32imm:$Enabled), 58606f32e7eSjoerg!strconcat(OpName, " $COUNT, @$ADDR, " 58706f32e7eSjoerg"KC0[$KCACHE_MODE0], KC1[$KCACHE_MODE1]"), 58806f32e7eSjoerg[] >, CF_ALU_WORD0, CF_ALU_WORD1 { 58906f32e7eSjoerg field bits<64> Inst; 59006f32e7eSjoerg 59106f32e7eSjoerg let CF_INST = inst; 59206f32e7eSjoerg let ALT_CONST = 0; 59306f32e7eSjoerg let WHOLE_QUAD_MODE = 0; 59406f32e7eSjoerg let BARRIER = 1; 59506f32e7eSjoerg let isCodeGenOnly = 1; 59606f32e7eSjoerg let UseNamedOperandTable = 1; 59706f32e7eSjoerg 59806f32e7eSjoerg let Inst{31-0} = Word0; 59906f32e7eSjoerg let Inst{63-32} = Word1; 60006f32e7eSjoerg} 60106f32e7eSjoerg 60206f32e7eSjoergclass CF_WORD0_R600 { 60306f32e7eSjoerg field bits<32> Word0; 60406f32e7eSjoerg 60506f32e7eSjoerg bits<32> ADDR; 60606f32e7eSjoerg 60706f32e7eSjoerg let Word0 = ADDR; 60806f32e7eSjoerg} 60906f32e7eSjoerg 61006f32e7eSjoergclass CF_CLAUSE_R600 <bits<7> inst, dag ins, string AsmPrint> : R600WrapperInst <(outs), 61106f32e7eSjoergins, AsmPrint, [] >, CF_WORD0_R600, CF_WORD1_R600 { 61206f32e7eSjoerg field bits<64> Inst; 61306f32e7eSjoerg bits<4> CNT; 61406f32e7eSjoerg 61506f32e7eSjoerg let CF_INST = inst; 61606f32e7eSjoerg let BARRIER = 1; 61706f32e7eSjoerg let CF_CONST = 0; 61806f32e7eSjoerg let VALID_PIXEL_MODE = 0; 61906f32e7eSjoerg let COND = 0; 62006f32e7eSjoerg let COUNT = CNT{2-0}; 62106f32e7eSjoerg let CALL_COUNT = 0; 62206f32e7eSjoerg let COUNT_3 = CNT{3}; 62306f32e7eSjoerg let END_OF_PROGRAM = 0; 62406f32e7eSjoerg let WHOLE_QUAD_MODE = 0; 62506f32e7eSjoerg 62606f32e7eSjoerg let Inst{31-0} = Word0; 62706f32e7eSjoerg let Inst{63-32} = Word1; 62806f32e7eSjoerg} 62906f32e7eSjoerg 63006f32e7eSjoergclass CF_CLAUSE_EG <bits<8> inst, dag ins, string AsmPrint> : R600WrapperInst <(outs), 63106f32e7eSjoergins, AsmPrint, [] >, CF_WORD0_EG, CF_WORD1_EG { 63206f32e7eSjoerg field bits<64> Inst; 63306f32e7eSjoerg 63406f32e7eSjoerg let CF_INST = inst; 63506f32e7eSjoerg let BARRIER = 1; 63606f32e7eSjoerg let JUMPTABLE_SEL = 0; 63706f32e7eSjoerg let CF_CONST = 0; 63806f32e7eSjoerg let VALID_PIXEL_MODE = 0; 63906f32e7eSjoerg let COND = 0; 64006f32e7eSjoerg let END_OF_PROGRAM = 0; 64106f32e7eSjoerg 64206f32e7eSjoerg let Inst{31-0} = Word0; 64306f32e7eSjoerg let Inst{63-32} = Word1; 64406f32e7eSjoerg} 64506f32e7eSjoerg 64606f32e7eSjoergdef CF_ALU : ALU_CLAUSE<8, "ALU">; 64706f32e7eSjoergdef CF_ALU_PUSH_BEFORE : ALU_CLAUSE<9, "ALU_PUSH_BEFORE">; 64806f32e7eSjoergdef CF_ALU_POP_AFTER : ALU_CLAUSE<10, "ALU_POP_AFTER">; 64906f32e7eSjoergdef CF_ALU_CONTINUE : ALU_CLAUSE<13, "ALU_CONTINUE">; 65006f32e7eSjoergdef CF_ALU_BREAK : ALU_CLAUSE<14, "ALU_BREAK">; 65106f32e7eSjoergdef CF_ALU_ELSE_AFTER : ALU_CLAUSE<15, "ALU_ELSE_AFTER">; 65206f32e7eSjoerg 65306f32e7eSjoergdef FETCH_CLAUSE : R600WrapperInst <(outs), 65406f32e7eSjoerg(ins i32imm:$addr), "Fetch clause starting at $addr:", [] > { 65506f32e7eSjoerg field bits<8> Inst; 65606f32e7eSjoerg bits<8> num; 65706f32e7eSjoerg let Inst = num; 65806f32e7eSjoerg let isCodeGenOnly = 1; 65906f32e7eSjoerg} 66006f32e7eSjoerg 66106f32e7eSjoergdef ALU_CLAUSE : R600WrapperInst <(outs), 66206f32e7eSjoerg(ins i32imm:$addr), "ALU clause starting at $addr:", [] > { 66306f32e7eSjoerg field bits<8> Inst; 66406f32e7eSjoerg bits<8> num; 66506f32e7eSjoerg let Inst = num; 66606f32e7eSjoerg let isCodeGenOnly = 1; 66706f32e7eSjoerg} 66806f32e7eSjoerg 66906f32e7eSjoergdef LITERALS : R600WrapperInst <(outs), 67006f32e7eSjoerg(ins LITERAL:$literal1, LITERAL:$literal2), "$literal1, $literal2", [] > { 67106f32e7eSjoerg let isCodeGenOnly = 1; 67206f32e7eSjoerg 67306f32e7eSjoerg field bits<64> Inst; 67406f32e7eSjoerg bits<32> literal1; 67506f32e7eSjoerg bits<32> literal2; 67606f32e7eSjoerg 67706f32e7eSjoerg let Inst{31-0} = literal1; 67806f32e7eSjoerg let Inst{63-32} = literal2; 67906f32e7eSjoerg} 68006f32e7eSjoerg 68106f32e7eSjoergdef PAD : R600WrapperInst <(outs), (ins), "PAD", [] > { 68206f32e7eSjoerg field bits<64> Inst; 68306f32e7eSjoerg} 68406f32e7eSjoerg 68506f32e7eSjoerg//===----------------------------------------------------------------------===// 68606f32e7eSjoerg// Common Instructions R600, R700, Evergreen, Cayman 68706f32e7eSjoerg//===----------------------------------------------------------------------===// 68806f32e7eSjoerg 68906f32e7eSjoerglet isCodeGenOnly = 1, isPseudo = 1 in { 69006f32e7eSjoerg 69106f32e7eSjoerglet Namespace = "R600", usesCustomInserter = 1 in { 69206f32e7eSjoerg 69306f32e7eSjoergclass FABS <RegisterClass rc> : AMDGPUShaderInst < 69406f32e7eSjoerg (outs rc:$dst), 69506f32e7eSjoerg (ins rc:$src0), 69606f32e7eSjoerg "FABS $dst, $src0", 69706f32e7eSjoerg [(set f32:$dst, (fabs f32:$src0))] 69806f32e7eSjoerg>; 69906f32e7eSjoerg 70006f32e7eSjoergclass FNEG <RegisterClass rc> : AMDGPUShaderInst < 70106f32e7eSjoerg (outs rc:$dst), 70206f32e7eSjoerg (ins rc:$src0), 70306f32e7eSjoerg "FNEG $dst, $src0", 70406f32e7eSjoerg [(set f32:$dst, (fneg f32:$src0))] 70506f32e7eSjoerg>; 70606f32e7eSjoerg 70706f32e7eSjoerg} // usesCustomInserter = 1 70806f32e7eSjoerg 70906f32e7eSjoergmulticlass RegisterLoadStore <RegisterClass dstClass, Operand addrClass, 71006f32e7eSjoerg ComplexPattern addrPat> { 71106f32e7eSjoerglet UseNamedOperandTable = 1 in { 71206f32e7eSjoerg 71306f32e7eSjoerg def RegisterLoad : AMDGPUShaderInst < 71406f32e7eSjoerg (outs dstClass:$dst), 71506f32e7eSjoerg (ins addrClass:$addr, i32imm:$chan), 71606f32e7eSjoerg "RegisterLoad $dst, $addr", 71706f32e7eSjoerg [(set i32:$dst, (AMDGPUregister_load addrPat:$addr, (i32 timm:$chan)))] 71806f32e7eSjoerg > { 71906f32e7eSjoerg let isRegisterLoad = 1; 72006f32e7eSjoerg } 72106f32e7eSjoerg 72206f32e7eSjoerg def RegisterStore : AMDGPUShaderInst < 72306f32e7eSjoerg (outs), 72406f32e7eSjoerg (ins dstClass:$val, addrClass:$addr, i32imm:$chan), 72506f32e7eSjoerg "RegisterStore $val, $addr", 72606f32e7eSjoerg [(AMDGPUregister_store i32:$val, addrPat:$addr, (i32 timm:$chan))] 72706f32e7eSjoerg > { 72806f32e7eSjoerg let isRegisterStore = 1; 72906f32e7eSjoerg } 73006f32e7eSjoerg} 73106f32e7eSjoerg} 73206f32e7eSjoerg 73306f32e7eSjoerg} // End isCodeGenOnly = 1, isPseudo = 1 73406f32e7eSjoerg 73506f32e7eSjoerg 73606f32e7eSjoergdef ADD : R600_2OP_Helper <0x0, "ADD", fadd>; 73706f32e7eSjoerg// Non-IEEE MUL: 0 * anything = 0 73806f32e7eSjoergdef MUL : R600_2OP_Helper <0x1, "MUL NON-IEEE">; 73906f32e7eSjoergdef MUL_IEEE : R600_2OP_Helper <0x2, "MUL_IEEE", fmul>; 74006f32e7eSjoerg// TODO: Do these actually match the regular fmin/fmax behavior? 74106f32e7eSjoergdef MAX : R600_2OP_Helper <0x3, "MAX", AMDGPUfmax_legacy>; 74206f32e7eSjoergdef MIN : R600_2OP_Helper <0x4, "MIN", AMDGPUfmin_legacy>; 74306f32e7eSjoerg// According to https://msdn.microsoft.com/en-us/library/windows/desktop/cc308050%28v=vs.85%29.aspx 74406f32e7eSjoerg// DX10 min/max returns the other operand if one is NaN, 74506f32e7eSjoerg// this matches http://llvm.org/docs/LangRef.html#llvm-minnum-intrinsic 74606f32e7eSjoergdef MAX_DX10 : R600_2OP_Helper <0x5, "MAX_DX10", fmaxnum>; 74706f32e7eSjoergdef MIN_DX10 : R600_2OP_Helper <0x6, "MIN_DX10", fminnum>; 74806f32e7eSjoerg 74906f32e7eSjoerg// For the SET* instructions there is a naming conflict in TargetSelectionDAG.td, 75006f32e7eSjoerg// so some of the instruction names don't match the asm string. 75106f32e7eSjoerg// XXX: Use the defs in TargetSelectionDAG.td instead of intrinsics. 75206f32e7eSjoergdef SETE : R600_2OP < 75306f32e7eSjoerg 0x08, "SETE", 75406f32e7eSjoerg [(set f32:$dst, (selectcc f32:$src0, f32:$src1, FP_ONE, FP_ZERO, COND_OEQ))] 75506f32e7eSjoerg>; 75606f32e7eSjoerg 75706f32e7eSjoergdef SGT : R600_2OP < 75806f32e7eSjoerg 0x09, "SETGT", 75906f32e7eSjoerg [(set f32:$dst, (selectcc f32:$src0, f32:$src1, FP_ONE, FP_ZERO, COND_OGT))] 76006f32e7eSjoerg>; 76106f32e7eSjoerg 76206f32e7eSjoergdef SGE : R600_2OP < 76306f32e7eSjoerg 0xA, "SETGE", 76406f32e7eSjoerg [(set f32:$dst, (selectcc f32:$src0, f32:$src1, FP_ONE, FP_ZERO, COND_OGE))] 76506f32e7eSjoerg>; 76606f32e7eSjoerg 76706f32e7eSjoergdef SNE : R600_2OP < 76806f32e7eSjoerg 0xB, "SETNE", 76906f32e7eSjoerg [(set f32:$dst, (selectcc f32:$src0, f32:$src1, FP_ONE, FP_ZERO, COND_UNE_NE))] 77006f32e7eSjoerg>; 77106f32e7eSjoerg 77206f32e7eSjoergdef SETE_DX10 : R600_2OP < 77306f32e7eSjoerg 0xC, "SETE_DX10", 77406f32e7eSjoerg [(set i32:$dst, (selectcc f32:$src0, f32:$src1, -1, 0, COND_OEQ))] 77506f32e7eSjoerg>; 77606f32e7eSjoerg 77706f32e7eSjoergdef SETGT_DX10 : R600_2OP < 77806f32e7eSjoerg 0xD, "SETGT_DX10", 77906f32e7eSjoerg [(set i32:$dst, (selectcc f32:$src0, f32:$src1, -1, 0, COND_OGT))] 78006f32e7eSjoerg>; 78106f32e7eSjoerg 78206f32e7eSjoergdef SETGE_DX10 : R600_2OP < 78306f32e7eSjoerg 0xE, "SETGE_DX10", 78406f32e7eSjoerg [(set i32:$dst, (selectcc f32:$src0, f32:$src1, -1, 0, COND_OGE))] 78506f32e7eSjoerg>; 78606f32e7eSjoerg 78706f32e7eSjoerg// FIXME: This should probably be COND_ONE 78806f32e7eSjoergdef SETNE_DX10 : R600_2OP < 78906f32e7eSjoerg 0xF, "SETNE_DX10", 79006f32e7eSjoerg [(set i32:$dst, (selectcc f32:$src0, f32:$src1, -1, 0, COND_UNE_NE))] 79106f32e7eSjoerg>; 79206f32e7eSjoerg 79306f32e7eSjoerg// FIXME: Need combine for AMDGPUfract 79406f32e7eSjoergdef FRACT : R600_1OP_Helper <0x10, "FRACT", AMDGPUfract>; 79506f32e7eSjoergdef TRUNC : R600_1OP_Helper <0x11, "TRUNC", ftrunc>; 79606f32e7eSjoergdef CEIL : R600_1OP_Helper <0x12, "CEIL", fceil>; 79706f32e7eSjoergdef RNDNE : R600_1OP_Helper <0x13, "RNDNE", frint>; 79806f32e7eSjoergdef FLOOR : R600_1OP_Helper <0x14, "FLOOR", ffloor>; 79906f32e7eSjoerg 80006f32e7eSjoergdef MOV : R600_1OP <0x19, "MOV", []>; 80106f32e7eSjoerg 80206f32e7eSjoerg 80306f32e7eSjoerg// This is a hack to get rid of DUMMY_CHAIN nodes. 80406f32e7eSjoerg// Most DUMMY_CHAINs should be eliminated during legalization, but undef 80506f32e7eSjoerg// values can sneak in some to selection. 80606f32e7eSjoerglet isPseudo = 1, isCodeGenOnly = 1 in { 80706f32e7eSjoergdef DUMMY_CHAIN : R600WrapperInst < 80806f32e7eSjoerg (outs), 80906f32e7eSjoerg (ins), 81006f32e7eSjoerg "DUMMY_CHAIN", 81106f32e7eSjoerg [(R600dummy_chain)] 81206f32e7eSjoerg>; 81306f32e7eSjoerg} // end let isPseudo = 1, isCodeGenOnly = 1 81406f32e7eSjoerg 81506f32e7eSjoerg 81606f32e7eSjoerglet isPseudo = 1, isCodeGenOnly = 1, usesCustomInserter = 1 in { 81706f32e7eSjoerg 81806f32e7eSjoergclass MOV_IMM <ValueType vt, Operand immType> : R600WrapperInst < 81906f32e7eSjoerg (outs R600_Reg32:$dst), 82006f32e7eSjoerg (ins immType:$imm), 82106f32e7eSjoerg "", 82206f32e7eSjoerg [] 82306f32e7eSjoerg> { 82406f32e7eSjoerg let Namespace = "R600"; 82506f32e7eSjoerg} 82606f32e7eSjoerg 82706f32e7eSjoerg} // end let isPseudo = 1, isCodeGenOnly = 1, usesCustomInserter = 1 82806f32e7eSjoerg 82906f32e7eSjoergdef MOV_IMM_I32 : MOV_IMM<i32, i32imm>; 83006f32e7eSjoergdef : R600Pat < 83106f32e7eSjoerg (imm:$val), 83206f32e7eSjoerg (MOV_IMM_I32 imm:$val) 83306f32e7eSjoerg>; 83406f32e7eSjoerg 83506f32e7eSjoergdef MOV_IMM_GLOBAL_ADDR : MOV_IMM<iPTR, i32imm>; 83606f32e7eSjoergdef : R600Pat < 83706f32e7eSjoerg (AMDGPUconstdata_ptr tglobaladdr:$addr), 83806f32e7eSjoerg (MOV_IMM_GLOBAL_ADDR tglobaladdr:$addr) 83906f32e7eSjoerg>; 84006f32e7eSjoerg 84106f32e7eSjoerg 84206f32e7eSjoergdef MOV_IMM_F32 : MOV_IMM<f32, f32imm>; 84306f32e7eSjoergdef : R600Pat < 84406f32e7eSjoerg (fpimm:$val), 84506f32e7eSjoerg (MOV_IMM_F32 fpimm:$val) 84606f32e7eSjoerg>; 84706f32e7eSjoerg 84806f32e7eSjoergdef PRED_SETE : R600_2OP <0x20, "PRED_SETE", []>; 84906f32e7eSjoergdef PRED_SETGT : R600_2OP <0x21, "PRED_SETGT", []>; 85006f32e7eSjoergdef PRED_SETGE : R600_2OP <0x22, "PRED_SETGE", []>; 85106f32e7eSjoergdef PRED_SETNE : R600_2OP <0x23, "PRED_SETNE", []>; 85206f32e7eSjoerg 85306f32e7eSjoerglet hasSideEffects = 1 in { 85406f32e7eSjoerg 85506f32e7eSjoergdef KILLGT : R600_2OP <0x2D, "KILLGT", []>; 85606f32e7eSjoerg 85706f32e7eSjoerg} // end hasSideEffects 85806f32e7eSjoerg 85906f32e7eSjoergdef AND_INT : R600_2OP_Helper <0x30, "AND_INT", and>; 86006f32e7eSjoergdef OR_INT : R600_2OP_Helper <0x31, "OR_INT", or>; 86106f32e7eSjoergdef XOR_INT : R600_2OP_Helper <0x32, "XOR_INT", xor>; 86206f32e7eSjoergdef NOT_INT : R600_1OP_Helper <0x33, "NOT_INT", not>; 86306f32e7eSjoergdef ADD_INT : R600_2OP_Helper <0x34, "ADD_INT", add>; 86406f32e7eSjoergdef SUB_INT : R600_2OP_Helper <0x35, "SUB_INT", sub>; 86506f32e7eSjoergdef MAX_INT : R600_2OP_Helper <0x36, "MAX_INT", smax>; 86606f32e7eSjoergdef MIN_INT : R600_2OP_Helper <0x37, "MIN_INT", smin>; 86706f32e7eSjoergdef MAX_UINT : R600_2OP_Helper <0x38, "MAX_UINT", umax>; 86806f32e7eSjoergdef MIN_UINT : R600_2OP_Helper <0x39, "MIN_UINT", umin>; 86906f32e7eSjoerg 87006f32e7eSjoergdef SETE_INT : R600_2OP < 87106f32e7eSjoerg 0x3A, "SETE_INT", 87206f32e7eSjoerg [(set i32:$dst, (selectcc i32:$src0, i32:$src1, -1, 0, SETEQ))] 87306f32e7eSjoerg>; 87406f32e7eSjoerg 87506f32e7eSjoergdef SETGT_INT : R600_2OP < 87606f32e7eSjoerg 0x3B, "SETGT_INT", 87706f32e7eSjoerg [(set i32:$dst, (selectcc i32:$src0, i32:$src1, -1, 0, SETGT))] 87806f32e7eSjoerg>; 87906f32e7eSjoerg 88006f32e7eSjoergdef SETGE_INT : R600_2OP < 88106f32e7eSjoerg 0x3C, "SETGE_INT", 88206f32e7eSjoerg [(set i32:$dst, (selectcc i32:$src0, i32:$src1, -1, 0, SETGE))] 88306f32e7eSjoerg>; 88406f32e7eSjoerg 88506f32e7eSjoergdef SETNE_INT : R600_2OP < 88606f32e7eSjoerg 0x3D, "SETNE_INT", 88706f32e7eSjoerg [(set i32:$dst, (selectcc i32:$src0, i32:$src1, -1, 0, SETNE))] 88806f32e7eSjoerg>; 88906f32e7eSjoerg 89006f32e7eSjoergdef SETGT_UINT : R600_2OP < 89106f32e7eSjoerg 0x3E, "SETGT_UINT", 89206f32e7eSjoerg [(set i32:$dst, (selectcc i32:$src0, i32:$src1, -1, 0, SETUGT))] 89306f32e7eSjoerg>; 89406f32e7eSjoerg 89506f32e7eSjoergdef SETGE_UINT : R600_2OP < 89606f32e7eSjoerg 0x3F, "SETGE_UINT", 89706f32e7eSjoerg [(set i32:$dst, (selectcc i32:$src0, i32:$src1, -1, 0, SETUGE))] 89806f32e7eSjoerg>; 89906f32e7eSjoerg 90006f32e7eSjoergdef PRED_SETE_INT : R600_2OP <0x42, "PRED_SETE_INT", []>; 90106f32e7eSjoergdef PRED_SETGT_INT : R600_2OP <0x43, "PRED_SETGE_INT", []>; 90206f32e7eSjoergdef PRED_SETGE_INT : R600_2OP <0x44, "PRED_SETGE_INT", []>; 90306f32e7eSjoergdef PRED_SETNE_INT : R600_2OP <0x45, "PRED_SETNE_INT", []>; 90406f32e7eSjoerg 90506f32e7eSjoergdef CNDE_INT : R600_3OP < 90606f32e7eSjoerg 0x1C, "CNDE_INT", 90706f32e7eSjoerg [(set i32:$dst, (selectcc i32:$src0, 0, i32:$src1, i32:$src2, COND_EQ))] 90806f32e7eSjoerg>; 90906f32e7eSjoerg 91006f32e7eSjoergdef CNDGE_INT : R600_3OP < 91106f32e7eSjoerg 0x1E, "CNDGE_INT", 91206f32e7eSjoerg [(set i32:$dst, (selectcc i32:$src0, 0, i32:$src1, i32:$src2, COND_SGE))] 91306f32e7eSjoerg>; 91406f32e7eSjoerg 91506f32e7eSjoergdef CNDGT_INT : R600_3OP < 91606f32e7eSjoerg 0x1D, "CNDGT_INT", 91706f32e7eSjoerg [(set i32:$dst, (selectcc i32:$src0, 0, i32:$src1, i32:$src2, COND_SGT))] 91806f32e7eSjoerg>; 91906f32e7eSjoerg 92006f32e7eSjoerg//===----------------------------------------------------------------------===// 92106f32e7eSjoerg// Texture instructions 92206f32e7eSjoerg//===----------------------------------------------------------------------===// 92306f32e7eSjoerg 92406f32e7eSjoerglet mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 92506f32e7eSjoerg 92606f32e7eSjoergclass R600_TEX <bits<11> inst, string opName> : 92706f32e7eSjoerg InstR600 <(outs R600_Reg128:$DST_GPR), 92806f32e7eSjoerg (ins R600_Reg128:$SRC_GPR, 92906f32e7eSjoerg RSel:$srcx, RSel:$srcy, RSel:$srcz, RSel:$srcw, 93006f32e7eSjoerg i32imm:$offsetx, i32imm:$offsety, i32imm:$offsetz, 93106f32e7eSjoerg RSel:$DST_SEL_X, RSel:$DST_SEL_Y, RSel:$DST_SEL_Z, RSel:$DST_SEL_W, 93206f32e7eSjoerg i32imm:$RESOURCE_ID, i32imm:$SAMPLER_ID, 93306f32e7eSjoerg CT:$COORD_TYPE_X, CT:$COORD_TYPE_Y, CT:$COORD_TYPE_Z, 93406f32e7eSjoerg CT:$COORD_TYPE_W), 93506f32e7eSjoerg !strconcat(" ", opName, 93606f32e7eSjoerg " $DST_GPR.$DST_SEL_X$DST_SEL_Y$DST_SEL_Z$DST_SEL_W, " 93706f32e7eSjoerg "$SRC_GPR.$srcx$srcy$srcz$srcw " 93806f32e7eSjoerg "RID:$RESOURCE_ID SID:$SAMPLER_ID " 93906f32e7eSjoerg "CT:$COORD_TYPE_X$COORD_TYPE_Y$COORD_TYPE_Z$COORD_TYPE_W"), 94006f32e7eSjoerg [], 94106f32e7eSjoerg NullALU>, TEX_WORD0, TEX_WORD1, TEX_WORD2 { 94206f32e7eSjoerg let Inst{31-0} = Word0; 94306f32e7eSjoerg let Inst{63-32} = Word1; 94406f32e7eSjoerg 94506f32e7eSjoerg let TEX_INST = inst{4-0}; 94606f32e7eSjoerg let SRC_REL = 0; 94706f32e7eSjoerg let DST_REL = 0; 94806f32e7eSjoerg let LOD_BIAS = 0; 94906f32e7eSjoerg 95006f32e7eSjoerg let INST_MOD = 0; 95106f32e7eSjoerg let FETCH_WHOLE_QUAD = 0; 95206f32e7eSjoerg let ALT_CONST = 0; 95306f32e7eSjoerg let SAMPLER_INDEX_MODE = 0; 95406f32e7eSjoerg let RESOURCE_INDEX_MODE = 0; 95506f32e7eSjoerg 95606f32e7eSjoerg let TEXInst = 1; 95706f32e7eSjoerg} 95806f32e7eSjoerg 95906f32e7eSjoerg} // End mayLoad = 0, mayStore = 0, hasSideEffects = 0 96006f32e7eSjoerg 96106f32e7eSjoerg 96206f32e7eSjoerg 96306f32e7eSjoergdef TEX_SAMPLE : R600_TEX <0x10, "TEX_SAMPLE">; 96406f32e7eSjoergdef TEX_SAMPLE_C : R600_TEX <0x18, "TEX_SAMPLE_C">; 96506f32e7eSjoergdef TEX_SAMPLE_L : R600_TEX <0x11, "TEX_SAMPLE_L">; 96606f32e7eSjoergdef TEX_SAMPLE_C_L : R600_TEX <0x19, "TEX_SAMPLE_C_L">; 96706f32e7eSjoergdef TEX_SAMPLE_LB : R600_TEX <0x12, "TEX_SAMPLE_LB">; 96806f32e7eSjoergdef TEX_SAMPLE_C_LB : R600_TEX <0x1A, "TEX_SAMPLE_C_LB">; 96906f32e7eSjoergdef TEX_LD : R600_TEX <0x03, "TEX_LD">; 97006f32e7eSjoergdef TEX_LDPTR : R600_TEX <0x03, "TEX_LDPTR"> { 97106f32e7eSjoerg let INST_MOD = 1; 97206f32e7eSjoerg} 97306f32e7eSjoergdef TEX_GET_TEXTURE_RESINFO : R600_TEX <0x04, "TEX_GET_TEXTURE_RESINFO">; 97406f32e7eSjoergdef TEX_GET_GRADIENTS_H : R600_TEX <0x07, "TEX_GET_GRADIENTS_H">; 97506f32e7eSjoergdef TEX_GET_GRADIENTS_V : R600_TEX <0x08, "TEX_GET_GRADIENTS_V">; 97606f32e7eSjoergdef TEX_SET_GRADIENTS_H : R600_TEX <0x0B, "TEX_SET_GRADIENTS_H">; 97706f32e7eSjoergdef TEX_SET_GRADIENTS_V : R600_TEX <0x0C, "TEX_SET_GRADIENTS_V">; 97806f32e7eSjoergdef TEX_SAMPLE_G : R600_TEX <0x14, "TEX_SAMPLE_G">; 97906f32e7eSjoergdef TEX_SAMPLE_C_G : R600_TEX <0x1C, "TEX_SAMPLE_C_G">; 98006f32e7eSjoerg 98106f32e7eSjoergdefm : TexPattern<0, TEX_SAMPLE>; 98206f32e7eSjoergdefm : TexPattern<1, TEX_SAMPLE_C>; 98306f32e7eSjoergdefm : TexPattern<2, TEX_SAMPLE_L>; 98406f32e7eSjoergdefm : TexPattern<3, TEX_SAMPLE_C_L>; 98506f32e7eSjoergdefm : TexPattern<4, TEX_SAMPLE_LB>; 98606f32e7eSjoergdefm : TexPattern<5, TEX_SAMPLE_C_LB>; 98706f32e7eSjoergdefm : TexPattern<6, TEX_LD, v4i32>; 98806f32e7eSjoergdefm : TexPattern<7, TEX_GET_TEXTURE_RESINFO, v4i32>; 98906f32e7eSjoergdefm : TexPattern<8, TEX_GET_GRADIENTS_H>; 99006f32e7eSjoergdefm : TexPattern<9, TEX_GET_GRADIENTS_V>; 99106f32e7eSjoergdefm : TexPattern<10, TEX_LDPTR, v4i32>; 99206f32e7eSjoerg 99306f32e7eSjoerg//===----------------------------------------------------------------------===// 99406f32e7eSjoerg// Helper classes for common instructions 99506f32e7eSjoerg//===----------------------------------------------------------------------===// 99606f32e7eSjoerg 99706f32e7eSjoergclass MUL_LIT_Common <bits<5> inst> : R600_3OP < 99806f32e7eSjoerg inst, "MUL_LIT", 99906f32e7eSjoerg [] 100006f32e7eSjoerg>; 100106f32e7eSjoerg 100206f32e7eSjoergclass MULADD_Common <bits<5> inst> : R600_3OP < 100306f32e7eSjoerg inst, "MULADD", 100406f32e7eSjoerg [] 100506f32e7eSjoerg>; 100606f32e7eSjoerg 100706f32e7eSjoergclass MULADD_IEEE_Common <bits<5> inst> : R600_3OP < 100806f32e7eSjoerg inst, "MULADD_IEEE", 1009*da58b97aSjoerg [(set f32:$dst, (any_fmad f32:$src0, f32:$src1, f32:$src2))] 101006f32e7eSjoerg>; 101106f32e7eSjoerg 101206f32e7eSjoergclass FMA_Common <bits<5> inst> : R600_3OP < 101306f32e7eSjoerg inst, "FMA", 101406f32e7eSjoerg [(set f32:$dst, (fma f32:$src0, f32:$src1, f32:$src2))], VecALU 101506f32e7eSjoerg> 101606f32e7eSjoerg{ 101706f32e7eSjoerg let OtherPredicates = [FMA]; 101806f32e7eSjoerg} 101906f32e7eSjoerg 102006f32e7eSjoergclass CNDE_Common <bits<5> inst> : R600_3OP < 102106f32e7eSjoerg inst, "CNDE", 102206f32e7eSjoerg [(set f32:$dst, (selectcc f32:$src0, FP_ZERO, f32:$src1, f32:$src2, COND_OEQ))] 102306f32e7eSjoerg>; 102406f32e7eSjoerg 102506f32e7eSjoergclass CNDGT_Common <bits<5> inst> : R600_3OP < 102606f32e7eSjoerg inst, "CNDGT", 102706f32e7eSjoerg [(set f32:$dst, (selectcc f32:$src0, FP_ZERO, f32:$src1, f32:$src2, COND_OGT))] 102806f32e7eSjoerg> { 102906f32e7eSjoerg let Itinerary = VecALU; 103006f32e7eSjoerg} 103106f32e7eSjoerg 103206f32e7eSjoergclass CNDGE_Common <bits<5> inst> : R600_3OP < 103306f32e7eSjoerg inst, "CNDGE", 103406f32e7eSjoerg [(set f32:$dst, (selectcc f32:$src0, FP_ZERO, f32:$src1, f32:$src2, COND_OGE))] 103506f32e7eSjoerg> { 103606f32e7eSjoerg let Itinerary = VecALU; 103706f32e7eSjoerg} 103806f32e7eSjoerg 103906f32e7eSjoerg 104006f32e7eSjoerglet isCodeGenOnly = 1, isPseudo = 1, Namespace = "R600" in { 104106f32e7eSjoergclass R600_VEC2OP<list<dag> pattern> : InstR600 <(outs R600_Reg32:$dst), (ins 104206f32e7eSjoerg// Slot X 104306f32e7eSjoerg UEM:$update_exec_mask_X, UP:$update_pred_X, WRITE:$write_X, 104406f32e7eSjoerg OMOD:$omod_X, REL:$dst_rel_X, CLAMP:$clamp_X, 104506f32e7eSjoerg R600_TReg32_X:$src0_X, NEG:$src0_neg_X, REL:$src0_rel_X, ABS:$src0_abs_X, SEL:$src0_sel_X, 104606f32e7eSjoerg R600_TReg32_X:$src1_X, NEG:$src1_neg_X, REL:$src1_rel_X, ABS:$src1_abs_X, SEL:$src1_sel_X, 104706f32e7eSjoerg R600_Pred:$pred_sel_X, 104806f32e7eSjoerg// Slot Y 104906f32e7eSjoerg UEM:$update_exec_mask_Y, UP:$update_pred_Y, WRITE:$write_Y, 105006f32e7eSjoerg OMOD:$omod_Y, REL:$dst_rel_Y, CLAMP:$clamp_Y, 105106f32e7eSjoerg R600_TReg32_Y:$src0_Y, NEG:$src0_neg_Y, REL:$src0_rel_Y, ABS:$src0_abs_Y, SEL:$src0_sel_Y, 105206f32e7eSjoerg R600_TReg32_Y:$src1_Y, NEG:$src1_neg_Y, REL:$src1_rel_Y, ABS:$src1_abs_Y, SEL:$src1_sel_Y, 105306f32e7eSjoerg R600_Pred:$pred_sel_Y, 105406f32e7eSjoerg// Slot Z 105506f32e7eSjoerg UEM:$update_exec_mask_Z, UP:$update_pred_Z, WRITE:$write_Z, 105606f32e7eSjoerg OMOD:$omod_Z, REL:$dst_rel_Z, CLAMP:$clamp_Z, 105706f32e7eSjoerg R600_TReg32_Z:$src0_Z, NEG:$src0_neg_Z, REL:$src0_rel_Z, ABS:$src0_abs_Z, SEL:$src0_sel_Z, 105806f32e7eSjoerg R600_TReg32_Z:$src1_Z, NEG:$src1_neg_Z, REL:$src1_rel_Z, ABS:$src1_abs_Z, SEL:$src1_sel_Z, 105906f32e7eSjoerg R600_Pred:$pred_sel_Z, 106006f32e7eSjoerg// Slot W 106106f32e7eSjoerg UEM:$update_exec_mask_W, UP:$update_pred_W, WRITE:$write_W, 106206f32e7eSjoerg OMOD:$omod_W, REL:$dst_rel_W, CLAMP:$clamp_W, 106306f32e7eSjoerg R600_TReg32_W:$src0_W, NEG:$src0_neg_W, REL:$src0_rel_W, ABS:$src0_abs_W, SEL:$src0_sel_W, 106406f32e7eSjoerg R600_TReg32_W:$src1_W, NEG:$src1_neg_W, REL:$src1_rel_W, ABS:$src1_abs_W, SEL:$src1_sel_W, 106506f32e7eSjoerg R600_Pred:$pred_sel_W, 106606f32e7eSjoerg LITERAL:$literal0, LITERAL:$literal1), 106706f32e7eSjoerg "", 106806f32e7eSjoerg pattern, 106906f32e7eSjoerg AnyALU> { 107006f32e7eSjoerg 107106f32e7eSjoerg let UseNamedOperandTable = 1; 107206f32e7eSjoerg 107306f32e7eSjoerg} 107406f32e7eSjoerg} 107506f32e7eSjoerg 107606f32e7eSjoergdef DOT_4 : R600_VEC2OP<[(set R600_Reg32:$dst, (DOT4 107706f32e7eSjoerg R600_TReg32_X:$src0_X, R600_TReg32_X:$src1_X, 107806f32e7eSjoerg R600_TReg32_Y:$src0_Y, R600_TReg32_Y:$src1_Y, 107906f32e7eSjoerg R600_TReg32_Z:$src0_Z, R600_TReg32_Z:$src1_Z, 108006f32e7eSjoerg R600_TReg32_W:$src0_W, R600_TReg32_W:$src1_W))]>; 108106f32e7eSjoerg 108206f32e7eSjoerg 108306f32e7eSjoergclass DOT4_Common <bits<11> inst> : R600_2OP <inst, "DOT4", []>; 108406f32e7eSjoerg 108506f32e7eSjoerg 108606f32e7eSjoerglet mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 108706f32e7eSjoergmulticlass CUBE_Common <bits<11> inst> { 108806f32e7eSjoerg 108906f32e7eSjoerg def _pseudo : InstR600 < 109006f32e7eSjoerg (outs R600_Reg128:$dst), 109106f32e7eSjoerg (ins R600_Reg128:$src0), 109206f32e7eSjoerg "CUBE $dst $src0", 109306f32e7eSjoerg [(set v4f32:$dst, (int_r600_cube v4f32:$src0))], 109406f32e7eSjoerg VecALU 109506f32e7eSjoerg > { 109606f32e7eSjoerg let isPseudo = 1; 109706f32e7eSjoerg let UseNamedOperandTable = 1; 109806f32e7eSjoerg } 109906f32e7eSjoerg 110006f32e7eSjoerg def _real : R600_2OP <inst, "CUBE", []>; 110106f32e7eSjoerg} 110206f32e7eSjoerg} // End mayLoad = 0, mayStore = 0, hasSideEffects = 0 110306f32e7eSjoerg 110406f32e7eSjoergclass EXP_IEEE_Common <bits<11> inst> : R600_1OP_Helper < 110506f32e7eSjoerg inst, "EXP_IEEE", fexp2 110606f32e7eSjoerg> { 110706f32e7eSjoerg let Itinerary = TransALU; 110806f32e7eSjoerg} 110906f32e7eSjoerg 111006f32e7eSjoergclass FLT_TO_INT_Common <bits<11> inst> : R600_1OP_Helper < 111106f32e7eSjoerg inst, "FLT_TO_INT", fp_to_sint 111206f32e7eSjoerg> { 111306f32e7eSjoerg let Itinerary = TransALU; 111406f32e7eSjoerg} 111506f32e7eSjoerg 111606f32e7eSjoergclass INT_TO_FLT_Common <bits<11> inst> : R600_1OP_Helper < 111706f32e7eSjoerg inst, "INT_TO_FLT", sint_to_fp 111806f32e7eSjoerg> { 111906f32e7eSjoerg let Itinerary = TransALU; 112006f32e7eSjoerg} 112106f32e7eSjoerg 112206f32e7eSjoergclass FLT_TO_UINT_Common <bits<11> inst> : R600_1OP_Helper < 112306f32e7eSjoerg inst, "FLT_TO_UINT", fp_to_uint 112406f32e7eSjoerg> { 112506f32e7eSjoerg let Itinerary = TransALU; 112606f32e7eSjoerg} 112706f32e7eSjoerg 112806f32e7eSjoergclass UINT_TO_FLT_Common <bits<11> inst> : R600_1OP_Helper < 112906f32e7eSjoerg inst, "UINT_TO_FLT", uint_to_fp 113006f32e7eSjoerg> { 113106f32e7eSjoerg let Itinerary = TransALU; 113206f32e7eSjoerg} 113306f32e7eSjoerg 113406f32e7eSjoergclass LOG_CLAMPED_Common <bits<11> inst> : R600_1OP < 113506f32e7eSjoerg inst, "LOG_CLAMPED", [] 113606f32e7eSjoerg>; 113706f32e7eSjoerg 113806f32e7eSjoergclass LOG_IEEE_Common <bits<11> inst> : R600_1OP_Helper < 113906f32e7eSjoerg inst, "LOG_IEEE", flog2 114006f32e7eSjoerg> { 114106f32e7eSjoerg let Itinerary = TransALU; 114206f32e7eSjoerg} 114306f32e7eSjoerg 114406f32e7eSjoergclass LSHL_Common <bits<11> inst> : R600_2OP_Helper <inst, "LSHL", shl>; 114506f32e7eSjoergclass LSHR_Common <bits<11> inst> : R600_2OP_Helper <inst, "LSHR", srl>; 114606f32e7eSjoergclass ASHR_Common <bits<11> inst> : R600_2OP_Helper <inst, "ASHR", sra>; 114706f32e7eSjoergclass MULHI_INT_Common <bits<11> inst> : R600_2OP_Helper < 114806f32e7eSjoerg inst, "MULHI_INT", mulhs> { 114906f32e7eSjoerg let Itinerary = TransALU; 115006f32e7eSjoerg} 115106f32e7eSjoerg 115206f32e7eSjoergclass MULHI_INT24_Common <bits<11> inst> : R600_2OP_Helper < 115306f32e7eSjoerg inst, "MULHI_INT24", AMDGPUmulhi_i24> { 115406f32e7eSjoerg let Itinerary = VecALU; 115506f32e7eSjoerg} 115606f32e7eSjoerg 115706f32e7eSjoergclass MULHI_UINT_Common <bits<11> inst> : R600_2OP_Helper < 115806f32e7eSjoerg inst, "MULHI", mulhu> { 115906f32e7eSjoerg let Itinerary = TransALU; 116006f32e7eSjoerg} 116106f32e7eSjoerg 116206f32e7eSjoergclass MULHI_UINT24_Common <bits<11> inst> : R600_2OP_Helper < 116306f32e7eSjoerg inst, "MULHI_UINT24", AMDGPUmulhi_u24> { 116406f32e7eSjoerg let Itinerary = VecALU; 116506f32e7eSjoerg} 116606f32e7eSjoerg 116706f32e7eSjoergclass MULLO_INT_Common <bits<11> inst> : R600_2OP_Helper < 116806f32e7eSjoerg inst, "MULLO_INT", mul> { 116906f32e7eSjoerg let Itinerary = TransALU; 117006f32e7eSjoerg} 117106f32e7eSjoergclass MULLO_UINT_Common <bits<11> inst> : R600_2OP <inst, "MULLO_UINT", []> { 117206f32e7eSjoerg let Itinerary = TransALU; 117306f32e7eSjoerg} 117406f32e7eSjoerg 117506f32e7eSjoergclass RECIP_CLAMPED_Common <bits<11> inst> : R600_1OP < 117606f32e7eSjoerg inst, "RECIP_CLAMPED", [] 117706f32e7eSjoerg> { 117806f32e7eSjoerg let Itinerary = TransALU; 117906f32e7eSjoerg} 118006f32e7eSjoerg 118106f32e7eSjoergclass RECIP_IEEE_Common <bits<11> inst> : R600_1OP < 118206f32e7eSjoerg inst, "RECIP_IEEE", [(set f32:$dst, (AMDGPUrcp f32:$src0))] 118306f32e7eSjoerg> { 118406f32e7eSjoerg let Itinerary = TransALU; 118506f32e7eSjoerg} 118606f32e7eSjoerg 118706f32e7eSjoergclass RECIP_UINT_Common <bits<11> inst> : R600_1OP_Helper < 118806f32e7eSjoerg inst, "RECIP_UINT", AMDGPUurecip 118906f32e7eSjoerg> { 119006f32e7eSjoerg let Itinerary = TransALU; 119106f32e7eSjoerg} 119206f32e7eSjoerg 119306f32e7eSjoerg// Clamped to maximum. 119406f32e7eSjoergclass RECIPSQRT_CLAMPED_Common <bits<11> inst> : R600_1OP_Helper < 119506f32e7eSjoerg inst, "RECIPSQRT_CLAMPED", AMDGPUrsq_clamp 119606f32e7eSjoerg> { 119706f32e7eSjoerg let Itinerary = TransALU; 119806f32e7eSjoerg} 119906f32e7eSjoerg 120006f32e7eSjoergclass RECIPSQRT_IEEE_Common <bits<11> inst> : R600_1OP_Helper < 120106f32e7eSjoerg inst, "RECIPSQRT_IEEE", AMDGPUrsq> { 120206f32e7eSjoerg let Itinerary = TransALU; 120306f32e7eSjoerg} 120406f32e7eSjoerg 120506f32e7eSjoerg// TODO: There is also RECIPSQRT_FF which clamps to zero. 120606f32e7eSjoerg 120706f32e7eSjoergclass SIN_Common <bits<11> inst> : R600_1OP < 120806f32e7eSjoerg inst, "SIN", [(set f32:$dst, (SIN_HW f32:$src0))]>{ 120906f32e7eSjoerg let Trig = 1; 121006f32e7eSjoerg let Itinerary = TransALU; 121106f32e7eSjoerg} 121206f32e7eSjoerg 121306f32e7eSjoergclass COS_Common <bits<11> inst> : R600_1OP < 121406f32e7eSjoerg inst, "COS", [(set f32:$dst, (COS_HW f32:$src0))]> { 121506f32e7eSjoerg let Trig = 1; 121606f32e7eSjoerg let Itinerary = TransALU; 121706f32e7eSjoerg} 121806f32e7eSjoerg 121906f32e7eSjoergdef FABS_R600 : FABS<R600_Reg32>; 122006f32e7eSjoergdef FNEG_R600 : FNEG<R600_Reg32>; 122106f32e7eSjoerg 122206f32e7eSjoerg//===----------------------------------------------------------------------===// 122306f32e7eSjoerg// Helper patterns for complex intrinsics 122406f32e7eSjoerg//===----------------------------------------------------------------------===// 122506f32e7eSjoerg 122606f32e7eSjoerg// FIXME: Should be predicated on unsafe fp math. 122706f32e7eSjoergmulticlass DIV_Common <InstR600 recip_ieee> { 122806f32e7eSjoergdef : R600Pat< 122906f32e7eSjoerg (fdiv f32:$src0, f32:$src1), 123006f32e7eSjoerg (MUL_IEEE $src0, (recip_ieee $src1)) 123106f32e7eSjoerg>; 123206f32e7eSjoerg 123306f32e7eSjoergdef : RcpPat<recip_ieee, f32>; 123406f32e7eSjoerg} 123506f32e7eSjoerg 1236*da58b97aSjoergclass SqrtPat<Instruction RsqInst, Instruction RecipInst> : R600Pat < 1237*da58b97aSjoerg (fsqrt f32:$src), 1238*da58b97aSjoerg (RecipInst (RsqInst $src)) 1239*da58b97aSjoerg>; 1240*da58b97aSjoerg 124106f32e7eSjoerg//===----------------------------------------------------------------------===// 124206f32e7eSjoerg// R600 / R700 Instructions 124306f32e7eSjoerg//===----------------------------------------------------------------------===// 124406f32e7eSjoerg 124506f32e7eSjoerglet Predicates = [isR600] in { 124606f32e7eSjoerg 124706f32e7eSjoerg def MUL_LIT_r600 : MUL_LIT_Common<0x0C>; 124806f32e7eSjoerg def MULADD_r600 : MULADD_Common<0x10>; 124906f32e7eSjoerg def MULADD_IEEE_r600 : MULADD_IEEE_Common<0x14>; 125006f32e7eSjoerg def CNDE_r600 : CNDE_Common<0x18>; 125106f32e7eSjoerg def CNDGT_r600 : CNDGT_Common<0x19>; 125206f32e7eSjoerg def CNDGE_r600 : CNDGE_Common<0x1A>; 125306f32e7eSjoerg def DOT4_r600 : DOT4_Common<0x50>; 125406f32e7eSjoerg defm CUBE_r600 : CUBE_Common<0x52>; 125506f32e7eSjoerg def EXP_IEEE_r600 : EXP_IEEE_Common<0x61>; 125606f32e7eSjoerg def LOG_CLAMPED_r600 : LOG_CLAMPED_Common<0x62>; 125706f32e7eSjoerg def LOG_IEEE_r600 : LOG_IEEE_Common<0x63>; 125806f32e7eSjoerg def RECIP_CLAMPED_r600 : RECIP_CLAMPED_Common<0x64>; 125906f32e7eSjoerg def RECIP_IEEE_r600 : RECIP_IEEE_Common<0x66>; 126006f32e7eSjoerg def RECIPSQRT_CLAMPED_r600 : RECIPSQRT_CLAMPED_Common<0x67>; 126106f32e7eSjoerg def RECIPSQRT_IEEE_r600 : RECIPSQRT_IEEE_Common<0x69>; 126206f32e7eSjoerg def FLT_TO_INT_r600 : FLT_TO_INT_Common<0x6b>; 126306f32e7eSjoerg def INT_TO_FLT_r600 : INT_TO_FLT_Common<0x6c>; 126406f32e7eSjoerg def FLT_TO_UINT_r600 : FLT_TO_UINT_Common<0x79>; 126506f32e7eSjoerg def UINT_TO_FLT_r600 : UINT_TO_FLT_Common<0x6d>; 126606f32e7eSjoerg def SIN_r600 : SIN_Common<0x6E>; 126706f32e7eSjoerg def COS_r600 : COS_Common<0x6F>; 126806f32e7eSjoerg def ASHR_r600 : ASHR_Common<0x70>; 126906f32e7eSjoerg def LSHR_r600 : LSHR_Common<0x71>; 127006f32e7eSjoerg def LSHL_r600 : LSHL_Common<0x72>; 127106f32e7eSjoerg def MULLO_INT_r600 : MULLO_INT_Common<0x73>; 127206f32e7eSjoerg def MULHI_INT_r600 : MULHI_INT_Common<0x74>; 127306f32e7eSjoerg def MULLO_UINT_r600 : MULLO_UINT_Common<0x75>; 127406f32e7eSjoerg def MULHI_UINT_r600 : MULHI_UINT_Common<0x76>; 127506f32e7eSjoerg def RECIP_UINT_r600 : RECIP_UINT_Common <0x78>; 127606f32e7eSjoerg 127706f32e7eSjoerg defm DIV_r600 : DIV_Common<RECIP_IEEE_r600>; 127806f32e7eSjoerg def : POW_Common <LOG_IEEE_r600, EXP_IEEE_r600, MUL>; 127906f32e7eSjoerg 128006f32e7eSjoerg def : RsqPat<RECIPSQRT_IEEE_r600, f32>; 1281*da58b97aSjoerg def : SqrtPat<RECIPSQRT_IEEE_r600, RECIP_IEEE_r600>; 128206f32e7eSjoerg 128306f32e7eSjoerg def R600_ExportSwz : ExportSwzInst { 128406f32e7eSjoerg let Word1{20-17} = 0; // BURST_COUNT 128506f32e7eSjoerg let Word1{21} = eop; 128606f32e7eSjoerg let Word1{22} = 0; // VALID_PIXEL_MODE 128706f32e7eSjoerg let Word1{30-23} = inst; 128806f32e7eSjoerg let Word1{31} = 1; // BARRIER 128906f32e7eSjoerg } 129006f32e7eSjoerg defm : ExportPattern<R600_ExportSwz, 39>; 129106f32e7eSjoerg 129206f32e7eSjoerg def R600_ExportBuf : ExportBufInst { 129306f32e7eSjoerg let Word1{20-17} = 0; // BURST_COUNT 129406f32e7eSjoerg let Word1{21} = eop; 129506f32e7eSjoerg let Word1{22} = 0; // VALID_PIXEL_MODE 129606f32e7eSjoerg let Word1{30-23} = inst; 129706f32e7eSjoerg let Word1{31} = 1; // BARRIER 129806f32e7eSjoerg } 129906f32e7eSjoerg defm : SteamOutputExportPattern<R600_ExportBuf, 0x20, 0x21, 0x22, 0x23>; 130006f32e7eSjoerg 130106f32e7eSjoerg def CF_TC_R600 : CF_CLAUSE_R600<1, (ins i32imm:$ADDR, i32imm:$CNT), 130206f32e7eSjoerg "TEX $CNT @$ADDR"> { 130306f32e7eSjoerg let POP_COUNT = 0; 130406f32e7eSjoerg } 130506f32e7eSjoerg def CF_VC_R600 : CF_CLAUSE_R600<2, (ins i32imm:$ADDR, i32imm:$CNT), 130606f32e7eSjoerg "VTX $CNT @$ADDR"> { 130706f32e7eSjoerg let POP_COUNT = 0; 130806f32e7eSjoerg } 130906f32e7eSjoerg def WHILE_LOOP_R600 : CF_CLAUSE_R600<6, (ins i32imm:$ADDR), 131006f32e7eSjoerg "LOOP_START_DX10 @$ADDR"> { 131106f32e7eSjoerg let POP_COUNT = 0; 131206f32e7eSjoerg let CNT = 0; 131306f32e7eSjoerg } 131406f32e7eSjoerg def END_LOOP_R600 : CF_CLAUSE_R600<5, (ins i32imm:$ADDR), "END_LOOP @$ADDR"> { 131506f32e7eSjoerg let POP_COUNT = 0; 131606f32e7eSjoerg let CNT = 0; 131706f32e7eSjoerg } 131806f32e7eSjoerg def LOOP_BREAK_R600 : CF_CLAUSE_R600<9, (ins i32imm:$ADDR), 131906f32e7eSjoerg "LOOP_BREAK @$ADDR"> { 132006f32e7eSjoerg let POP_COUNT = 0; 132106f32e7eSjoerg let CNT = 0; 132206f32e7eSjoerg } 132306f32e7eSjoerg def CF_CONTINUE_R600 : CF_CLAUSE_R600<8, (ins i32imm:$ADDR), 132406f32e7eSjoerg "CONTINUE @$ADDR"> { 132506f32e7eSjoerg let POP_COUNT = 0; 132606f32e7eSjoerg let CNT = 0; 132706f32e7eSjoerg } 132806f32e7eSjoerg def CF_JUMP_R600 : CF_CLAUSE_R600<10, (ins i32imm:$ADDR, i32imm:$POP_COUNT), 132906f32e7eSjoerg "JUMP @$ADDR POP:$POP_COUNT"> { 133006f32e7eSjoerg let CNT = 0; 133106f32e7eSjoerg } 133206f32e7eSjoerg def CF_PUSH_ELSE_R600 : CF_CLAUSE_R600<12, (ins i32imm:$ADDR), 133306f32e7eSjoerg "PUSH_ELSE @$ADDR"> { 133406f32e7eSjoerg let CNT = 0; 133506f32e7eSjoerg let POP_COUNT = 0; // FIXME? 133606f32e7eSjoerg } 133706f32e7eSjoerg def CF_ELSE_R600 : CF_CLAUSE_R600<13, (ins i32imm:$ADDR, i32imm:$POP_COUNT), 133806f32e7eSjoerg "ELSE @$ADDR POP:$POP_COUNT"> { 133906f32e7eSjoerg let CNT = 0; 134006f32e7eSjoerg } 134106f32e7eSjoerg def CF_CALL_FS_R600 : CF_CLAUSE_R600<19, (ins), "CALL_FS"> { 134206f32e7eSjoerg let ADDR = 0; 134306f32e7eSjoerg let CNT = 0; 134406f32e7eSjoerg let POP_COUNT = 0; 134506f32e7eSjoerg } 134606f32e7eSjoerg def POP_R600 : CF_CLAUSE_R600<14, (ins i32imm:$ADDR, i32imm:$POP_COUNT), 134706f32e7eSjoerg "POP @$ADDR POP:$POP_COUNT"> { 134806f32e7eSjoerg let CNT = 0; 134906f32e7eSjoerg } 135006f32e7eSjoerg def CF_END_R600 : CF_CLAUSE_R600<0, (ins), "CF_END"> { 135106f32e7eSjoerg let CNT = 0; 135206f32e7eSjoerg let POP_COUNT = 0; 135306f32e7eSjoerg let ADDR = 0; 135406f32e7eSjoerg let END_OF_PROGRAM = 1; 135506f32e7eSjoerg } 135606f32e7eSjoerg 135706f32e7eSjoerg} 135806f32e7eSjoerg 135906f32e7eSjoerg 136006f32e7eSjoerg//===----------------------------------------------------------------------===// 136106f32e7eSjoerg// Regist loads and stores - for indirect addressing 136206f32e7eSjoerg//===----------------------------------------------------------------------===// 136306f32e7eSjoerg 136406f32e7eSjoerglet Namespace = "R600" in { 136506f32e7eSjoergdefm R600_ : RegisterLoadStore <R600_Reg32, FRAMEri, ADDRIndirect>; 136606f32e7eSjoerg} 136706f32e7eSjoerg 136806f32e7eSjoerg// Hardcode channel to 0 136906f32e7eSjoerg// NOTE: LSHR is not available here. LSHR is per family instruction 137006f32e7eSjoergdef : R600Pat < 137106f32e7eSjoerg (i32 (load_private ADDRIndirect:$addr) ), 137206f32e7eSjoerg (R600_RegisterLoad FRAMEri:$addr, (i32 0)) 137306f32e7eSjoerg>; 137406f32e7eSjoergdef : R600Pat < 137506f32e7eSjoerg (store_private i32:$val, ADDRIndirect:$addr), 137606f32e7eSjoerg (R600_RegisterStore i32:$val, FRAMEri:$addr, (i32 0)) 137706f32e7eSjoerg>; 137806f32e7eSjoerg 137906f32e7eSjoerg 138006f32e7eSjoerg//===----------------------------------------------------------------------===// 138106f32e7eSjoerg// Pseudo instructions 138206f32e7eSjoerg//===----------------------------------------------------------------------===// 138306f32e7eSjoerg 138406f32e7eSjoerglet isPseudo = 1 in { 138506f32e7eSjoerg 138606f32e7eSjoergdef PRED_X : InstR600 < 138706f32e7eSjoerg (outs R600_Predicate_Bit:$dst), 138806f32e7eSjoerg (ins R600_Reg32:$src0, i32imm:$src1, i32imm:$flags), 138906f32e7eSjoerg "", [], NullALU> { 139006f32e7eSjoerg let FlagOperandIdx = 3; 139106f32e7eSjoerg} 139206f32e7eSjoerg 139306f32e7eSjoerglet isTerminator = 1, isBranch = 1 in { 139406f32e7eSjoergdef JUMP_COND : InstR600 < 139506f32e7eSjoerg (outs), 139606f32e7eSjoerg (ins brtarget:$target, R600_Predicate_Bit:$p), 139706f32e7eSjoerg "JUMP $target ($p)", 139806f32e7eSjoerg [], AnyALU 139906f32e7eSjoerg >; 140006f32e7eSjoerg 140106f32e7eSjoergdef JUMP : InstR600 < 140206f32e7eSjoerg (outs), 140306f32e7eSjoerg (ins brtarget:$target), 140406f32e7eSjoerg "JUMP $target", 140506f32e7eSjoerg [], AnyALU 140606f32e7eSjoerg > 140706f32e7eSjoerg{ 140806f32e7eSjoerg let isPredicable = 1; 140906f32e7eSjoerg let isBarrier = 1; 141006f32e7eSjoerg} 141106f32e7eSjoerg 141206f32e7eSjoerg} // End isTerminator = 1, isBranch = 1 141306f32e7eSjoerg 141406f32e7eSjoerglet usesCustomInserter = 1 in { 141506f32e7eSjoerg 141606f32e7eSjoerglet mayLoad = 0, mayStore = 0, hasSideEffects = 1 in { 141706f32e7eSjoerg 141806f32e7eSjoergdef MASK_WRITE : InstR600 < 141906f32e7eSjoerg (outs), 142006f32e7eSjoerg (ins R600_Reg32:$src), 142106f32e7eSjoerg "MASK_WRITE $src", 142206f32e7eSjoerg [], 142306f32e7eSjoerg NullALU 142406f32e7eSjoerg>; 142506f32e7eSjoerg 142606f32e7eSjoerg} // End mayLoad = 0, mayStore = 0, hasSideEffects = 1 142706f32e7eSjoerg 142806f32e7eSjoerg 142906f32e7eSjoergdef TXD: InstR600 < 143006f32e7eSjoerg (outs R600_Reg128:$dst), 143106f32e7eSjoerg (ins R600_Reg128:$src0, R600_Reg128:$src1, R600_Reg128:$src2, 143206f32e7eSjoerg i32imm:$resourceId, i32imm:$samplerId, i32imm:$textureTarget), 143306f32e7eSjoerg "TXD $dst, $src0, $src1, $src2, $resourceId, $samplerId, $textureTarget", [], 143406f32e7eSjoerg NullALU > { 143506f32e7eSjoerg let TEXInst = 1; 143606f32e7eSjoerg} 143706f32e7eSjoerg 143806f32e7eSjoergdef TXD_SHADOW: InstR600 < 143906f32e7eSjoerg (outs R600_Reg128:$dst), 144006f32e7eSjoerg (ins R600_Reg128:$src0, R600_Reg128:$src1, R600_Reg128:$src2, 144106f32e7eSjoerg i32imm:$resourceId, i32imm:$samplerId, i32imm:$textureTarget), 144206f32e7eSjoerg "TXD_SHADOW $dst, $src0, $src1, $src2, $resourceId, $samplerId, $textureTarget", 144306f32e7eSjoerg [], NullALU> { 144406f32e7eSjoerg let TEXInst = 1; 144506f32e7eSjoerg} 144606f32e7eSjoerg} // End isPseudo = 1 144706f32e7eSjoerg} // End usesCustomInserter = 1 144806f32e7eSjoerg 144906f32e7eSjoerg 145006f32e7eSjoerg//===----------------------------------------------------------------------===// 145106f32e7eSjoerg// Constant Buffer Addressing Support 145206f32e7eSjoerg//===----------------------------------------------------------------------===// 145306f32e7eSjoerg 145406f32e7eSjoerglet usesCustomInserter = 1, isCodeGenOnly = 1, isPseudo = 1, Namespace = "R600" in { 145506f32e7eSjoergdef CONST_COPY : Instruction { 145606f32e7eSjoerg let OutOperandList = (outs R600_Reg32:$dst); 145706f32e7eSjoerg let InOperandList = (ins i32imm:$src); 145806f32e7eSjoerg let Pattern = 145906f32e7eSjoerg [(set R600_Reg32:$dst, (CONST_ADDRESS ADDRGA_CONST_OFFSET:$src))]; 146006f32e7eSjoerg let AsmString = "CONST_COPY"; 146106f32e7eSjoerg let hasSideEffects = 0; 146206f32e7eSjoerg let isAsCheapAsAMove = 1; 146306f32e7eSjoerg let Itinerary = NullALU; 146406f32e7eSjoerg} 146506f32e7eSjoerg} // end usesCustomInserter = 1, isCodeGenOnly = 1, isPseudo = 1, Namespace = "AMDGPU" 146606f32e7eSjoerg 146706f32e7eSjoergdef TEX_VTX_CONSTBUF : 146806f32e7eSjoerg InstR600ISA <(outs R600_Reg128:$dst), (ins MEMxi:$ptr, i32imm:$buffer_id), "VTX_READ_eg $dst, $ptr", 146906f32e7eSjoerg [(set v4i32:$dst, (CONST_ADDRESS ADDRGA_VAR_OFFSET:$ptr, (i32 imm:$buffer_id)))]>, 147006f32e7eSjoerg VTX_WORD1_GPR, VTX_WORD0_eg { 147106f32e7eSjoerg 147206f32e7eSjoerg let VC_INST = 0; 147306f32e7eSjoerg let FETCH_TYPE = 2; 147406f32e7eSjoerg let FETCH_WHOLE_QUAD = 0; 147506f32e7eSjoerg let SRC_REL = 0; 147606f32e7eSjoerg let SRC_SEL_X = 0; 147706f32e7eSjoerg let DST_REL = 0; 147806f32e7eSjoerg let USE_CONST_FIELDS = 0; 147906f32e7eSjoerg let NUM_FORMAT_ALL = 2; 148006f32e7eSjoerg let FORMAT_COMP_ALL = 1; 148106f32e7eSjoerg let SRF_MODE_ALL = 1; 148206f32e7eSjoerg let MEGA_FETCH_COUNT = 16; 148306f32e7eSjoerg let DST_SEL_X = 0; 148406f32e7eSjoerg let DST_SEL_Y = 1; 148506f32e7eSjoerg let DST_SEL_Z = 2; 148606f32e7eSjoerg let DST_SEL_W = 3; 148706f32e7eSjoerg let DATA_FORMAT = 35; 148806f32e7eSjoerg 148906f32e7eSjoerg let Inst{31-0} = Word0; 149006f32e7eSjoerg let Inst{63-32} = Word1; 149106f32e7eSjoerg 149206f32e7eSjoerg// LLVM can only encode 64-bit instructions, so these fields are manually 149306f32e7eSjoerg// encoded in R600CodeEmitter 149406f32e7eSjoerg// 149506f32e7eSjoerg// bits<16> OFFSET; 149606f32e7eSjoerg// bits<2> ENDIAN_SWAP = 0; 149706f32e7eSjoerg// bits<1> CONST_BUF_NO_STRIDE = 0; 149806f32e7eSjoerg// bits<1> MEGA_FETCH = 0; 149906f32e7eSjoerg// bits<1> ALT_CONST = 0; 150006f32e7eSjoerg// bits<2> BUFFER_INDEX_MODE = 0; 150106f32e7eSjoerg 150206f32e7eSjoerg 150306f32e7eSjoerg 150406f32e7eSjoerg// VTX_WORD2 (LLVM can only encode 64-bit instructions, so WORD2 encoding 150506f32e7eSjoerg// is done in R600CodeEmitter 150606f32e7eSjoerg// 150706f32e7eSjoerg// Inst{79-64} = OFFSET; 150806f32e7eSjoerg// Inst{81-80} = ENDIAN_SWAP; 150906f32e7eSjoerg// Inst{82} = CONST_BUF_NO_STRIDE; 151006f32e7eSjoerg// Inst{83} = MEGA_FETCH; 151106f32e7eSjoerg// Inst{84} = ALT_CONST; 151206f32e7eSjoerg// Inst{86-85} = BUFFER_INDEX_MODE; 151306f32e7eSjoerg// Inst{95-86} = 0; Reserved 151406f32e7eSjoerg 151506f32e7eSjoerg// VTX_WORD3 (Padding) 151606f32e7eSjoerg// 151706f32e7eSjoerg// Inst{127-96} = 0; 151806f32e7eSjoerg let VTXInst = 1; 151906f32e7eSjoerg} 152006f32e7eSjoerg 152106f32e7eSjoergdef TEX_VTX_TEXBUF: 152206f32e7eSjoerg InstR600ISA <(outs R600_Reg128:$dst), (ins MEMxi:$ptr, i32imm:$buffer_id), "TEX_VTX_EXPLICIT_READ $dst, $ptr">, 152306f32e7eSjoergVTX_WORD1_GPR, VTX_WORD0_eg { 152406f32e7eSjoerg 152506f32e7eSjoerglet VC_INST = 0; 152606f32e7eSjoerglet FETCH_TYPE = 2; 152706f32e7eSjoerglet FETCH_WHOLE_QUAD = 0; 152806f32e7eSjoerglet SRC_REL = 0; 152906f32e7eSjoerglet SRC_SEL_X = 0; 153006f32e7eSjoerglet DST_REL = 0; 153106f32e7eSjoerglet USE_CONST_FIELDS = 1; 153206f32e7eSjoerglet NUM_FORMAT_ALL = 0; 153306f32e7eSjoerglet FORMAT_COMP_ALL = 0; 153406f32e7eSjoerglet SRF_MODE_ALL = 1; 153506f32e7eSjoerglet MEGA_FETCH_COUNT = 16; 153606f32e7eSjoerglet DST_SEL_X = 0; 153706f32e7eSjoerglet DST_SEL_Y = 1; 153806f32e7eSjoerglet DST_SEL_Z = 2; 153906f32e7eSjoerglet DST_SEL_W = 3; 154006f32e7eSjoerglet DATA_FORMAT = 0; 154106f32e7eSjoerg 154206f32e7eSjoerglet Inst{31-0} = Word0; 154306f32e7eSjoerglet Inst{63-32} = Word1; 154406f32e7eSjoerg 154506f32e7eSjoerg// LLVM can only encode 64-bit instructions, so these fields are manually 154606f32e7eSjoerg// encoded in R600CodeEmitter 154706f32e7eSjoerg// 154806f32e7eSjoerg// bits<16> OFFSET; 154906f32e7eSjoerg// bits<2> ENDIAN_SWAP = 0; 155006f32e7eSjoerg// bits<1> CONST_BUF_NO_STRIDE = 0; 155106f32e7eSjoerg// bits<1> MEGA_FETCH = 0; 155206f32e7eSjoerg// bits<1> ALT_CONST = 0; 155306f32e7eSjoerg// bits<2> BUFFER_INDEX_MODE = 0; 155406f32e7eSjoerg 155506f32e7eSjoerg 155606f32e7eSjoerg 155706f32e7eSjoerg// VTX_WORD2 (LLVM can only encode 64-bit instructions, so WORD2 encoding 155806f32e7eSjoerg// is done in R600CodeEmitter 155906f32e7eSjoerg// 156006f32e7eSjoerg// Inst{79-64} = OFFSET; 156106f32e7eSjoerg// Inst{81-80} = ENDIAN_SWAP; 156206f32e7eSjoerg// Inst{82} = CONST_BUF_NO_STRIDE; 156306f32e7eSjoerg// Inst{83} = MEGA_FETCH; 156406f32e7eSjoerg// Inst{84} = ALT_CONST; 156506f32e7eSjoerg// Inst{86-85} = BUFFER_INDEX_MODE; 156606f32e7eSjoerg// Inst{95-86} = 0; Reserved 156706f32e7eSjoerg 156806f32e7eSjoerg// VTX_WORD3 (Padding) 156906f32e7eSjoerg// 157006f32e7eSjoerg// Inst{127-96} = 0; 157106f32e7eSjoerg let VTXInst = 1; 157206f32e7eSjoerg} 157306f32e7eSjoerg 157406f32e7eSjoerg//===---------------------------------------------------------------------===// 157506f32e7eSjoerg// Flow and Program control Instructions 157606f32e7eSjoerg//===---------------------------------------------------------------------===// 157706f32e7eSjoerg 157806f32e7eSjoergmulticlass BranchConditional<SDNode Op, RegisterClass rci, RegisterClass rcf> { 157906f32e7eSjoerg def _i32 : ILFormat<(outs), 158006f32e7eSjoerg (ins brtarget:$target, rci:$src0), 158106f32e7eSjoerg "; i32 Pseudo branch instruction", 158206f32e7eSjoerg [(Op bb:$target, (i32 rci:$src0))]>; 158306f32e7eSjoerg def _f32 : ILFormat<(outs), 158406f32e7eSjoerg (ins brtarget:$target, rcf:$src0), 158506f32e7eSjoerg "; f32 Pseudo branch instruction", 158606f32e7eSjoerg [(Op bb:$target, (f32 rcf:$src0))]>; 158706f32e7eSjoerg} 158806f32e7eSjoerg 158906f32e7eSjoerg// Only scalar types should generate flow control 159006f32e7eSjoergmulticlass BranchInstr<string name> { 159106f32e7eSjoerg def _i32 : ILFormat<(outs), (ins R600_Reg32:$src), 159206f32e7eSjoerg !strconcat(name, " $src"), []>; 159306f32e7eSjoerg def _f32 : ILFormat<(outs), (ins R600_Reg32:$src), 159406f32e7eSjoerg !strconcat(name, " $src"), []>; 159506f32e7eSjoerg} 159606f32e7eSjoerg// Only scalar types should generate flow control 159706f32e7eSjoergmulticlass BranchInstr2<string name> { 159806f32e7eSjoerg def _i32 : ILFormat<(outs), (ins R600_Reg32:$src0, R600_Reg32:$src1), 159906f32e7eSjoerg !strconcat(name, " $src0, $src1"), []>; 160006f32e7eSjoerg def _f32 : ILFormat<(outs), (ins R600_Reg32:$src0, R600_Reg32:$src1), 160106f32e7eSjoerg !strconcat(name, " $src0, $src1"), []>; 160206f32e7eSjoerg} 160306f32e7eSjoerg 160406f32e7eSjoerg//===---------------------------------------------------------------------===// 160506f32e7eSjoerg// Custom Inserter for Branches and returns, this eventually will be a 160606f32e7eSjoerg// separate pass 160706f32e7eSjoerg//===---------------------------------------------------------------------===// 160806f32e7eSjoerglet isTerminator = 1, usesCustomInserter = 1, isBranch = 1, isBarrier = 1, 160906f32e7eSjoerg Namespace = "R600" in { 161006f32e7eSjoerg def BRANCH : ILFormat<(outs), (ins brtarget:$target), 161106f32e7eSjoerg "; Pseudo unconditional branch instruction", 161206f32e7eSjoerg [(br bb:$target)]>; 161306f32e7eSjoerg defm BRANCH_COND : BranchConditional<IL_brcond, R600_Reg32, R600_Reg32>; 161406f32e7eSjoerg} 161506f32e7eSjoerg 161606f32e7eSjoerg//===----------------------------------------------------------------------===// 161706f32e7eSjoerg// Branch Instructions 161806f32e7eSjoerg//===----------------------------------------------------------------------===// 161906f32e7eSjoerg 162006f32e7eSjoergdef IF_PREDICATE_SET : ILFormat<(outs), (ins R600_Reg32:$src), 162106f32e7eSjoerg "IF_PREDICATE_SET $src", []>; 162206f32e7eSjoerg 162306f32e7eSjoerglet isTerminator=1 in { 162406f32e7eSjoerg def BREAK : ILFormat< (outs), (ins), 162506f32e7eSjoerg "BREAK", []>; 162606f32e7eSjoerg def CONTINUE : ILFormat< (outs), (ins), 162706f32e7eSjoerg "CONTINUE", []>; 162806f32e7eSjoerg def DEFAULT : ILFormat< (outs), (ins), 162906f32e7eSjoerg "DEFAULT", []>; 163006f32e7eSjoerg def ELSE : ILFormat< (outs), (ins), 163106f32e7eSjoerg "ELSE", []>; 163206f32e7eSjoerg def ENDSWITCH : ILFormat< (outs), (ins), 163306f32e7eSjoerg "ENDSWITCH", []>; 163406f32e7eSjoerg def ENDMAIN : ILFormat< (outs), (ins), 163506f32e7eSjoerg "ENDMAIN", []>; 163606f32e7eSjoerg def END : ILFormat< (outs), (ins), 163706f32e7eSjoerg "END", []>; 163806f32e7eSjoerg def ENDFUNC : ILFormat< (outs), (ins), 163906f32e7eSjoerg "ENDFUNC", []>; 164006f32e7eSjoerg def ENDIF : ILFormat< (outs), (ins), 164106f32e7eSjoerg "ENDIF", []>; 164206f32e7eSjoerg def WHILELOOP : ILFormat< (outs), (ins), 164306f32e7eSjoerg "WHILE", []>; 164406f32e7eSjoerg def ENDLOOP : ILFormat< (outs), (ins), 164506f32e7eSjoerg "ENDLOOP", []>; 164606f32e7eSjoerg def FUNC : ILFormat< (outs), (ins), 164706f32e7eSjoerg "FUNC", []>; 164806f32e7eSjoerg def RETDYN : ILFormat< (outs), (ins), 164906f32e7eSjoerg "RET_DYN", []>; 165006f32e7eSjoerg // This opcode has custom swizzle pattern encoded in Swizzle Encoder 165106f32e7eSjoerg defm IF_LOGICALNZ : BranchInstr<"IF_LOGICALNZ">; 165206f32e7eSjoerg // This opcode has custom swizzle pattern encoded in Swizzle Encoder 165306f32e7eSjoerg defm IF_LOGICALZ : BranchInstr<"IF_LOGICALZ">; 165406f32e7eSjoerg // This opcode has custom swizzle pattern encoded in Swizzle Encoder 165506f32e7eSjoerg defm BREAK_LOGICALNZ : BranchInstr<"BREAK_LOGICALNZ">; 165606f32e7eSjoerg // This opcode has custom swizzle pattern encoded in Swizzle Encoder 165706f32e7eSjoerg defm BREAK_LOGICALZ : BranchInstr<"BREAK_LOGICALZ">; 165806f32e7eSjoerg // This opcode has custom swizzle pattern encoded in Swizzle Encoder 165906f32e7eSjoerg defm CONTINUE_LOGICALNZ : BranchInstr<"CONTINUE_LOGICALNZ">; 166006f32e7eSjoerg // This opcode has custom swizzle pattern encoded in Swizzle Encoder 166106f32e7eSjoerg defm CONTINUE_LOGICALZ : BranchInstr<"CONTINUE_LOGICALZ">; 166206f32e7eSjoerg defm IFC : BranchInstr2<"IFC">; 166306f32e7eSjoerg defm BREAKC : BranchInstr2<"BREAKC">; 166406f32e7eSjoerg defm CONTINUEC : BranchInstr2<"CONTINUEC">; 166506f32e7eSjoerg} 166606f32e7eSjoerg 166706f32e7eSjoerg//===----------------------------------------------------------------------===// 166806f32e7eSjoerg// Indirect addressing pseudo instructions 166906f32e7eSjoerg//===----------------------------------------------------------------------===// 167006f32e7eSjoerg 167106f32e7eSjoerglet isPseudo = 1 in { 167206f32e7eSjoerg 167306f32e7eSjoergclass ExtractVertical <RegisterClass vec_rc> : InstR600 < 167406f32e7eSjoerg (outs R600_Reg32:$dst), 167506f32e7eSjoerg (ins vec_rc:$vec, R600_Reg32:$index), "", 167606f32e7eSjoerg [], 167706f32e7eSjoerg AnyALU 167806f32e7eSjoerg>; 167906f32e7eSjoerg 168006f32e7eSjoerglet Constraints = "$dst = $vec" in { 168106f32e7eSjoerg 168206f32e7eSjoergclass InsertVertical <RegisterClass vec_rc> : InstR600 < 168306f32e7eSjoerg (outs vec_rc:$dst), 168406f32e7eSjoerg (ins vec_rc:$vec, R600_Reg32:$value, R600_Reg32:$index), "", 168506f32e7eSjoerg [], 168606f32e7eSjoerg AnyALU 168706f32e7eSjoerg>; 168806f32e7eSjoerg 168906f32e7eSjoerg} // End Constraints = "$dst = $vec" 169006f32e7eSjoerg 169106f32e7eSjoerg} // End isPseudo = 1 169206f32e7eSjoerg 169306f32e7eSjoergdef R600_EXTRACT_ELT_V2 : ExtractVertical <R600_Reg64Vertical>; 169406f32e7eSjoergdef R600_EXTRACT_ELT_V4 : ExtractVertical <R600_Reg128Vertical>; 169506f32e7eSjoerg 169606f32e7eSjoergdef R600_INSERT_ELT_V2 : InsertVertical <R600_Reg64Vertical>; 169706f32e7eSjoergdef R600_INSERT_ELT_V4 : InsertVertical <R600_Reg128Vertical>; 169806f32e7eSjoerg 169906f32e7eSjoergclass ExtractVerticalPat <Instruction inst, ValueType vec_ty, 170006f32e7eSjoerg ValueType scalar_ty> : R600Pat < 170106f32e7eSjoerg (scalar_ty (extractelt vec_ty:$vec, i32:$index)), 170206f32e7eSjoerg (inst $vec, $index) 170306f32e7eSjoerg>; 170406f32e7eSjoerg 170506f32e7eSjoergdef : ExtractVerticalPat <R600_EXTRACT_ELT_V2, v2i32, i32>; 170606f32e7eSjoergdef : ExtractVerticalPat <R600_EXTRACT_ELT_V2, v2f32, f32>; 170706f32e7eSjoergdef : ExtractVerticalPat <R600_EXTRACT_ELT_V4, v4i32, i32>; 170806f32e7eSjoergdef : ExtractVerticalPat <R600_EXTRACT_ELT_V4, v4f32, f32>; 170906f32e7eSjoerg 171006f32e7eSjoergclass InsertVerticalPat <Instruction inst, ValueType vec_ty, 171106f32e7eSjoerg ValueType scalar_ty> : R600Pat < 171206f32e7eSjoerg (vec_ty (insertelt vec_ty:$vec, scalar_ty:$value, i32:$index)), 171306f32e7eSjoerg (inst $vec, $value, $index) 171406f32e7eSjoerg>; 171506f32e7eSjoerg 171606f32e7eSjoergdef : InsertVerticalPat <R600_INSERT_ELT_V2, v2i32, i32>; 171706f32e7eSjoergdef : InsertVerticalPat <R600_INSERT_ELT_V2, v2f32, f32>; 171806f32e7eSjoergdef : InsertVerticalPat <R600_INSERT_ELT_V4, v4i32, i32>; 171906f32e7eSjoergdef : InsertVerticalPat <R600_INSERT_ELT_V4, v4f32, f32>; 172006f32e7eSjoerg 172106f32e7eSjoerg//===----------------------------------------------------------------------===// 172206f32e7eSjoerg// ISel Patterns 172306f32e7eSjoerg//===----------------------------------------------------------------------===// 172406f32e7eSjoerg 172506f32e7eSjoerglet SubtargetPredicate = isR600toCayman in { 172606f32e7eSjoerg 172706f32e7eSjoerg// CND*_INT Patterns for f32 True / False values 172806f32e7eSjoerg 172906f32e7eSjoergclass CND_INT_f32 <InstR600 cnd, CondCode cc> : R600Pat < 173006f32e7eSjoerg (selectcc i32:$src0, 0, f32:$src1, f32:$src2, cc), 173106f32e7eSjoerg (cnd $src0, $src1, $src2) 173206f32e7eSjoerg>; 173306f32e7eSjoerg 173406f32e7eSjoergdef : CND_INT_f32 <CNDE_INT, SETEQ>; 173506f32e7eSjoergdef : CND_INT_f32 <CNDGT_INT, SETGT>; 173606f32e7eSjoergdef : CND_INT_f32 <CNDGE_INT, SETGE>; 173706f32e7eSjoerg 173806f32e7eSjoerg//CNDGE_INT extra pattern 173906f32e7eSjoergdef : R600Pat < 174006f32e7eSjoerg (selectcc i32:$src0, -1, i32:$src1, i32:$src2, COND_SGT), 174106f32e7eSjoerg (CNDGE_INT $src0, $src1, $src2) 174206f32e7eSjoerg>; 174306f32e7eSjoerg 174406f32e7eSjoerg// KIL Patterns 174506f32e7eSjoergdef KIL : R600Pat < 174606f32e7eSjoerg (int_r600_kill f32:$src0), 174706f32e7eSjoerg (MASK_WRITE (KILLGT (f32 ZERO), $src0)) 174806f32e7eSjoerg>; 174906f32e7eSjoerg 175006f32e7eSjoergdef : Extract_Element <f32, v4f32, 0, sub0>; 175106f32e7eSjoergdef : Extract_Element <f32, v4f32, 1, sub1>; 175206f32e7eSjoergdef : Extract_Element <f32, v4f32, 2, sub2>; 175306f32e7eSjoergdef : Extract_Element <f32, v4f32, 3, sub3>; 175406f32e7eSjoerg 175506f32e7eSjoergdef : Insert_Element <f32, v4f32, 0, sub0>; 175606f32e7eSjoergdef : Insert_Element <f32, v4f32, 1, sub1>; 175706f32e7eSjoergdef : Insert_Element <f32, v4f32, 2, sub2>; 175806f32e7eSjoergdef : Insert_Element <f32, v4f32, 3, sub3>; 175906f32e7eSjoerg 176006f32e7eSjoergdef : Extract_Element <i32, v4i32, 0, sub0>; 176106f32e7eSjoergdef : Extract_Element <i32, v4i32, 1, sub1>; 176206f32e7eSjoergdef : Extract_Element <i32, v4i32, 2, sub2>; 176306f32e7eSjoergdef : Extract_Element <i32, v4i32, 3, sub3>; 176406f32e7eSjoerg 176506f32e7eSjoergdef : Insert_Element <i32, v4i32, 0, sub0>; 176606f32e7eSjoergdef : Insert_Element <i32, v4i32, 1, sub1>; 176706f32e7eSjoergdef : Insert_Element <i32, v4i32, 2, sub2>; 176806f32e7eSjoergdef : Insert_Element <i32, v4i32, 3, sub3>; 176906f32e7eSjoerg 177006f32e7eSjoergdef : Extract_Element <f32, v2f32, 0, sub0>; 177106f32e7eSjoergdef : Extract_Element <f32, v2f32, 1, sub1>; 177206f32e7eSjoerg 177306f32e7eSjoergdef : Insert_Element <f32, v2f32, 0, sub0>; 177406f32e7eSjoergdef : Insert_Element <f32, v2f32, 1, sub1>; 177506f32e7eSjoerg 177606f32e7eSjoergdef : Extract_Element <i32, v2i32, 0, sub0>; 177706f32e7eSjoergdef : Extract_Element <i32, v2i32, 1, sub1>; 177806f32e7eSjoerg 177906f32e7eSjoergdef : Insert_Element <i32, v2i32, 0, sub0>; 178006f32e7eSjoergdef : Insert_Element <i32, v2i32, 1, sub1>; 178106f32e7eSjoerg 178206f32e7eSjoerg// bitconvert patterns 178306f32e7eSjoerg 178406f32e7eSjoergdef : BitConvert <i32, f32, R600_Reg32>; 178506f32e7eSjoergdef : BitConvert <f32, i32, R600_Reg32>; 178606f32e7eSjoergdef : BitConvert <v2f32, v2i32, R600_Reg64>; 178706f32e7eSjoergdef : BitConvert <v2i32, v2f32, R600_Reg64>; 178806f32e7eSjoergdef : BitConvert <v4f32, v4i32, R600_Reg128>; 178906f32e7eSjoergdef : BitConvert <v4i32, v4f32, R600_Reg128>; 179006f32e7eSjoerg 179106f32e7eSjoerg// DWORDADDR pattern 179206f32e7eSjoergdef : DwordAddrPat <i32, R600_Reg32>; 179306f32e7eSjoerg 179406f32e7eSjoerg} // End SubtargetPredicate = isR600toCayman 179506f32e7eSjoerg 179606f32e7eSjoergdef getLDSNoRetOp : InstrMapping { 179706f32e7eSjoerg let FilterClass = "R600_LDS_1A1D"; 179806f32e7eSjoerg let RowFields = ["BaseOp"]; 179906f32e7eSjoerg let ColFields = ["DisableEncoding"]; 180006f32e7eSjoerg let KeyCol = ["$dst"]; 180106f32e7eSjoerg let ValueCols = [[""""]]; 180206f32e7eSjoerg} 1803