[LoongArch] Add EncoderMethods for transformed immediate operands
authorWeining Lu <luweining@loongson.cn>
Mon, 7 Mar 2022 08:38:30 +0000 (16:38 +0800)
committerWeining Lu <luweining@loongson.cn>
Mon, 7 Mar 2022 08:47:26 +0000 (16:47 +0800)
This is a split patch of D120476 and thanks to myhsu.

'Transformed' means the encoding of an immediate is not the same as
its binary representation. For example, the `bl` instruction
requires a signed 28-bits integer as its operand and the low 2 bits
must be 0. So only the upper 26 bits are needed to get encoded into
the instruction.

Based on the above reason this kind of immediate needs a customed
`EncoderMethod` to get the real value getting encoded into the
instruction.

Currently these immediate includes:
```
  uimm2_plus1
  simm14_lsl2
  simm16_lsl2
  simm21_lsl2
  simm26_lsl2
```

This patch adds those `EncoderMethod`s and revises related .mir test
in previous patch.

Reviewed By: xen0n, MaskRay

Differential Revision: https://reviews.llvm.org/D120545

llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp
llvm/test/CodeGen/LoongArch/1ri.mir
llvm/test/CodeGen/LoongArch/2ri.mir
llvm/test/CodeGen/LoongArch/3ri.mir
llvm/test/CodeGen/LoongArch/misc.mir

index ee73e81..4b452b2 100644 (file)
@@ -33,7 +33,9 @@ class UImmAsmOperand<int width, string suffix = "">
 }
 
 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 uimm12 : Operand<GRLenVT>;
 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
index 7af2dc0..9c6a4f3 100644 (file)
@@ -51,6 +51,23 @@ public:
   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 shifted right
+  //  arithmetically by 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
 
@@ -68,6 +85,22 @@ LoongArchMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
   llvm_unreachable("Unhandled expression!");
 }
 
+unsigned
+LoongArchMCCodeEmitter::getImmOpValueSub1(const MCInst &MI, unsigned OpNo,
+                                          SmallVectorImpl<MCFixup> &Fixups,
+                                          const MCSubtargetInfo &STI) const {
+  return MI.getOperand(OpNo).getImm() - 1;
+}
+
+unsigned
+LoongArchMCCodeEmitter::getImmOpValueAsr2(const MCInst &MI, unsigned OpNo,
+                                          SmallVectorImpl<MCFixup> &Fixups,
+                                          const MCSubtargetInfo &STI) const {
+  unsigned Res = MI.getOperand(OpNo).getImm();
+  assert((Res & 3) == 0 && "lowest 2 bits are non-zero");
+  return Res >> 2;
+}
+
 void LoongArchMCCodeEmitter::encodeInstruction(
     const MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups,
     const MCSubtargetInfo &STI) const {
index 537fe07..571a755 100644 (file)
@@ -80,17 +80,17 @@ body: |
 ---
 # 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
index 15a2759..263fed4 100644 (file)
@@ -280,74 +280,74 @@ body: |
 ---
 # 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 @@ body: |
 ---
 # 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
index 1f21dc2..c86e141 100644 (file)
 ---
 # 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:
index 3035edc..56793c5 100644 (file)
@@ -62,20 +62,20 @@ body: |
 ---
 # 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
 ...
 
 # --------------------------------------------------------------------------------------------------------