diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
--- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
@@ -33,7 +33,9 @@
 }
 
 def uimm2 : Operand<GRLenVT>;
-def uimm2_plus1 : Operand<GRLenVT>;
+def uimm2_plus1 : Operand<GRLenVT> {
+  let EncoderMethod = "getImmOpValueSub1";
+}
 def uimm3 : Operand<GRLenVT>;
 def uimm5 : Operand<GRLenVT>;
 def uimm6 : Operand<GRLenVT>;
@@ -41,12 +43,20 @@
 def uimm15 : Operand<GRLenVT>;
 def simm12 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isInt<12>(Imm);}]>;
 def simm14 : Operand<GRLenVT>;
-def simm14_lsl2 : Operand<GRLenVT>;
+def simm14_lsl2 : Operand<GRLenVT> {
+  let EncoderMethod = "getImmOpValueAsr2";
+}
 def simm16 : Operand<GRLenVT>;
-def simm16_lsl2 : Operand<GRLenVT>;
+def simm16_lsl2 : Operand<GRLenVT> {
+  let EncoderMethod = "getImmOpValueAsr2";
+}
 def simm20 : Operand<GRLenVT>;
-def simm21_lsl2 : Operand<GRLenVT>;
-def simm26_lsl2 : Operand<GRLenVT>;
+def simm21_lsl2 : Operand<GRLenVT> {
+  let EncoderMethod = "getImmOpValueAsr2";
+}
+def simm26_lsl2 : Operand<GRLenVT> {
+  let EncoderMethod = "getImmOpValueAsr2";
+}
 
 //===----------------------------------------------------------------------===//
 // Instruction Formats
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp
@@ -51,6 +51,23 @@
   unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
                              SmallVectorImpl<MCFixup> &Fixups,
                              const MCSubtargetInfo &STI) const;
+
+  /// Return binary encoding of an immediate operand specified by OpNo.
+  /// The value returned is the value of the immediate minus 1.
+  /// Note that this function is dedicated to specific immediate types,
+  /// e.g. uimm2_plus1.
+  unsigned getImmOpValueSub1(const MCInst &MI, unsigned OpNo,
+                             SmallVectorImpl<MCFixup> &Fixups,
+                             const MCSubtargetInfo &STI) const;
+
+  /// Return binary encoding of an immediate operand specified by OpNo.
+  /// The value returned is the value of the immediate arithmetical right
+  //  shifts 2.
+  /// Note that this function is dedicated to specific immediate types,
+  /// e.g. simm14_lsl2, simm16_lsl2, simm21_lsl2 and simm26_lsl2.
+  unsigned getImmOpValueAsr2(const MCInst &MI, unsigned OpNo,
+                             SmallVectorImpl<MCFixup> &Fixups,
+                             const MCSubtargetInfo &STI) const;
 };
 } // end anonymous namespace
 
@@ -69,6 +86,37 @@
   return 0;
 }
 
+unsigned
+LoongArchMCCodeEmitter::getImmOpValueSub1(const MCInst &MI, unsigned OpNo,
+                                          SmallVectorImpl<MCFixup> &Fixups,
+                                          const MCSubtargetInfo &STI) const {
+  const MCOperand &MO = MI.getOperand(OpNo);
+
+  if (MO.isImm()) {
+    unsigned Res = MO.getImm();
+    return Res - 1;
+  }
+
+  llvm_unreachable("Unhandled expression!");
+  return 0;
+}
+
+unsigned
+LoongArchMCCodeEmitter::getImmOpValueAsr2(const MCInst &MI, unsigned OpNo,
+                                          SmallVectorImpl<MCFixup> &Fixups,
+                                          const MCSubtargetInfo &STI) const {
+  const MCOperand &MO = MI.getOperand(OpNo);
+
+  if (MO.isImm()) {
+    unsigned Res = MO.getImm();
+    assert((Res & 3) == 0 && "lowest 2 bits are non-zero");
+    return Res >> 2;
+  }
+
+  llvm_unreachable("Unhandled expression!");
+  return 0;
+}
+
 void LoongArchMCCodeEmitter::encodeInstruction(
     const MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups,
     const MCSubtargetInfo &STI) const {
diff --git a/llvm/test/CodeGen/LoongArch/1ri.mir b/llvm/test/CodeGen/LoongArch/1ri.mir
--- a/llvm/test/CodeGen/LoongArch/1ri.mir
+++ b/llvm/test/CodeGen/LoongArch/1ri.mir
@@ -80,17 +80,17 @@
 ---
 # CHECK-LABEL: test_BEQZ:
 # CHECK-ENC: 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 0 0 1 0 0 0 0 0 0 0
-# CHECK-ASM: beqz	$a0, 23
+# CHECK-ASM: beqz	$a0, 92
 name: test_BEQZ
 body: |
   bb.0:
-    BEQZ $r4, 23
+    BEQZ $r4, 92
 ...
 ---
 # CHECK-LABEL: test_BNEZ:
 # CHECK-ENC: 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 1 0 0 0 0 0 0 0
-# CHECK-ASM: bnez	$a0, 21
+# CHECK-ASM: bnez	$a0, 84
 name: test_BNEZ
 body: |
   bb.0:
-    BNEZ $r4, 21
+    BNEZ $r4, 84
diff --git a/llvm/test/CodeGen/LoongArch/2ri.mir b/llvm/test/CodeGen/LoongArch/2ri.mir
--- a/llvm/test/CodeGen/LoongArch/2ri.mir
+++ b/llvm/test/CodeGen/LoongArch/2ri.mir
@@ -280,74 +280,74 @@
 ---
 # CHECK-LABEL: test_LDPTR_W:
 # CHECK-ENC: 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 1 0 0 1 0 0
-# CHECK-ASM: ldptr.w	$a0, $a1, 66
+# CHECK-ASM: ldptr.w	$a0, $a1, 264
 name: test_LDPTR_W
 body: |
   bb.0:
-    $r4 = LDPTR_W $r5, 66
+    $r4 = LDPTR_W $r5, 264
 ...
 ---
 # CHECK-LABEL: test_LDPTR_D:
 # CHECK-ENC: 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 0 1 0 0 1 0 0
-# CHECK-ASM: ldptr.d	$a0, $a1, 56
+# CHECK-ASM: ldptr.d	$a0, $a1, 224
 name: test_LDPTR_D
 body: |
   bb.0:
-    $r4 = LDPTR_D $r5, 56
+    $r4 = LDPTR_D $r5, 224
 ...
 ---
 # CHECK-LABEL: test_STPTR_W:
 # CHECK-ENC: 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 1 0 1 0 1 1 1 0 0 1 0 1 0 0 1 0 0
-# CHECK-ASM: stptr.w	$a0, $a1, 87
+# CHECK-ASM: stptr.w	$a0, $a1, 348
 name: test_STPTR_W
 body: |
   bb.0:
-    STPTR_W $r4, $r5, 87
+    STPTR_W $r4, $r5, 348
 ...
 ---
 # CHECK-LABEL: test_STPTR_D:
 # CHECK-ENC: 0 0 1 0 0 1 1 1 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 1 0 1 0 0 1 0 0
-# CHECK-ASM: stptr.d	$a0, $a1, 145
+# CHECK-ASM: stptr.d	$a0, $a1, 580
 name: test_STPTR_D
 body: |
   bb.0:
-    STPTR_D $r4, $r5, 145
+    STPTR_D $r4, $r5, 580
 ...
 ---
 # CHECK-LABEL: test_LL_W:
 # CHECK-ENC: 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 1 1 0 0 1 0 1 0 0 1 0 0
-# CHECK-ASM: ll.w	$a0, $a1, 243
+# CHECK-ASM: ll.w	$a0, $a1, 972
 name: test_LL_W
 body: |
   bb.0:
-    $r4 = LL_W $r5, 243
+    $r4 = LL_W $r5, 972
 ...
 ---
 # CHECK-LABEL: test_LL_D:
 # CHECK-ENC: 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 1 0 1 0 0 1 0 0
-# CHECK-ASM: ll.d	$a0, $a1, 74
+# CHECK-ASM: ll.d	$a0, $a1, 296
 name: test_LL_D
 body: |
   bb.0:
-    $r4 = LL_D $r5, 74
+    $r4 = LL_D $r5, 296
 ...
 ---
 # CHECK-LABEL: test_SC_W:
 # CHECK-ENC: 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 1 0 0 1 0 0
-# CHECK-ASM: sc.w	$a0, $a1, 96
+# CHECK-ASM: sc.w	$a0, $a1, 384
 name: test_SC_W
 body: |
   bb.0:
-    $r4 = SC_W $r4, $r5, 96
+    $r4 = SC_W $r4, $r5, 384
 ...
 ---
 # CHECK-LABEL: test_SC_D:
 # CHECK-ENC: 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 1 1 0 1 0 0 1 0 0 1 0 1 0 0 1 0 0
-# CHECK-ASM: sc.d	$a0, $a1, 105
+# CHECK-ASM: sc.d	$a0, $a1, 420
 name: test_SC_D
 body: |
   bb.0:
-    $r4 = SC_D $r4, $r5, 105
+    $r4 = SC_D $r4, $r5, 420
 ...
 
 # -------------------------------------------------------------------------------------------------
@@ -371,62 +371,62 @@
 ---
 # CHECK-LABEL: test_JIRL:
 # CHECK-ENC: 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 1 0 1 0 0 1 0 0
-# CHECK-ASM: jirl	$a0, $a1, 49
+# CHECK-ASM: jirl	$a0, $a1, 196
 name: test_JIRL
 body: |
   bb.0:
-    $r4 = JIRL $r5, 49
+    $r4 = JIRL $r5, 196
 ...
 ---
 # CHECK-LABEL: test_BEQ:
 # CHECK-ENC: 0 1 0 1 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 1
-# CHECK-ASM: beq	$a0, $a1, 196
+# CHECK-ASM: beq	$a0, $a1, 784
 name: test_BEQ
 body: |
   bb.0:
-    BEQ $r4, $r5, 196
+    BEQ $r4, $r5, 784
 ...
 ---
 # CHECK-LABEL: test_BNE:
 # CHECK-ENC: 0 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0 1 0 0 0 0 1 0 1
-# CHECK-ASM: bne	$a0, $a1, 19
+# CHECK-ASM: bne	$a0, $a1, 76
 name: test_BNE
 body: |
   bb.0:
-    BNE $r4, $r5, 19
+    BNE $r4, $r5, 76
 ...
 ---
 # CHECK-LABEL: test_BLT:
 # CHECK-ENC: 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 0 0 1 0 0 0 0 1 0 1
-# CHECK-ASM: blt	$a0, $a1, 123
+# CHECK-ASM: blt	$a0, $a1, 492
 name: test_BLT
 body: |
   bb.0:
-    BLT $r4, $r5, 123
+    BLT $r4, $r5, 492
 ...
 ---
 # CHECK-LABEL: test_BGE:
 # CHECK-ENC: 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 1 0 1
-# CHECK-ASM: bge	$a0, $a1, 12
+# CHECK-ASM: bge	$a0, $a1, 48
 name: test_BGE
 body: |
   bb.0:
-    BGE $r4, $r5, 12
+    BGE $r4, $r5, 48
 ...
 ---
 # CHECK-LABEL: test_BLTU:
 # CHECK-ENC: 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 0 1 0 1
-# CHECK-ASM: bltu	$a0, $a1, 17
+# CHECK-ASM: bltu	$a0, $a1, 68
 name: test_BLTU
 body: |
   bb.0:
-    BLTU $r4, $r5, 17
+    BLTU $r4, $r5, 68
 ...
 ---
 # CHECK-LABEL: test_BGEU:
 # CHECK-ENC: 0 1 1 0 1 1 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 1 0 0 0 0 1 0 1
-# CHECK-ASM: bgeu	$a0, $a1, 88
+# CHECK-ASM: bgeu	$a0, $a1, 352
 name: test_BGEU
 body: |
   bb.0:
-    BGEU $r4, $r5, 88
+    BGEU $r4, $r5, 352
diff --git a/llvm/test/CodeGen/LoongArch/3ri.mir b/llvm/test/CodeGen/LoongArch/3ri.mir
--- a/llvm/test/CodeGen/LoongArch/3ri.mir
+++ b/llvm/test/CodeGen/LoongArch/3ri.mir
@@ -16,29 +16,29 @@
 ---
 # CHECK-LABEL: test_ALSL_W:
 # CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0
-# CHECK-ASM: alsl.w	$a0, $a1, $a2, 3
+# CHECK-ASM: alsl.w	$a0, $a1, $a2, 4
 name: test_ALSL_W
 body: |
   bb.0:
-    $r4 = ALSL_W $r5, $r6, 3
+    $r4 = ALSL_W $r5, $r6, 4
 ...
 ---
 # CHECK-LABEL: test_ALSL_WU:
 # CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0
-# CHECK-ASM: alsl.wu	$a0, $a1, $a2, 1
+# CHECK-ASM: alsl.wu	$a0, $a1, $a2, 2
 name: test_ALSL_WU
 body: |
   bb.0:
-    $r4 = ALSL_WU $r5, $r6, 1
+    $r4 = ALSL_WU $r5, $r6, 2
 ...
 ---
 # CHECK-LABEL: test_ALSL_D:
 # CHECK-ENC: 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1 1 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0
-# CHECK-ASM: alsl.d	$a0, $a1, $a2, 3
+# CHECK-ASM: alsl.d	$a0, $a1, $a2, 4
 name: test_ALSL_D
 body: |
   bb.0:
-    $r4 = ALSL_D $r5, $r6, 3
+    $r4 = ALSL_D $r5, $r6, 4
 ...
 ---
 # CHECK-LABEL: test_BYTEPICK_W:
diff --git a/llvm/test/CodeGen/LoongArch/misc.mir b/llvm/test/CodeGen/LoongArch/misc.mir
--- a/llvm/test/CodeGen/LoongArch/misc.mir
+++ b/llvm/test/CodeGen/LoongArch/misc.mir
@@ -62,20 +62,20 @@
 ---
 # CHECK-LABEL: test_B:
 # CHECK-ENC: 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
-# CHECK-ASM: b	20
+# CHECK-ASM: b	80
 name: test_B
 body: |
   bb.0:
-    B 20
+    B 80
 ...
 ---
 # CHECK-LABEL: test_BL:
 # CHECK-ENC: 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
-# CHECK-ASM: bl	34
+# CHECK-ASM: bl	136
 name: test_BL
 body: |
   bb.0:
-    BL 34
+    BL 136
 ...
 
 # --------------------------------------------------------------------------------------------------------