1//===- ARCInstrInfo.td - Target Description for ARC --------*- tablegen -*-===// 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 ARC instructions in TableGen format. 10// 11//===----------------------------------------------------------------------===// 12 13include "ARCInstrFormats.td" 14 15//===----------------------------------------------------------------------===// 16// Operand Pattern Stuff. 17//===----------------------------------------------------------------------===// 18 19// Operand for printing out a condition code. 20let PrintMethod = "printCCOperand" in 21 def CCOp : PredicateOperand<i32, (ops i32imm), (ops)>; 22 23// The "u6" operand of a RRU6-type instruction 24let PrintMethod = "printU6" in { 25 def u6 : Operand<i32>, ImmLeaf<i32, [{ 26 return isUInt<6>(Imm); 27 }]>; 28 def wide_u6 : Operand<i64>, ImmLeaf<i64, [{ 29 return isUInt<6>(Imm); 30 }]>; 31} 32 33// --------------------------------------------------------------------------- 34// Selection DAG Nodes. 35// --------------------------------------------------------------------------- 36 37// Selection DAG types. 38def SDT_ARCcmptst : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>; 39def SDT_ARCcmov : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>]>; 40def SDT_ARCmov : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>]>; 41def SDT_ARCbrcc : SDTypeProfile<0, 4, []>; 42def SDT_ARCBranchLink : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>; 43def SDT_ARCCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32>, 44 SDTCisVT<1, i32> ]>; 45def SDT_ARCCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, 46 SDTCisVT<1, i32> ]>; 47 48 49// Global Address. 50def ARCGAWrapper : SDNode<"ARCISD::GAWRAPPER", SDT_ARCmov, []>; 51 52// Comparison 53def ARCcmp : SDNode<"ARCISD::CMP", SDT_ARCcmptst, [SDNPOutGlue]>; 54 55// Conditional mov 56def ARCcmov : SDNode<"ARCISD::CMOV", SDT_ARCcmov, [SDNPInGlue]>; 57 58// Conditional Branch 59def ARCbrcc : SDNode<"ARCISD::BRcc", SDT_ARCbrcc, 60 [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>; 61 62// Direct Call 63def ARCBranchLink : SDNode<"ARCISD::BL",SDT_ARCBranchLink, 64 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 65 SDNPVariadic]>; 66 67// Indirect Call 68def ARCJumpLink : SDNode<"ARCISD::JL",SDT_ARCBranchLink, 69 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 70 SDNPVariadic]>; 71// Call return 72def ret : SDNode<"ARCISD::RET", SDTNone, 73 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 74 75// Call sequencing nodes. 76// These are target-independent nodes, but have target-specific formats. 77def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARCCallSeqStart, 78 [SDNPHasChain, SDNPOutGlue]>; 79def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARCCallSeqEnd, 80 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 81 82//===----------------------------------------------------------------------===// 83// Instruction Pattern Stuff 84//===----------------------------------------------------------------------===// 85 86def imm32 : ImmLeaf<i32, [{ 87 return (Imm & 0xFFFFFFFF) == Imm; 88}]>; 89 90// Addressing modes 91def FrameADDR_ri : ComplexPattern<i32, 2, "SelectFrameADDR_ri", 92 [add, frameindex], []>; 93def AddrModeS9 : ComplexPattern<i32, 2, "SelectAddrModeS9", []>; 94def AddrModeImm : ComplexPattern<i32, 2, "SelectAddrModeImm", []>; 95def AddrModeFar : ComplexPattern<i32, 2, "SelectAddrModeFar", []>; 96 97//===----------------------------------------------------------------------===// 98// Instruction Class Templates 99//===----------------------------------------------------------------------===// 100 101//===----------------------------------------------------------------------===// 102// Pseudo Instructions 103//===----------------------------------------------------------------------===// 104 105let Defs = [SP], Uses = [SP] in { 106def ADJCALLSTACKDOWN : PseudoInstARC<(outs), (ins i32imm:$amt, i32imm:$amt2), 107 "# ADJCALLSTACKDOWN $amt, $amt2", 108 [(callseq_start timm:$amt, timm:$amt2)]>; 109def ADJCALLSTACKUP : PseudoInstARC<(outs), (ins i32imm:$amt1, i32imm:$amt2), 110 "# ADJCALLSTACKUP $amt1", 111 [(callseq_end timm:$amt1, timm:$amt2)]>; 112} 113 114def GETFI : PseudoInstARC<(outs GPR32:$dst), (ins MEMii:$addr), 115 "pldfi $dst, $addr", 116 [(set GPR32:$dst, FrameADDR_ri:$addr)]>; 117 118 119def ST_FAR : PseudoInstARC<(outs), (ins GPR32:$dst, MEMrlimm:$addr), 120 "ST_FAR $dst, $addr", 121 [(store GPR32:$dst, AddrModeFar:$addr)]>; 122 123def STH_FAR : PseudoInstARC<(outs), (ins GPR32:$dst, MEMrlimm:$addr), 124 "STH_FAR $dst, $addr", 125 [(truncstorei16 GPR32:$dst, AddrModeFar:$addr)]>; 126 127def STB_FAR : PseudoInstARC<(outs), (ins GPR32:$dst, MEMrlimm:$addr), 128 "STB_FAR $dst, $addr", 129 [(truncstorei8 GPR32:$dst, AddrModeFar:$addr)]>; 130 131//===----------------------------------------------------------------------===// 132// Instruction Generation multiclasses. 133// Generate many variants of a single instruction with a single defining 134// multiclass. These classes do not contain Selection DAG patterns. 135//===----------------------------------------------------------------------===// 136 137// Generic 3 operand binary instructions (i.e., add r0, r1, r2). 138multiclass ArcBinaryInst<bits<5> major, bits<6> mincode, 139 string opasm, bit Commutable> { 140 // 3 register variant. 141 def _rrr : F32_DOP_RR<major, mincode, 0, (outs GPR32:$A), 142 (ins GPR32:$B, GPR32:$C), 143 !strconcat(opasm, "\t$A, $B, $C"), 144 []> 145 { let isCommutable = Commutable; } 146 def _f_rrr : F32_DOP_RR<major, mincode, 1, (outs GPR32:$A), 147 (ins GPR32:$B, GPR32:$C), 148 !strconcat(opasm, ".f\t$A, $B, $C"), 149 []> 150 { let Defs = [STATUS32]; } 151 152 // 2 register with unsigned 6-bit immediate variant. 153 def _rru6 : F32_DOP_RU6<major, mincode, 0, (outs GPR32:$A), 154 (ins GPR32:$B, immU6:$U6), 155 !strconcat(opasm, "\t$A, $B, $U6"), 156 []>; 157 def _f_rru6 : F32_DOP_RU6<major, mincode, 1, (outs GPR32:$A), 158 (ins GPR32:$B, immU6:$U6), 159 !strconcat(opasm, ".f\t$A, $B, $U6"), 160 []> 161 { let Defs = [STATUS32]; } 162 163 def _cc_rru6 : F32_DOP_CC_RRU6<major, mincode, 0, (outs GPR32:$A), 164 (ins immU6:$U6, ccond:$cc, GPR32:$B), 165 !strconcat(opasm, ".$cc\t$A, $B, $U6"), 166 []> { 167 let Uses = [STATUS32]; 168 let Constraints = "$A = $B"; 169 } 170 171 def _cc_f_rru6 : F32_DOP_CC_RRU6<major, mincode, 1, (outs GPR32:$A), 172 (ins immU6:$U6, ccond:$cc, GPR32:$B), 173 !strconcat(opasm, ".$cc.f\t$A, $B, $U6"), 174 []> { 175 let Defs = [STATUS32]; 176 let Uses = [STATUS32]; 177 let Constraints = "$A = $B"; 178 } 179 180 // 2 register with 32-bit immediate variant. 181 def _rrlimm : F32_DOP_RLIMM<major, mincode, 0, 182 (outs GPR32:$A), 183 (ins GPR32:$B, i32imm:$LImm), 184 !strconcat(opasm, "\t$A, $B, $LImm"), 185 []>; 186 def _f_rrlimm : F32_DOP_RLIMM<major, mincode, 1, 187 (outs GPR32:$A), 188 (ins GPR32:$B, i32imm:$LImm), 189 !strconcat(opasm, ".f\t$A, $B, $LImm"), 190 []> 191 { let Defs = [STATUS32]; } 192 193 // 2 matched-register with signed 12-bit immediate variant (add r0, r0, -1). 194 def _rrs12 : F32_DOP_RS12<major, mincode, 0, 195 (outs GPR32:$B), 196 (ins GPR32:$in, immS<12>:$S12), 197 !strconcat(opasm, "\t$B, $in, $S12"), 198 []> 199 { let Constraints = "$B = $in"; } 200 def _f_rrs12 : F32_DOP_RS12<major, mincode, 1, 201 (outs GPR32:$B), 202 (ins GPR32:$in, immS<12>:$S12), 203 !strconcat(opasm, ".f\t$B, $in, $S12"), 204 []> 205 { let Constraints = "$B = $in"; let Defs = [STATUS32]; } 206} 207 208// Special multivariant GEN4 DOP format instruction that take 2 registers. 209// This is the class that is used for various comparison instructions. 210multiclass ArcSpecialDOPInst<bits<6> subop, string opasm, bit F> { 211 def _rr : F32_DOP_RR<0b00100, subop, F, (outs), (ins GPR32:$B, GPR32:$C), 212 !strconcat(opasm, "\t$B, $C"), 213 []>; 214 215 def _ru6 : F32_DOP_RU6<0b00100, subop, F, (outs), (ins GPR32:$B, i32imm:$U6), 216 !strconcat(opasm, "\t$B, $U6"), 217 []>; 218 219 def _rlimm : F32_DOP_RLIMM<0b00100, subop, F, (outs), 220 (ins GPR32:$B, i32imm:$LImm), 221 !strconcat(opasm, "\t$B, $LImm"), 222 []>; 223} 224 225// Generic 2-operand unary instructions. 226multiclass ArcUnaryInst<bits<5> major, bits<6> subop, 227 string opasm> { 228 def _rr : F32_SOP_RR<major, subop, 0, (outs GPR32:$B), (ins GPR32:$C), 229 !strconcat(opasm, "\t$B, $C"), []>; 230 231 def _f_rr : F32_SOP_RR<major, subop, 1, (outs GPR32:$B), (ins GPR32:$C), 232 !strconcat(opasm, ".f\t$B, $C"), []> 233 { let Defs = [STATUS32]; } 234} 235 236 237multiclass ArcBinaryGEN4Inst<bits<6> mincode, string opasm, bit Commutable = 0> : 238 ArcBinaryInst<0b00100, mincode, opasm, Commutable>; 239multiclass ArcBinaryEXT5Inst<bits<6> mincode, string opasm> : 240 ArcBinaryInst<0b00101, mincode, opasm, 0>; 241 242multiclass ArcUnaryGEN4Inst<bits<6> mincode, string opasm> : 243 ArcUnaryInst<0b00100, mincode, opasm>; 244multiclass ArcUnaryEXT5Inst<bits<6> mincode, string opasm> : 245 ArcUnaryInst<0b00101, mincode, opasm>; 246 247// Pattern generation for different instruction variants. 248multiclass MultiPat<SDPatternOperator InFrag, 249 Instruction RRR, Instruction RRU6, Instruction RRLImm> { 250 def _rrr : Pat<(InFrag i32:$B, i32:$C), (RRR i32:$B, i32:$C)>; 251 def _rru6 : Pat<(InFrag i32:$B, immU6:$U6), (RRU6 i32:$B, immU6:$U6)>; 252 def _rrlimm : Pat<(InFrag i32:$B, imm32:$LImm), (RRLImm i32:$B, imm32:$LImm)>; 253} 254 255// --------------------------------------------------------------------------- 256// Instruction definitions and patterns for 3 operand binary instructions. 257// --------------------------------------------------------------------------- 258 259// Definitions for 3 operand binary instructions. 260defm ADD : ArcBinaryGEN4Inst<0b000000, "add",1>; 261defm SUB : ArcBinaryGEN4Inst<0b000010, "sub">; 262defm SUB1 : ArcBinaryGEN4Inst<0b010111, "sub1">; 263defm SUB2 : ArcBinaryGEN4Inst<0b011000, "sub2">; 264defm SUB3 : ArcBinaryGEN4Inst<0b011001, "sub3">; 265defm RSUB : ArcBinaryGEN4Inst<0b001110, "rsub">; 266defm OR : ArcBinaryGEN4Inst<0b000101, "or",1>; 267defm AND : ArcBinaryGEN4Inst<0b000100, "and",1>; 268defm XOR : ArcBinaryGEN4Inst<0b000111, "xor",1>; 269defm MAX : ArcBinaryGEN4Inst<0b001000, "max",1>; 270defm MIN : ArcBinaryGEN4Inst<0b001001, "min",1>; 271defm ASL : ArcBinaryEXT5Inst<0b000000, "asl">; 272defm LSR : ArcBinaryEXT5Inst<0b000001, "lsr">; 273defm ASR : ArcBinaryEXT5Inst<0b000010, "asr">; 274defm ROR : ArcBinaryEXT5Inst<0b000011, "ror">; 275defm MPY : ArcBinaryGEN4Inst<0b011010, "mpy",1>; 276defm MPYM : ArcBinaryGEN4Inst<0b011011, "mpym",1>; 277defm MPYMU : ArcBinaryGEN4Inst<0b011100, "mpymu",1>; 278defm SETEQ : ArcBinaryGEN4Inst<0b111000, "seteq",1>; 279 280// Patterns for 3 operand binary instructions. 281defm : MultiPat<add, ADD_rrr, ADD_rru6, ADD_rrlimm>; 282defm : MultiPat<sub, SUB_rrr, SUB_rru6, SUB_rrlimm>; 283defm : MultiPat<or, OR_rrr, OR_rru6, OR_rrlimm>; 284defm : MultiPat<and, AND_rrr, AND_rru6, AND_rrlimm>; 285defm : MultiPat<xor, XOR_rrr, XOR_rru6, XOR_rrlimm>; 286defm : MultiPat<smax, MAX_rrr, MAX_rru6, MAX_rrlimm>; 287defm : MultiPat<smin, MIN_rrr, MIN_rru6, MIN_rrlimm>; 288defm : MultiPat<shl, ASL_rrr, ASL_rru6, ASL_rrlimm>; 289defm : MultiPat<srl, LSR_rrr, LSR_rru6, LSR_rrlimm>; 290defm : MultiPat<sra, ASR_rrr, ASR_rru6, ASR_rrlimm>; 291defm : MultiPat<rotr, ROR_rrr, ROR_rru6, ROR_rrlimm>; 292defm : MultiPat<mul, MPY_rrr, MPY_rru6, MPY_rrlimm>; 293defm : MultiPat<mulhs, MPYM_rrr, MPYM_rru6, MPYM_rrlimm>; 294defm : MultiPat<mulhu, MPYMU_rrr, MPYMU_rru6, MPYMU_rrlimm>; 295 296// --------------------------------------------------------------------------- 297// Unary Instruction definitions. 298// --------------------------------------------------------------------------- 299// General unary instruction definitions. 300defm SEXB : ArcUnaryGEN4Inst<0b000101, "sexb">; 301defm SEXH : ArcUnaryGEN4Inst<0b000110, "sexh">; 302 303// Extension unary instruction definitions. 304defm FLS : ArcUnaryEXT5Inst<0b010011, "fls">; 305 306// General Unary Instruction fragments. 307def : Pat<(sext_inreg i32:$a, i8), (SEXB_rr i32:$a)>; 308def : Pat<(sext_inreg i32:$a, i16), (SEXH_rr i32:$a)>; 309 310// Comparison instruction definition 311let isCompare = 1, Defs = [STATUS32] in { 312defm CMP : ArcSpecialDOPInst<0b001100, "cmp", 1>; 313} 314 315def cmp : PatFrag<(ops node:$op1, node:$op2), (ARCcmp $op1, $op2)>; 316defm : MultiPat<cmp, CMP_rr, CMP_ru6, CMP_rlimm>; 317 318// --------------------------------------------------------------------------- 319// MOV instruction and variants (conditional mov). 320// --------------------------------------------------------------------------- 321let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in { 322def MOV_rs12 : F32_DOP_RS12<0b00100, 0b001010, 0, 323 (outs GPR32:$B), (ins immS<12>:$S12), 324 "mov\t$B, $S12", 325 [(set GPR32:$B, immS<12>:$S12)]>; 326} 327 328def MOV_rr : F32_DOP_RR<0b00100, 0b001010, 0, 329 (outs GPR32:$B), (ins GPR32:$C), 330 "mov\t$B, $C", []>; 331 332def MOV_rlimm : F32_DOP_RLIMM<0b00100, 0b001010, 0, 333 (outs GPR32:$B), (ins i32imm:$LImm), 334 "mov\t$B, $LImm", []>; 335 336def MOV_ru6 : F32_DOP_RU6<0b00100, 0b001010, 0, 337 (outs GPR32:$B), (ins immU6:$U6), 338 "mov\t$B, $U6", []>; 339 340def cmov : PatFrag<(ops node:$op1, node:$op2, node:$cc), 341 (ARCcmov $op1, $op2, $cc)>; 342let Uses = [STATUS32] in { 343 def MOVcc : F32_DOP_CC_RR<0b00100, 0b001010, 0, 344 (outs GPR32:$B), 345 (ins GPR32:$C, GPR32:$fval, cmovpred:$cc), 346 !strconcat("mov.", "$cc\t$B, $C"), 347 [(set GPR32:$B, (cmov i32:$C, i32:$fval, cmovpred:$cc))]> { 348 let Constraints = "$B = $fval"; 349 } 350 351 def MOVcc_ru6 : F32_SOP_CC_RU6<0b00100, 0b001010, 0, 352 (outs GPR32:$b), (ins u6:$c, CCOp:$cc, GPR32:$b2), 353 "mov.$cc\t$b, $c", []> { 354 let isAsCheapAsAMove=0; 355 let isPredicable=1; 356 let isReMaterializable=0; 357 let Constraints="$b2 = $b"; 358 } 359} 360 361def : Pat<(ARCGAWrapper tglobaladdr:$addr), 362 (MOV_rlimm tglobaladdr:$addr)>; 363 364def : Pat<(ARCGAWrapper tjumptable:$addr), 365 (MOV_rlimm tjumptable:$addr)>; 366 367 368// --------------------------------------------------------------------------- 369// Control flow instructions (branch, return, calls, etc). 370// --------------------------------------------------------------------------- 371 372// Branch instructions 373let isBranch = 1, isTerminator = 1 in { 374 375 // Unconditional branch. 376 let isBarrier = 1 in 377 def BR : F32_BR0_UCOND_FAR<(outs), (ins btargetS25:$S25), 378 "b\t$S25", [(br bb:$S25)]>; 379 380 let Uses=[STATUS32] in 381 // Conditional branch. 382 def Bcc : F32_BR0_COND<(outs), (ins btargetS21:$S21, ccond:$cc), 383 "b$cc\t$S21", []>; 384 385 // Compare and branch (limited range). 386 def BRcc_rr : F32_BR1_BCC<(outs), 387 (ins btargetS9:$S9, GPR32:$B, GPR32:$C, brccond:$cc), 388 "br$cc\t$B, $C, $S9", 0, []>; 389 def BRcc_ru6 : F32_BR1_BCC<(outs), 390 (ins btargetS9:$S9, GPR32:$B, immU6:$C, brccond:$cc), 391 "br$cc\t$B, $C, $S9", 1, []>; 392 393 // Pseudo compare and branch. 394 // After register allocation, this can expand into either a limited range 395 // Compare and branch (BRcc), or into CMP + Bcc. 396 // At worst, this expands into 2 4-byte instructions. 397 def BRcc_rr_p : PseudoInstARC<(outs), 398 (ins btarget:$T, GPR32:$B, GPR32:$C, ccond:$cc), 399 "pbr$cc\t$B, $C, $T", 400 [(ARCbrcc bb:$T, i32:$B, i32:$C, imm32:$cc)]> 401 { let Size = 8; } 402 403 def BRcc_ru6_p : PseudoInstARC<(outs), 404 (ins btarget:$T, GPR32:$B, i32imm:$C, ccond:$cc), 405 "pbr$cc\t$B, $C, $T", 406 [(ARCbrcc bb:$T, i32:$B, immU6:$C, imm32:$cc)]> 407 { let Size = 8; } 408} // let isBranch, isTerminator 409 410// Unconditional Jump. 411let isBranch = 1, isTerminator = 1, isBarrier = 1 in { 412 // Indirect. 413 let isIndirectBranch = 1 in 414 def J : F32_DOP_RR<0b00100, 0b100000, 0, 415 (outs), (ins GPR32:$C), 416 "j\t[$C]", [(brind i32:$C)]>; 417 418 // Direct. 419 def J_LImm : F32_DOP_RLIMM<0b00100, 0b100000, 0, 420 (outs), (ins i32imm:$LImm), 421 "j\t$LImm", []>; 422} 423 424// Call instructions. 425let isCall = 1, isBarrier = 1, Defs = [BLINK], Uses = [SP] in { 426 // Direct unconditional call. 427 def BL : F32_BR1_BL_UCOND_FAR<(outs), (ins calltargetS25:$S25), 428 "bl\t$S25", [(ARCBranchLink tglobaladdr:$S25)]>; 429 430 // Indirect unconditional call. 431 let isIndirectBranch = 1 in 432 def JL : F32_DOP_RR<0b00100, 0b100010, 0, (outs), (ins GPR32:$C), 433 "jl\t[$C]", [(ARCJumpLink i32:$C)]>; 434 435 // Direct unconditional call. 436 def JL_LImm : F32_DOP_RLIMM<0b00100, 0b100010, 0, (outs), (ins i32imm:$LImm), 437 "jl\t$LImm", []>; 438} // let isCall, isBarrier, Defs, Uses 439 440// Pattern to generate BL instruction. 441def : Pat<(ARCBranchLink texternalsym:$dst), (BL texternalsym:$dst)>; 442 443// Return from call. 444let isReturn = 1, isTerminator = 1, isBarrier = 1 in 445// This is a specialized 2-byte instruction that doesn't generalize 446// to any larger 2-byte class, so go ahead and define it here. 447def J_S_BLINK : InstARC<2, (outs), (ins), "j_s\t[%blink]", [(ret)]> { 448 let Inst{15-0} = 0b0111111011100000; 449} 450 451//---------------------------------------------------------------------------- 452// Compact stack-based operations. 453//---------------------------------------------------------------------------- 454 455// 2-byte push/pop blink instructions commonly used for prolog/epilog 456// generation. These 2 instructions are actually specialized 2-byte 457// format instructions that aren't generalized to a larger 2-byte 458// class, so we might as well have them here. 459let Uses = [BLINK], Defs = [SP] in 460def PUSH_S_BLINK : F16_SP_OPS_buconst<0b111, "push_s">; 461 462let Defs = [BLINK, SP] in 463def POP_S_BLINK : F16_SP_OPS_buconst<0b110, "pop_s">; 464 465def PUSH_S_r : F16_SP_OPS_uconst<0b110, 466 (outs), (ins GPR32Reduced:$b3), "push_s">; 467def POP_S_r : F16_SP_OPS_uconst<0b111, 468 (outs GPR32Reduced:$b3), (ins), "pop_s">; 469 470def SP_SUB_SP_S : F16_SP_OPS_bconst<0b001, "sub_s">; 471def SP_ADD_SP_S : F16_SP_OPS_bconst<0b000, "add_s">; 472def SP_ADD_S : F16_SP_OPS_u7_aligned<0b100, 473 (outs GPR32Reduced:$b3), (ins immU<7>:$u7), 474 "add_s\t$b3, %sp, $u7">; 475 476def SP_LD_S : F16_SP_LD<0b000, "ld_s">; 477def SP_LDB_S : F16_SP_LD<0b001, "ldb_s">; 478def SP_ST_S : F16_SP_ST<0b010, "st_s">; 479def SP_STB_S : F16_SP_ST<0b011, "stb_s">; 480 481def LEAVE_S : F16_SP_OPS<0b110, 482 (outs), (ins immU<7>:$u7), "leave_s\t$u7"> { 483 484 bits<7> u7; 485 486 let fieldB = u7{6-4}; 487 let fieldU{4-1} = u7{3-0}; 488 let fieldU{0} = 0b0; 489} 490 491def ENTER_S : F16_SP_OPS<0b111, 492 (outs), (ins immU<6>:$u6), "enter_s\t$u6"> { 493 494 bits<6> u6; 495 496 let fieldB{2} = 0; 497 let fieldB{1-0} = u6{5-4}; 498 let fieldU{4-1} = u6{3-0}; 499 let fieldU{0} = 0b0; 500} 501 502//---------------------------------------------------------------------------- 503// Compact Move/Load instructions. 504//---------------------------------------------------------------------------- 505class COMPACT_MOV_S : 506 F16_COMPACT<0b0, (outs GPR32:$g), (ins GPR32:$h), 507 "mov_s\t$g, $h"> { 508 let DecoderMethod = "DecodeMoveHRegInstruction"; 509} 510 511def COMPACT_MOV_S_limm : COMPACT_MOV_S { 512 bits<32> LImm; 513 let Inst{47-16} = LImm; 514 515 bits<5> LImmReg = 0b11110; 516 let Inst{7-5} = LImmReg{2-0}; 517 let Inst{1-0} = LImmReg{4-3}; 518 519 let Size = 6; 520} 521 522def COMPACT_MOV_S_hreg : COMPACT_MOV_S; 523 524def COMPACT_LD_S : 525 F16_COMPACT<0b1, (outs GPR32:$r), (ins GPR32:$h, immU<5>:$u5), 526 "ld_s\t$r, [$h, $u5]"> { 527 bits<5> u5; 528 bits<2> r; 529 530 let Inst{10} = u5{4}; 531 let Inst{9-8} = r; 532 let Inst{4-3} = u5{3-2}; 533 let u5{1-0} = 0b00; 534} 535 536//---------------------------------------------------------------------------- 537// Compact Load/Add/Sub. 538//---------------------------------------------------------------------------- 539def LD_S_AS_rrr : F16_LD_SUB<0b0, "ld_s.as\t$a, [$b, $c]">; 540def SUB_S_rrr : F16_LD_SUB<0b1, "sub_s\t$a, $b, $c">; 541def ADD_S_rru6 : F16_ADD; 542 543//---------------------------------------------------------------------------- 544// Compact Load/Store. 545//---------------------------------------------------------------------------- 546def LD_S_s11 : F16_LD_ST_s11<0b0, "ld_s\t%r1, [%gp, $s11]">; 547def ST_S_s11 : F16_LD_ST_s11<0b1, "st_s\t%r0, [%gp, $s11]">; 548def LDI_S_u7 : F16_LDI_u7; 549 550//---------------------------------------------------------------------------- 551// Indexed Jump or Execute. 552//---------------------------------------------------------------------------- 553def JLI_S : F16_JLI_EI<0, "jli_s">; 554def EI_S : F16_JLI_EI<1, "ei_s">; 555 556//---------------------------------------------------------------------------- 557// Load/Add Register-Register. 558//---------------------------------------------------------------------------- 559def LD_S_rrr : F16_LD_ADD_RR<0b00, "ld_s\t$a, [$b, $c]">; 560def LDB_S_rrr : F16_LD_ADD_RR<0b01, "ldb_s\t$a, [$b, $c]">; 561def LDH_S_rrr : F16_LD_ADD_RR<0b10, "ldh_s\t$a, [$b, $c]">; 562def ADD_S_rrr : F16_LD_ADD_RR<0b11, "add_s\t$a, $b, $c">; 563 564//---------------------------------------------------------------------------- 565// Load/Add GP-Relative. 566//---------------------------------------------------------------------------- 567def GP_LD_S : F16_GP_LD_ADD<0b00, (ins immS<11>:$s), 568 "ld_s\t%r0, [%gp, $s]"> { 569 570 bits<11> s; 571 let Inst{8-0} = s{10-2}; 572 let s{1-0} = 0b00; 573} 574 575def GP_LDB_S : F16_GP_LD_ADD<0b01, (ins immS<9>:$s), 576 "ldb_s\t%r0, [%gp, $s]"> { 577 578 bits<9> s; 579 let Inst{8-0} = s{8-0}; 580} 581 582def GP_LDH_S : F16_GP_LD_ADD<0b10, (ins immS<10>:$s), 583 "ldh_s\t%r0, [%gp, $s]"> { 584 585 bits<10> s; 586 let Inst{8-0} = s{9-1}; 587 let s{0} = 0b0; 588} 589 590def GP_ADD_S : F16_GP_LD_ADD<0b11, (ins immS<11>:$s), 591 "add_s\t%r0, %gp, $s"> { 592 593 bits<11> s; 594 let Inst{8-0} = s{10-2}; 595 let s{1-0} = 0b00; 596} 597 598//---------------------------------------------------------------------------- 599// Load PCL-Relative. 600//---------------------------------------------------------------------------- 601def PCL_LD : InstARC<2, (outs GPR32:$b), (ins immU<10>:$u10), 602 "ld_s\t$b, [%pcl, $u10]", []> { 603 604 bits<3> b; 605 bits<10> u10; 606 607 let Inst{15-11} = 0b11010; 608 let Inst{10-8} = b; 609 let Inst{7-0} = u10{9-2}; 610 let u10{1-0} = 0b00; 611} 612 613let isBranch = 1 in { 614 //---------------------------------------------------------------------------- 615 // Branch on Compare Register with Zero. 616 //---------------------------------------------------------------------------- 617 def BREQ_S : F16_BCC_REG<0b0, "breq_s">; 618 def BRNE_S : F16_BCC_REG<0b1, "brne_s">; 619 620 //---------------------------------------------------------------------------- 621 // Branch Conditionally. 622 //---------------------------------------------------------------------------- 623 let isBarrier = 1 in 624 def B_S : F16_BCC_s10<0b00, "b_s">; 625 626 def BEQ_S : F16_BCC_s10<0b01, "beq_s">; 627 def BNE_S : F16_BCC_s10<0b10, "bne_s">; 628 def BGT_S : F16_BCC_s7<0b000, "bgt_s">; 629 def BGE_S : F16_BCC_s7<0b001, "bge_s">; 630 def BLT_S : F16_BCC_s7<0b010, "blt_s">; 631 def BLE_S : F16_BCC_s7<0b011, "ble_s">; 632 def BHI_S : F16_BCC_s7<0b100, "bhi_s">; 633 def BHS_S : F16_BCC_s7<0b101, "bhs_s">; 634 def BLO_S : F16_BCC_s7<0b110, "blo_s">; 635 def BLS_S : F16_BCC_s7<0b111, "bls_s">; 636} // let isBranch 637 638def BL_S : 639 InstARC<2, (outs), (ins btargetS13:$s13), "bl_s\t$s13", []> { 640 641 let Inst{15-11} = 0b11111; 642 643 bits<13> s13; 644 let Inst{10-0} = s13{12-2}; 645 let s13{1-0} = 0b00; 646 647 let isCall = 1; 648 let isBarrier = 1; 649} 650 651//---------------------------------------------------------------------------- 652// Add/Sub/Shift Register-Immediate. 653//---------------------------------------------------------------------------- 654def ADD_S_ru3 : F16_ADD_IMM<0b00,"add_s">; 655def SUB_S_ru3 : F16_ADD_IMM<0b01,"sub_s">; 656def ASL_S_ru3 : F16_ADD_IMM<0b10,"asl_s">; 657def ASR_S_ru3 : F16_ADD_IMM<0b11,"asr_s">; 658 659//---------------------------------------------------------------------------- 660// Shift/Subtract/Bit Immediate. 661//---------------------------------------------------------------------------- 662def ASL_S_ru5 : F16_SH_SUB_BIT_DST<0b000,"asl_s">; 663def LSR_S_ru5 : F16_SH_SUB_BIT_DST<0b001,"lsr_s">; 664def ASR_S_ru5 : F16_SH_SUB_BIT_DST<0b010,"asr_s">; 665def SUB_S_ru5 : F16_SH_SUB_BIT_DST<0b011,"sub_s">; 666def BSET_S_ru5 : F16_SH_SUB_BIT_DST<0b100,"bset_s">; 667def BCLR_S_ru5 : F16_SH_SUB_BIT_DST<0b101,"bclr_s">; 668def BMSK_S_ru5 : F16_SH_SUB_BIT_DST<0b110,"bmsk_s">; 669def BTST_S_ru5 : F16_SH_SUB_BIT<0b111, "btst_s\t$b, $u5">; 670 671//---------------------------------------------------------------------------- 672// Dual Register Operations. 673//---------------------------------------------------------------------------- 674def ADD_S_rlimm : 675 F16_OP_HREG_LIMM<0b000, (outs GPR32:$b_s3), (ins i32imm:$LImm), 676 !strconcat("add_s", "\t$b_s3, $b_s3, $LImm")>; 677 678def ADD_S_rr : 679 F16_OP_HREG<0b000, (outs GPR32:$b_s3), (ins GPR32:$h), 680 !strconcat("add_s", "\t$b_s3, $b_s3, $h")>; 681 682def ADD_S_rs3 : 683 F16_OP_HREG<0b001, (outs GPR32:$h), (ins immC<3>:$b_s3), 684 !strconcat("add_s", "\t$h, $h, $b_s3")>; 685 686def ADD_S_limms3 : 687 F16_OP_HREG_LIMM<0b001, (outs), (ins immC<3>:$b_s3, i32imm:$LImm), 688 !strconcat("add_s", "\t0, $LImm, $b_s3")>; 689 690def MOV_S_NE_rlimm : 691 F16_OP_HREG_LIMM<0b111, (outs GPR32:$b_s3), (ins i32imm:$LImm), 692 !strconcat("mov_s.ne", "\t$b_s3, $LImm")>; 693 694def MOV_S_NE_rr : 695 F16_OP_HREG<0b111,(outs GPR32:$b_s3), (ins GPR32:$h), 696 !strconcat("mov_s.ne", "\t$b_s3, $h")>; 697 698def MOV_S_rs3 : 699 F16_OP_HREG<0b011, (outs GPR32:$h), (ins immC<3>:$b_s3), 700 !strconcat("mov_s", "\t$h, $b_s3")>; 701 702def MOV_S_s3 : 703 F16_OP_HREG30<0b011, (outs), (ins immC<3>:$b_s3), 704 !strconcat("mov_s", "\t0, $b_s3")>; 705 706def CMP_S_rlimm : 707 F16_OP_HREG_LIMM<0b100, (outs GPR32:$b_s3), (ins i32imm:$LImm), 708 !strconcat("cmp_s", "\t$b_s3, $LImm")>; 709 710def CMP_S_rr : 711 F16_OP_HREG<0b100, (outs GPR32:$b_s3), (ins GPR32:$h), 712 !strconcat("cmp_s", "\t$b_s3, $h")>; 713 714def CMP_S_rs3 : 715 F16_OP_HREG<0b101, (outs GPR32:$h), (ins immC<3>:$b_s3), 716 !strconcat("cmp_s", "\t$h, $b_s3")>; 717 718def CMP_S_limms3 : 719 F16_OP_HREG_LIMM<0b101, (outs), (ins immC<3>:$b_s3, i32imm:$LImm), 720 !strconcat("cmp_s", "\t$LImm, $b_s3")>; 721 722//---------------------------------------------------------------------------- 723// Compact MOV/ADD/CMP Immediate instructions. 724//---------------------------------------------------------------------------- 725def MOV_S_u8 : 726 F16_OP_IMM<0b11011, (outs GPR32:$b), (ins immU<8>:$u8), 727 !strconcat("mov_s", "\t$b, $u8")> { 728 bits<8> u8; 729 let Inst{7-0} = u8; 730} 731 732def ADD_S_u7 : 733 F16_OP_U7<0b0, !strconcat("add_s", "\t$b, $b, $u7")>; 734 735def CMP_S_u7 : 736 F16_OP_U7<0b1, !strconcat("cmp_s", "\t$b, $u7")>; 737 738//---------------------------------------------------------------------------- 739// Compact Load/Store instructions with offset. 740//---------------------------------------------------------------------------- 741def LD_S_OFF : 742 F16_LD_ST_WORD_OFF<0x10, (outs GPR32:$c), (ins GPR32:$b, immU<7>:$off), 743 "ld_s">; 744 745def LDB_S_OFF : 746 F16_LD_ST_BYTE_OFF<0x11, (outs GPR32:$c), (ins GPR32:$b, immU<5>:$off), 747 "ldb_s">; 748 749class F16_LDH_OFF<bits<5> opc, string asmstr> : 750 F16_LD_ST_HALF_OFF<opc, (outs GPR32:$c), (ins GPR32:$b, immU<6>:$off), 751 asmstr>; 752 753def LDH_S_OFF : F16_LDH_OFF<0x12, "ldh_s">; 754def LDH_S_X_OFF : F16_LDH_OFF<0x13, "ldh_s.x">; 755 756def ST_S_OFF : 757 F16_LD_ST_WORD_OFF<0x14, (outs), (ins GPR32:$c, GPR32:$b, immU<7>:$off), 758 "st_s">; 759 760def STB_S_OFF : 761 F16_LD_ST_BYTE_OFF<0x15, (outs), (ins GPR32:$c, GPR32:$b, immU<5>:$off), 762 "stb_s">; 763 764def STH_S_OFF : 765 F16_LD_ST_HALF_OFF<0x16, (outs), (ins GPR32:$c, GPR32:$b, immU<6>:$off), 766 "sth_s">; 767 768//---------------------------------------------------------------------------- 769// General compact instructions. 770//---------------------------------------------------------------------------- 771def GEN_SUB_S : F16_GEN_DOP<0x02, "sub_s">; 772def GEN_AND_S : F16_GEN_DOP<0x04, "and_s">; 773def GEN_OR_S : F16_GEN_DOP<0x05, "or_s">; 774def GEN_BIC_S : F16_GEN_DOP<0x06, "bic_s">; 775def GEN_XOR_S : F16_GEN_DOP<0x07, "xor_s">; 776def GEN_MPYW_S : F16_GEN_DOP<0x09, "mpyw_s">; 777def GEN_MPYUW_S : F16_GEN_DOP<0x0a, "mpyuw_s">; 778def GEN_TST_S : F16_GEN_DOP_NODST<0x0b, "tst_s">; 779def GEN_MPY_S : F16_GEN_DOP<0x0c, "mpy_s">; 780def GEN_SEXB_S : F16_GEN_DOP_SINGLESRC<0x0d, "sexb_s">; 781def GEN_SEXH_S : F16_GEN_DOP_SINGLESRC<0x0e, "sexh_s">; 782def GEN_EXTB_S : F16_GEN_DOP_SINGLESRC<0x0f, "extb_s">; 783def GEN_EXTH_S : F16_GEN_DOP_SINGLESRC<0x10, "exth_s">; 784def GEN_ABS_S : F16_GEN_DOP_SINGLESRC<0x11, "abs_s">; 785def GEN_NOT_S : F16_GEN_DOP_SINGLESRC<0x12, "not_s">; 786def GEN_NEG_S : F16_GEN_DOP_SINGLESRC<0x13, "neg_s">; 787def GEN_ADD1_S : F16_GEN_DOP<0x14, "add1_s">; 788def GEN_ADD2_S : F16_GEN_DOP<0x15, "add2_s">; 789def GEN_ADD3_S : F16_GEN_DOP<0x16, "add3_s">; 790def GEN_ASL_S : F16_GEN_DOP<0x18, "asl_s">; 791def GEN_LSR_S : F16_GEN_DOP<0x19, "lsr_s">; 792def GEN_ASR_S : F16_GEN_DOP<0x1a, "asr_s">; 793def GEN_AS1L_S : F16_GEN_DOP_SINGLESRC<0x1b, "asl_s">; 794def GEN_AS1R_S : F16_GEN_DOP_SINGLESRC<0x1c, "asr_s">; 795def GEN_LS1R_S : F16_GEN_DOP_SINGLESRC<0x1d, "lsr_s">; 796def GEN_TRAP_S : F16_GEN_DOP_BASE<0x1e, (outs), (ins immU6:$u6), 797 "trap_s\t$u6"> { 798 799 bits<6> u6; 800 let b = u6{5-3}; 801 let c = u6{2-0}; 802} 803 804def GEN_BRK_S : F16_GEN_DOP_BASE<0x1f, (outs), (ins), 805 "brk_s"> { 806 807 let b = 0b111; 808 let c = 0b111; 809} 810 811let isBarrier = 1 in { 812 let isBranch = 1 in { 813 def GEN_J_S : F16_GEN_SOP<0x0, "j_s\t[$b]">; 814 def GEN_J_S_D : F16_GEN_SOP<0x1, "j_s.d\t[$b]">; 815 } // let isBranch 816 817 let isCall = 1 in { 818 def GEN_JL_S : F16_GEN_SOP<0x2, "jl_s\t[$b]">; 819 def GEN_JL_S_D : F16_GEN_SOP<0x3, "jl_s.d\t[$b]">; 820 } // let isCall 821} // let isBarrier 822 823def GEN_SUB_S_NE : F16_GEN_SOP<0x6, "sub_s.ne\t$b, $b, $b">; 824 825def GEN_NOP_S : F16_GEN_ZOP<0x0, "nop_s">; 826def GEN_UNIMP_S : F16_GEN_ZOP<0x1, "unimp_s">; 827def GEN_SWI_S : F16_GEN_ZOP<0x2, "swi_s">; 828 829let isReturn = 1, isTerminator = 1 in { 830 def GEN_JEQ_S : F16_GEN_ZOP<0x4, "jeq_s\t[%blink]">; 831 def GEN_JNE_S : F16_GEN_ZOP<0x5, "jne_s\t[%blink]">; 832 let isBarrier = 1 in { 833 //def GEN_J_S_BLINK : F16_GEN_ZOP<0x6, "j_s\t[%blink]">; 834 def GEN_J_S_D_BLINK : F16_GEN_ZOP<0x7, "j_s.d\t[%blink]">; 835 } // let isBarrier 836} // let isReturn, isTerminator 837 838//---------------------------------------------------------------------------- 839// Load/Store instructions. 840//---------------------------------------------------------------------------- 841 842// Filter class for load/store mappings 843class ArcLdStRel; 844 845// Load instruction variants: 846// Control bits: x, aa, di, zz 847// x - sign extend. 848// aa - incrementing mode. (N/A for LIMM). 849// di - uncached. 850// zz - data size. 851multiclass ArcLdInst<DataSizeMode zz, ExtMode x, CacheMode di, string asmop> { 852 let mayLoad = 1, ZZ = zz, X = x, DI = di in { 853 def _rs9: F32_LD_ADDR<x.Value, NoAM.Value, di.Value, zz.Value, 854 (outs GPR32:$A), (ins MEMrs9:$addr), 855 !strconcat(asmop, "\t$A, [$addr]"), []>, ArcLdStRel; 856 857 def _limm: F32_LD_LIMM<x.Value, di.Value, zz.Value, 858 (outs GPR32:$A), (ins MEMii:$addr), 859 !strconcat(asmop, "\t$A, [$addr]"), []>, ArcLdStRel; 860 861 def _rlimm: F32_LD_RLIMM<x.Value, NoAM.Value, di.Value, zz.Value, 862 (outs GPR32:$A), (ins MEMrlimm:$addr), 863 !strconcat(asmop, "\t$A, [$addr]"), []>, ArcLdStRel; 864 865 foreach aa = [PreIncAM, PostIncAM] in { 866 def aa.InstSuffix#_rs9: F32_LD_RS9<x.Value, aa.Value, di.Value, zz.Value, 867 (outs GPR32:$A, GPR32:$addrout), 868 (ins GPR32:$B, immS<9>:$S9), 869 asmop#aa.AsmSuffix#"\t$A, [$B,$S9]", []>, ArcLdStRel 870 { let Constraints = "$addrout = $B"; let AA = aa; } 871 } 872 } 873} 874 875foreach di = [NoCC, UncachedCC] in { 876 defm LD#di.InstSuffix : ArcLdInst<WordSM, NoEM, di, "ld"#di.AsmSuffix>; 877 foreach zz = [ByteSM, HalfSM] in { 878 foreach x = [NoEM, SignedEM] in { 879 defm LD#zz.InstSuffix#x.InstSuffix#di.InstSuffix : ArcLdInst<zz, x, di, "ld"#zz.AsmSuffix#x.AsmSuffix#di.AsmSuffix>; 880 } 881 } 882} 883 884// Load instruction patterns. 885// 32-bit loads. 886def : Pat<(load AddrModeS9:$addr), (LD_rs9 AddrModeS9:$addr)>; 887def : Pat<(load AddrModeImm:$addr), (LD_limm AddrModeImm:$addr)>; 888def : Pat<(load AddrModeFar:$addr), (LD_rs9 AddrModeFar:$addr)>; 889 890// 16-bit loads 891def : Pat<(zextloadi16 AddrModeS9:$addr), (LDH_rs9 AddrModeS9:$addr)>; 892def : Pat<(extloadi16 AddrModeS9:$addr), (LDH_rs9 AddrModeS9:$addr)>; 893def : Pat<(zextloadi16 AddrModeImm:$addr), (LDH_limm AddrModeImm:$addr)>; 894def : Pat<(extloadi16 AddrModeImm:$addr), (LDH_limm AddrModeImm:$addr)>; 895def : Pat<(zextloadi16 AddrModeFar:$addr), (LDH_rlimm AddrModeFar:$addr)>; 896def : Pat<(extloadi16 AddrModeFar:$addr), (LDH_rlimm AddrModeFar:$addr)>; 897def : Pat<(sextloadi16 AddrModeImm:$addr),(LDH_X_limm AddrModeImm:$addr)>; 898def : Pat<(sextloadi16 AddrModeFar:$addr),(LDH_X_rlimm AddrModeFar:$addr)>; 899def : Pat<(sextloadi16 AddrModeS9:$addr),(LDH_X_rs9 AddrModeS9:$addr)>; 900 901// 8-bit loads. 902def : Pat<(zextloadi8 AddrModeS9:$addr), (LDB_rs9 AddrModeS9:$addr)>; 903def : Pat<(extloadi8 AddrModeS9:$addr), (LDB_rs9 AddrModeS9:$addr)>; 904def : Pat<(zextloadi8 AddrModeImm:$addr), (LDB_limm AddrModeImm:$addr)>; 905def : Pat<(extloadi8 AddrModeImm:$addr), (LDB_limm AddrModeImm:$addr)>; 906def : Pat<(zextloadi8 AddrModeFar:$addr), (LDB_rlimm AddrModeFar:$addr)>; 907def : Pat<(extloadi8 AddrModeFar:$addr), (LDB_rlimm AddrModeFar:$addr)>; 908def : Pat<(zextloadi1 AddrModeS9:$addr), (LDB_rs9 AddrModeS9:$addr)>; 909def : Pat<(extloadi1 AddrModeS9:$addr), (LDB_rs9 AddrModeS9:$addr)>; 910def : Pat<(zextloadi1 AddrModeImm:$addr), (LDB_limm AddrModeImm:$addr)>; 911def : Pat<(extloadi1 AddrModeImm:$addr), (LDB_limm AddrModeImm:$addr)>; 912def : Pat<(zextloadi1 AddrModeFar:$addr), (LDB_rlimm AddrModeFar:$addr)>; 913def : Pat<(extloadi1 AddrModeFar:$addr), (LDB_rlimm AddrModeFar:$addr)>; 914def : Pat<(sextloadi8 AddrModeImm:$addr),(LDB_X_limm AddrModeImm:$addr)>; 915def : Pat<(sextloadi8 AddrModeFar:$addr),(LDB_X_rlimm AddrModeFar:$addr)>; 916def : Pat<(sextloadi8 AddrModeS9:$addr),(LDB_X_rs9 AddrModeS9:$addr)>; 917 918 919// Store instruction variants: 920// Control bits: aa, di, zz 921// aa - incrementing mode. (N/A for LIMM). 922// di - uncached. 923// zz - data size. 924multiclass ArcStInst<DataSizeMode zz, CacheMode di, string asmop> { 925 let mayStore = 1, ZZ = zz, DI = di in { 926 def _rs9: F32_ST_ADDR<NoAM.Value, di.Value, zz.Value, 927 (outs), (ins GPR32:$C, MEMrs9:$addr), 928 !strconcat(asmop, "\t$C, [$addr]"), []>, ArcLdStRel; 929 930 def _limm: F32_ST_LIMM<di.Value, zz.Value, 931 (outs), (ins GPR32:$C, MEMii:$addr), 932 !strconcat(asmop, "\t$C, [$addr]"), []>, ArcLdStRel; 933 934 935 foreach aa = [PreIncAM, PostIncAM] in { 936 def aa.InstSuffix#_rs9: F32_ST_RS9<aa.Value, di.Value, zz.Value, 937 (outs GPR32:$addrout), 938 (ins GPR32:$C, GPR32:$B, immS<9>:$S9), 939 asmop#aa.AsmSuffix#"\t$C, [$B,$S9]", []>, ArcLdStRel 940 { let Constraints = "$addrout = $B"; let AA = aa; } 941 } 942 } 943} 944 945foreach di = [NoCC, UncachedCC] in { 946 foreach zz = [ByteSM, HalfSM, WordSM] in { 947 defm ST#zz.InstSuffix#di.InstSuffix : ArcStInst<zz, di, "st"#zz.AsmSuffix#di.AsmSuffix>; 948 } 949} 950 951// Store instruction patterns. 952// 32-bit stores 953def : Pat<(store i32:$C, AddrModeS9:$addr), 954 (ST_rs9 i32:$C, AddrModeS9:$addr)>; 955def : Pat<(store i32:$C, AddrModeImm:$addr), 956 (ST_limm i32:$C, AddrModeImm:$addr)>; 957 958// 16-bit stores 959def : Pat<(truncstorei16 i32:$C, AddrModeS9:$addr), 960 (STH_rs9 i32:$C, AddrModeS9:$addr)>; 961def : Pat<(truncstorei16 i32:$C, AddrModeImm:$addr), 962 (STH_limm i32:$C, AddrModeImm:$addr)>; 963 964// 8-bit stores 965def : Pat<(truncstorei8 i32:$C, AddrModeS9:$addr), 966 (STB_rs9 i32:$C, AddrModeS9:$addr)>; 967def : Pat<(truncstorei8 i32:$C, AddrModeImm:$addr), 968 (STB_limm i32:$C, AddrModeImm:$addr)>; 969 970def getPostIncOpcode : InstrMapping { 971 let FilterClass = "ArcLdStRel"; 972 let RowFields = [ "BaseOpcode", "ZZ", "DI", "X"]; 973 let ColFields = [ "AA" ]; 974 let KeyCol = [ "NoAM" ]; 975 let ValueCols = [["PostIncAM"]]; 976} 977