1//===-- VEInstrInfo.td - Target Description for VE Target -----------------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This file describes the VE instructions in TableGen format. 10// 11//===----------------------------------------------------------------------===// 12 13//===----------------------------------------------------------------------===// 14// Instruction format superclass 15//===----------------------------------------------------------------------===// 16 17include "VEInstrFormats.td" 18 19//===----------------------------------------------------------------------===// 20// Feature predicates. 21//===----------------------------------------------------------------------===// 22 23//===----------------------------------------------------------------------===// 24// Instruction Pattern Stuff 25//===----------------------------------------------------------------------===// 26 27def simm7 : PatLeaf<(imm), [{ return isInt<7>(N->getSExtValue()); }]>; 28def simm32 : PatLeaf<(imm), [{ return isInt<32>(N->getSExtValue()); }]>; 29def uimm6 : PatLeaf<(imm), [{ return isUInt<6>(N->getZExtValue()); }]>; 30 31// ASX format of memory address 32def MEMri : Operand<iPTR> { 33 let PrintMethod = "printMemASXOperand"; 34 let MIOperandInfo = (ops ptr_rc, i64imm); 35} 36 37// AS format of memory address 38def MEMASri : Operand<iPTR> { 39 let PrintMethod = "printMemASOperand"; 40 let MIOperandInfo = (ops ptr_rc, i64imm); 41} 42 43// Branch targets have OtherVT type. 44def brtarget32 : Operand<OtherVT> { 45 let EncoderMethod = "getBranchTarget32OpValue"; 46} 47 48def simm7Op64 : Operand<i64> { 49 let DecoderMethod = "DecodeSIMM7"; 50} 51 52def simm32Op64 : Operand<i64> { 53 let DecoderMethod = "DecodeSIMM32"; 54} 55 56def uimm6Op64 : Operand<i64> { 57 let DecoderMethod = "DecodeUIMM6"; 58} 59 60// Operand for printing out a condition code. 61let PrintMethod = "printCCOperand" in 62 def CCOp : Operand<i32>; 63 64// These are target-independent nodes, but have target-specific formats. 65def SDT_SPCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i64>, 66 SDTCisVT<1, i64> ]>; 67def SDT_SPCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i64>, 68 SDTCisVT<1, i64> ]>; 69 70def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPCallSeqStart, 71 [SDNPHasChain, SDNPOutGlue]>; 72def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPCallSeqEnd, 73 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 74 75// def SDT_SPCall : SDTypeProfile<0, -1, [SDTCisVT<0, i64>]>; 76 77def retflag : SDNode<"VEISD::RET_FLAG", SDTNone, 78 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 79//===----------------------------------------------------------------------===// 80// VE Flag Conditions 81//===----------------------------------------------------------------------===// 82 83// Note that these values must be kept in sync with the CCOp::CondCode enum 84// values. 85class CC_VAL<int N> : PatLeaf<(i32 N)>; 86def CC_IG : CC_VAL< 0>; // Greater 87def CC_IL : CC_VAL< 1>; // Less 88def CC_INE : CC_VAL< 2>; // Not Equal 89def CC_IEQ : CC_VAL< 3>; // Equal 90def CC_IGE : CC_VAL< 4>; // Greater or Equal 91def CC_ILE : CC_VAL< 5>; // Less or Equal 92def CC_AF : CC_VAL< 6>; // Always false 93def CC_G : CC_VAL< 7>; // Greater 94def CC_L : CC_VAL< 8>; // Less 95def CC_NE : CC_VAL< 9>; // Not Equal 96def CC_EQ : CC_VAL<10>; // Equal 97def CC_GE : CC_VAL<11>; // Greater or Equal 98def CC_LE : CC_VAL<12>; // Less or Equal 99def CC_NUM : CC_VAL<13>; // Number 100def CC_NAN : CC_VAL<14>; // NaN 101def CC_GNAN : CC_VAL<15>; // Greater or NaN 102def CC_LNAN : CC_VAL<16>; // Less or NaN 103def CC_NENAN : CC_VAL<17>; // Not Equal or NaN 104def CC_EQNAN : CC_VAL<18>; // Equal or NaN 105def CC_GENAN : CC_VAL<19>; // Greater or Equal or NaN 106def CC_LENAN : CC_VAL<20>; // Less or Equal or NaN 107def CC_AT : CC_VAL<21>; // Always true 108 109//===----------------------------------------------------------------------===// 110// VE Multiclasses for common instruction formats 111//===----------------------------------------------------------------------===// 112 113multiclass RMm<string opcStr, bits<8>opc, 114 RegisterClass RC, ValueType Ty, Operand immOp, Operand immOp2> { 115 def rri : RM< 116 opc, (outs RC:$sx), (ins RC:$sy, RC:$sz, immOp2:$imm32), 117 !strconcat(opcStr, " $sx, ${imm32}($sy, ${sz})")> { 118 let cy = 1; 119 let cz = 1; 120 let hasSideEffects = 0; 121 } 122 def zzi : RM< 123 opc, (outs RC:$sx), (ins immOp2:$imm32), 124 !strconcat(opcStr, " $sx, $imm32")> { 125 let cy = 0; 126 let sy = 0; 127 let cz = 0; 128 let sz = 0; 129 let hasSideEffects = 0; 130 } 131} 132 133// Multiclass for RR type instructions 134 135multiclass RRmrr<string opcStr, bits<8>opc, 136 RegisterClass RCo, ValueType Tyo, 137 RegisterClass RCi, ValueType Tyi> { 138 def rr : RR<opc, (outs RCo:$sx), (ins RCi:$sy, RCi:$sz), 139 !strconcat(opcStr, " $sx, $sy, $sz")> 140 { let cy = 1; let cz = 1; let hasSideEffects = 0; } 141} 142 143multiclass RRmri<string opcStr, bits<8>opc, 144 RegisterClass RCo, ValueType Tyo, 145 RegisterClass RCi, ValueType Tyi, Operand immOp> { 146 // VE calculates (OpNode $sy, $sz), but llvm requires to have immediate 147 // in RHS, so we use following definition. 148 def ri : RR<opc, (outs RCo:$sx), (ins RCi:$sz, immOp:$sy), 149 !strconcat(opcStr, " $sx, $sy, $sz")> 150 { let cy = 0; let cz = 1; let hasSideEffects = 0; } 151} 152 153multiclass RRmiz<string opcStr, bits<8>opc, 154 RegisterClass RCo, ValueType Tyo, 155 RegisterClass RCi, ValueType Tyi, Operand immOp> { 156 def zi : RR<opc, (outs RCo:$sx), (ins immOp:$sy), 157 !strconcat(opcStr, " $sx, $sy")> 158 { let cy = 0; let cz = 0; let sz = 0; let hasSideEffects = 0; } 159} 160 161multiclass RRNDmrm<string opcStr, bits<8>opc, 162 RegisterClass RCo, ValueType Tyo, 163 RegisterClass RCi, ValueType Tyi, Operand immOp2> { 164 def rm0 : RR<opc, (outs RCo:$sx), (ins RCi:$sy, immOp2:$sz), 165 !strconcat(opcStr, " $sx, $sy, (${sz})0")> { 166 let cy = 1; 167 let cz = 0; 168 let sz{6} = 1; 169 // (guess) tblgen conservatively assumes hasSideEffects when 170 // it fails to infer from a pattern. 171 let hasSideEffects = 0; 172 } 173} 174 175// Used by add, mul, div, and similar commutative instructions 176// The order of operands are "$sx, $sy, $sz" 177 178multiclass RRm<string opcStr, bits<8>opc, 179 RegisterClass RC, ValueType Ty, Operand immOp, Operand immOp2> : 180 RRmrr<opcStr, opc, RC, Ty, RC, Ty>, 181 RRmri<opcStr, opc, RC, Ty, RC, Ty, immOp>, 182 RRmiz<opcStr, opc, RC, Ty, RC, Ty, immOp>, 183 RRNDmrm<opcStr, opc, RC, Ty, RC, Ty, immOp2>; 184 185// Branch multiclass 186let isBranch = 1, isTerminator = 1, hasDelaySlot = 1 in 187multiclass BCRm<string opcStr, string opcStrAt, bits<8> opc, 188 RegisterClass RC, ValueType Ty, Operand immOp, Operand immOp2> { 189 def rr : CF< 190 opc, (outs), 191 (ins CCOp:$cf, RC:$sy, RC:$sz, brtarget32:$imm32), 192 !strconcat(opcStr, " $sy, $sz, $imm32")> { 193 let cy = 1; 194 let cz = 1; 195 let hasSideEffects = 0; 196 } 197} 198 199 200//===----------------------------------------------------------------------===// 201// Instructions 202//===----------------------------------------------------------------------===// 203 204// LEA and LEASL instruction (load 32 bit imm to low or high part) 205let cx = 0 in 206defm LEA : RMm<"lea", 0x06, I64, i64, simm7Op64, simm32Op64>; 207let cx = 1 in 208defm LEASL : RMm<"lea.sl", 0x06, I64, i64, simm7Op64, simm32Op64>; 209 210// 5.3.2.2. Fixed-Point Arithmetic Operation Instructions 211 212// ADX instruction 213let cx = 0 in 214defm ADX : RRm<"adds.l", 0x59, I64, i64, simm7Op64, uimm6Op64>; 215 216// 5.3.2.3. Logical Arithmetic Operation Instructions 217 218let cx = 0 in { 219 defm AND : RRm<"and", 0x44, I64, i64, simm7Op64, uimm6Op64>; 220 defm OR : RRm<"or", 0x45, I64, i64, simm7Op64, uimm6Op64>; 221} 222 223// Load and Store instructions 224// As 1st step, only uses sz and imm32 to represent $addr 225let mayLoad = 1, hasSideEffects = 0 in { 226let cy = 0, sy = 0, cz = 1 in { 227let cx = 0 in 228def LDSri : RM< 229 0x01, (outs I64:$sx), (ins MEMri:$addr), 230 "ld $sx, $addr">; 231} 232} 233 234let mayStore = 1, hasSideEffects = 0 in { 235let cx = 0, cy = 0, sy = 0, cz = 1 in { 236def STSri : RM< 237 0x11, (outs), (ins MEMri:$addr, I64:$sx), 238 "st $sx, $addr">; 239} 240} 241 242// Return instruction is also a special case of jump. 243let cx = 0, cx2 = 0, bpf = 0 /* NONE */, cf = 15 /* AT */, cy = 0, sy = 0, 244 cz = 1, sz = 0x10 /* SX10 */, imm32 = 0, Uses = [SX10], 245 isReturn = 1, isTerminator = 1, hasDelaySlot = 1, isBarrier = 1, 246 isCodeGenOnly = 1, hasSideEffects = 0 in 247def RET : CF< 248 0x19, (outs), (ins), 249 "b.l (,%lr)", 250 [(retflag)]>; 251 252// Branch instruction 253let cx = 0, cx2 = 0, bpf = 0 /* NONE */ in 254defm BCRL : BCRm<"br${cf}.l", "br.l", 0x18, I64, i64, simm7Op64, uimm6Op64>; 255 256let cx = 0, cy = 0, cz = 1, hasSideEffects = 0 in { 257let sy = 3 in 258def SHMri : RM< 259 0x31, (outs), (ins MEMASri:$addr, I64:$sx), 260 "shm.l $sx, $addr">; 261} 262 263let cx = 0, sx = 0, cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 0 in 264def MONC : RR< 265 0x3F, (outs), (ins), 266 "monc">; 267 268//===----------------------------------------------------------------------===// 269// Pseudo Instructions 270//===----------------------------------------------------------------------===// 271 272let Defs = [SX11], Uses = [SX11], hasSideEffects = 0 in { 273def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i64imm:$amt, i64imm:$amt2), 274 "# ADJCALLSTACKDOWN $amt, $amt2", 275 [(callseq_start timm:$amt, timm:$amt2)]>; 276def ADJCALLSTACKUP : Pseudo<(outs), (ins i64imm:$amt1, i64imm:$amt2), 277 "# ADJCALLSTACKUP $amt1", 278 [(callseq_end timm:$amt1, timm:$amt2)]>; 279} 280 281let Defs = [SX8], Uses = [SX8, SX11], hasSideEffects = 0 in 282def EXTEND_STACK : Pseudo<(outs), (ins), 283 "# EXTEND STACK", 284 []>; 285let hasSideEffects = 0 in 286def EXTEND_STACK_GUARD : Pseudo<(outs), (ins), 287 "# EXTEND STACK GUARD", 288 []>; 289