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