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