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; -def uimm2_plus1 : Operand; +def uimm2_plus1 : Operand { + let EncoderMethod = "getImmOpValueSub1"; +} def uimm3 : Operand; def uimm5 : Operand; def uimm6 : Operand; @@ -41,12 +43,20 @@ def uimm15 : Operand; def simm12 : Operand, ImmLeaf(Imm);}]>; def simm14 : Operand; -def simm14_lsl2 : Operand; +def simm14_lsl2 : Operand { + let EncoderMethod = "getImmOpValueAsr2"; +} def simm16 : Operand; -def simm16_lsl2 : Operand; +def simm16_lsl2 : Operand { + let EncoderMethod = "getImmOpValueAsr2"; +} def simm20 : Operand; -def simm21_lsl2 : Operand; -def simm26_lsl2 : Operand; +def simm21_lsl2 : Operand { + let EncoderMethod = "getImmOpValueAsr2"; +} +def simm26_lsl2 : Operand { + 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 &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 &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 &Fixups, + const MCSubtargetInfo &STI) const; }; } // end anonymous namespace @@ -69,6 +86,31 @@ return 0; } +unsigned +LoongArchMCCodeEmitter::getImmOpValueSub1(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(OpNo); + if (MO.isImm()) + return MO.getImm() - 1; + + llvm_unreachable("Unhandled expression!"); +} + +unsigned +LoongArchMCCodeEmitter::getImmOpValueAsr2(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &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!"); +} + void LoongArchMCCodeEmitter::encodeInstruction( const MCInst &MI, raw_ostream &OS, SmallVectorImpl &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 ... # --------------------------------------------------------------------------------------------------------