[llvm] r326626 - [RISCV] Implement MC relaxations for compressed instructions.
Sameer AbuAsal via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 2 14:04:12 PST 2018
Author: sabuasal
Date: Fri Mar 2 14:04:12 2018
New Revision: 326626
URL: http://llvm.org/viewvc/llvm-project?rev=326626&view=rev
Log:
[RISCV] Implement MC relaxations for compressed instructions.
Summary:
This patch implements relaxation for RISCV in the MC layer.
The following relaxations are currently handled:
1) Relax C_BEQZ to BEQ and C_BNEZ to BNEZ in RISCV.
2) Relax and C_J $imm to JAL x0, $imm and CJAL to JAL ra, $imm.
Reviewers: asb, llvm-commits, efriedma
Reviewed By: asb
Subscribers: shiva0217
Differential Revision: https://reviews.llvm.org/D43055
Added:
llvm/trunk/test/MC/RISCV/rv32-relaxation.s
llvm/trunk/test/MC/RISCV/rv64-relaxation.s
Modified:
llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
llvm/trunk/test/MC/RISCV/fixups-compressed.s
llvm/trunk/test/MC/RISCV/relocations.s
Modified: llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp?rev=326626&r1=326625&r2=326626&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp (original)
+++ llvm/trunk/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp Fri Mar 2 14:04:12 2018
@@ -45,9 +45,7 @@ public:
bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
const MCRelaxableFragment *DF,
- const MCAsmLayout &Layout) const override {
- return false;
- }
+ const MCAsmLayout &Layout) const override;
unsigned getNumFixupKinds() const override {
return RISCV::NumTargetFixupKinds;
@@ -79,17 +77,92 @@ public:
return Infos[Kind - FirstTargetFixupKind];
}
- bool mayNeedRelaxation(const MCInst &Inst) const override { return false; }
+ bool mayNeedRelaxation(const MCInst &Inst) const override;
+ unsigned getRelaxedOpcode(unsigned Op) const;
void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
- MCInst &Res) const override {
+ MCInst &Res) const override;
- report_fatal_error("RISCVAsmBackend::relaxInstruction() unimplemented");
- }
bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
};
+
+bool RISCVAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup,
+ uint64_t Value,
+ const MCRelaxableFragment *DF,
+ const MCAsmLayout &Layout) const {
+ int64_t Offset = int64_t(Value);
+ switch ((unsigned)Fixup.getKind()) {
+ default:
+ return false;
+ case RISCV::fixup_riscv_rvc_branch:
+ // For compressed branch instructions the immediate must be
+ // in the range [-256, 254].
+ return Offset > 254 || Offset < -256;
+ case RISCV::fixup_riscv_rvc_jump:
+ // For compressed jump instructions the immediate must be
+ // in the range [-2048, 2046].
+ return Offset > 2046 || Offset < -2048;
+ }
+}
+
+void RISCVAsmBackend::relaxInstruction(const MCInst &Inst,
+ const MCSubtargetInfo &STI,
+ MCInst &Res) const {
+ // TODO: replace this with call to auto generated uncompressinstr() function.
+ switch (Inst.getOpcode()) {
+ default:
+ llvm_unreachable("Opcode not expected!");
+ case RISCV::C_BEQZ:
+ // c.beqz $rs1, $imm -> beq $rs1, X0, $imm.
+ Res.setOpcode(RISCV::BEQ);
+ Res.addOperand(Inst.getOperand(0));
+ Res.addOperand(MCOperand::createReg(RISCV::X0));
+ Res.addOperand(Inst.getOperand(1));
+ break;
+ case RISCV::C_BNEZ:
+ // c.bnez $rs1, $imm -> bne $rs1, X0, $imm.
+ Res.setOpcode(RISCV::BNE);
+ Res.addOperand(Inst.getOperand(0));
+ Res.addOperand(MCOperand::createReg(RISCV::X0));
+ Res.addOperand(Inst.getOperand(1));
+ break;
+ case RISCV::C_J:
+ // c.j $imm -> jal X0, $imm.
+ Res.setOpcode(RISCV::JAL);
+ Res.addOperand(MCOperand::createReg(RISCV::X0));
+ Res.addOperand(Inst.getOperand(0));
+ break;
+ case RISCV::C_JAL:
+ // c.jal $imm -> jal X1, $imm.
+ Res.setOpcode(RISCV::JAL);
+ Res.addOperand(MCOperand::createReg(RISCV::X1));
+ Res.addOperand(Inst.getOperand(0));
+ break;
+ }
+}
+
+// Given a compressed control flow instruction this function returns
+// the expanded instruction.
+unsigned RISCVAsmBackend::getRelaxedOpcode(unsigned Op) const {
+ switch (Op) {
+ default:
+ return Op;
+ case RISCV::C_BEQZ:
+ return RISCV::BEQ;
+ case RISCV::C_BNEZ:
+ return RISCV::BNE;
+ case RISCV::C_J:
+ case RISCV::C_JAL: // fall through.
+ return RISCV::JAL;
+ }
+}
+
+bool RISCVAsmBackend::mayNeedRelaxation(const MCInst &Inst) const {
+ return getRelaxedOpcode(Inst.getOpcode()) != Inst.getOpcode();
+}
+
bool RISCVAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
bool HasStdExtC = STI.getFeatureBits()[RISCV::FeatureStdExtC];
unsigned MinNopLen = HasStdExtC ? 2 : 4;
Modified: llvm/trunk/test/MC/RISCV/fixups-compressed.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/fixups-compressed.s?rev=326626&r1=326625&r2=326626&view=diff
==============================================================================
--- llvm/trunk/test/MC/RISCV/fixups-compressed.s (original)
+++ llvm/trunk/test/MC/RISCV/fixups-compressed.s Fri Mar 2 14:04:12 2018
@@ -2,13 +2,15 @@
# RUN: | FileCheck -check-prefix=CHECK-FIXUP %s
# RUN: llvm-mc -triple riscv32 -filetype=obj -mattr=+c < %s \
# RUN: | llvm-objdump -d - | FileCheck -check-prefix=CHECK-INSTR %s
+# RUN: llvm-mc -filetype=obj -mattr=+c -triple=riscv32 %s \
+# RUN: | llvm-readobj -r | FileCheck %s -check-prefix=CHECK-REL
.LBB0_2:
# CHECK-FIXUP: fixup A - offset: 0, value: .LBB0_2, kind: fixup_riscv_rvc_jump
# CHECK-INSTR: c.j 0
c.j .LBB0_2
# CHECK: fixup A - offset: 0, value: func1, kind: fixup_riscv_rvc_jump
-# CHECK-INSTR: c.jal 0
+# CHECK-INSTR: c.jal 6
c.jal func1
# CHECK-FIXUP: fixup A - offset: 0, value: .LBB0_2, kind: fixup_riscv_rvc_branch
# CHECK-INSTR: c.beqz a3, -4
@@ -16,3 +18,8 @@ c.beqz a3, .LBB0_2
# CHECK-FIXUP: fixup A - offset: 0, value: .LBB0_2, kind: fixup_riscv_rvc_branch
# CHECK-INSTR: c.bnez a5, -6
c.bnez a5, .LBB0_2
+
+func1:
+ nop
+
+# CHECK-REL-NOT: R_RISCV
Modified: llvm/trunk/test/MC/RISCV/relocations.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/relocations.s?rev=326626&r1=326625&r2=326626&view=diff
==============================================================================
--- llvm/trunk/test/MC/RISCV/relocations.s (original)
+++ llvm/trunk/test/MC/RISCV/relocations.s Fri Mar 2 14:04:12 2018
@@ -85,11 +85,13 @@ bgeu a0, a1, foo
# FIXUP: fixup A - offset: 0, value: foo, kind: fixup_riscv_branch
c.jal foo
-# RELOC: R_RISCV_RVC_JUMP
+# A compressed jump (c.j) to an unresolved symbol will be relaxed to a (jal).
+# RELOC: R_RISCV_JAL
# INSTR: c.jal foo
# FIXUP: fixup A - offset: 0, value: foo, kind: fixup_riscv_rvc_jump
c.bnez a0, foo
-# RELOC: R_RISCV_RVC_BRANCH
+# A compressed branch (c.bnez) to an unresolved symbol will be relaxed to a (bnez).
+# RELOC: R_RISCV_BRANCH
# INSTR: c.bnez a0, foo
# FIXUP: fixup A - offset: 0, value: foo, kind: fixup_riscv_rvc_branch
Added: llvm/trunk/test/MC/RISCV/rv32-relaxation.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/rv32-relaxation.s?rev=326626&view=auto
==============================================================================
--- llvm/trunk/test/MC/RISCV/rv32-relaxation.s (added)
+++ llvm/trunk/test/MC/RISCV/rv32-relaxation.s Fri Mar 2 14:04:12 2018
@@ -0,0 +1,75 @@
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+c < %s \
+# RUN: | llvm-objdump -d - | FileCheck -check-prefix=INSTR %s
+
+FAR_JUMP_NEGATIVE:
+ c.nop
+.space 2000
+
+FAR_BRANCH_NEGATIVE:
+ c.nop
+.space 256
+
+NEAR_NEGATIVE:
+ c.nop
+
+start:
+ c.bnez a0, NEAR
+#INSTR: c.bnez a0, 72
+ c.bnez a0, NEAR_NEGATIVE
+#INSTR: c.bnez a0, -4
+ c.bnez a0, FAR_BRANCH
+#INSTR-NEXT: bnez a0, 326
+ c.bnez a0, FAR_BRANCH_NEGATIVE
+#INSTR-NEXT: bnez a0, -268
+ c.bnez a0, FAR_JUMP
+#INSTR-NEXT: bnez a0, 2320
+ c.bnez a0, FAR_JUMP_NEGATIVE
+#INSTR-NEXT: bnez a0, -2278
+
+ c.beqz a0, NEAR
+#INSTR-NEXT: c.beqz a0, 52
+ c.beqz a0, NEAR_NEGATIVE
+#INSTR-NEXT: c.beqz a0, -24
+ c.beqz a0, FAR_BRANCH
+#INSTR-NEXT: beqz a0, 306
+ c.beqz a0, FAR_BRANCH_NEGATIVE
+#INSTR-NEXT: beqz a0, -288
+ c.beqz a0, FAR_JUMP
+#INSTR-NEXT: beqz a0, 2300
+ c.beqz a0, FAR_JUMP_NEGATIVE
+#INSTR-NEXT: beqz a0, -2298
+
+ c.j NEAR
+#INSTR-NEXT: c.j 32
+ c.j NEAR_NEGATIVE
+#INSTR-NEXT: c.j -44
+ c.j FAR_BRANCH
+#INSTR-NEXT: c.j 286
+ c.j FAR_BRANCH_NEGATIVE
+#INSTR-NEXT: c.j -306
+ c.j FAR_JUMP
+#INSTR-NEXT: j 2284
+ c.j FAR_JUMP_NEGATIVE
+#INSTR-NEXT: j -2314
+
+ c.jal NEAR
+#INSTR: c.jal 16
+ c.jal NEAR_NEGATIVE
+#INSTR: c.jal -60
+ c.jal FAR_BRANCH
+#INSTR-NEXT: c.jal 270
+ c.jal FAR_BRANCH_NEGATIVE
+#INSTR-NEXT: c.jal -322
+ c.jal FAR_JUMP
+#INSTR-NEXT: jal 2268
+ c.jal FAR_JUMP_NEGATIVE
+#INSTR-NEXT: jal -2330
+
+NEAR:
+ c.nop
+.space 256
+FAR_BRANCH:
+ c.nop
+.space 2000
+FAR_JUMP:
+ c.nop
Added: llvm/trunk/test/MC/RISCV/rv64-relaxation.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/rv64-relaxation.s?rev=326626&view=auto
==============================================================================
--- llvm/trunk/test/MC/RISCV/rv64-relaxation.s (added)
+++ llvm/trunk/test/MC/RISCV/rv64-relaxation.s Fri Mar 2 14:04:12 2018
@@ -0,0 +1,64 @@
+# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+c < %s \
+# RUN: | llvm-objdump -d - | FileCheck -check-prefix=INSTR %s
+
+FAR_JUMP_NEGATIVE:
+ c.nop
+.space 2000
+
+FAR_BRANCH_NEGATIVE:
+ c.nop
+.space 256
+
+NEAR_NEGATIVE:
+ c.nop
+
+start:
+ c.bnez a0, NEAR
+#INSTR: c.bnez a0, 56
+ c.bnez a0, NEAR_NEGATIVE
+#INSTR: c.bnez a0, -4
+ c.bnez a0, FAR_BRANCH
+#INSTR-NEXT: bnez a0, 310
+ c.bnez a0, FAR_BRANCH_NEGATIVE
+#INSTR-NEXT: bnez a0, -268
+ c.bnez a0, FAR_JUMP
+#INSTR-NEXT: bnez a0, 2304
+ c.bnez a0, FAR_JUMP_NEGATIVE
+#INSTR-NEXT: bnez a0, -2278
+
+ c.beqz a0, NEAR
+#INSTR-NEXT: c.beqz a0, 36
+ c.beqz a0, NEAR_NEGATIVE
+#INSTR-NEXT: c.beqz a0, -24
+ c.beqz a0, FAR_BRANCH
+#INSTR-NEXT: beqz a0, 290
+ c.beqz a0, FAR_BRANCH_NEGATIVE
+#INSTR-NEXT: beqz a0, -288
+ c.beqz a0, FAR_JUMP
+#INSTR-NEXT: beqz a0, 2284
+ c.beqz a0, FAR_JUMP_NEGATIVE
+#INSTR-NEXT: beqz a0, -2298
+
+ c.j NEAR
+#INSTR-NEXT: c.j 16
+ c.j NEAR_NEGATIVE
+#INSTR-NEXT: c.j -44
+ c.j FAR_BRANCH
+#INSTR-NEXT: c.j 270
+ c.j FAR_BRANCH_NEGATIVE
+#INSTR-NEXT: c.j -306
+ c.j FAR_JUMP
+#INSTR-NEXT: j 2268
+ c.j FAR_JUMP_NEGATIVE
+#INSTR-NEXT: j -2314
+
+NEAR:
+ c.nop
+
+.space 256
+FAR_BRANCH:
+ c.nop
+
+.space 2000
+FAR_JUMP:
+ c.nop
More information about the llvm-commits
mailing list