Index: lib/Target/RISCV/RISCVInstrInfo.td =================================================================== --- lib/Target/RISCV/RISCVInstrInfo.td +++ lib/Target/RISCV/RISCVInstrInfo.td @@ -329,7 +329,7 @@ let isCall = 1 in def JALR : RVInstI<0b000, OPC_JALR, (outs GPR:$rd), (ins GPR:$rs1, simm12:$imm12), - "jalr", "$rd, $rs1, $imm12">; + "jalr", "$rd, ${imm12}(${rs1})">; } // hasSideEffects = 0, mayLoad = 0, mayStore = 0 def BEQ : BranchCC_rri<0b000, "beq">; @@ -558,12 +558,23 @@ def : InstAlias<"bleu $rs, $rt, $offset", (BGEU GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>; -// "ret" has more weight since "ret" and "jr" alias the same "jalr" instruction. -def : InstAlias<"j $offset", (JAL X0, simm21_lsb0_jal:$offset)>; -def : InstAlias<"jal $offset", (JAL X1, simm21_lsb0_jal:$offset)>; -def : InstAlias<"jr $rs", (JALR X0, GPR:$rs, 0)>; -def : InstAlias<"jalr $rs", (JALR X1, GPR:$rs, 0)>; -def : InstAlias<"ret", (JALR X0, X1, 0), 2>; +def : InstAlias<"j $offset", (JAL X0, simm21_lsb0_jal:$offset)>; +def : InstAlias<"jal $offset", (JAL X1, simm21_lsb0_jal:$offset)>; + +// Non-zero offset aliases of "jalr" are the lowest weight, followed by the +// two-register form, then the one-register forms and finally "ret". +def : InstAlias<"jr $rs", (JALR X0, GPR:$rs, 0), 3>; +def : InstAlias<"jr ${offset}(${rs})", (JALR X0, GPR:$rs, simm12:$offset)>; +def : InstAlias<"jalr $rs", (JALR X1, GPR:$rs, 0), 3>; +def : InstAlias<"jalr ${offset}(${rs})", (JALR X1, GPR:$rs, simm12:$offset)>; +def : InstAlias<"jalr $rd, $rs", (JALR GPR:$rd, GPR:$rs, 0), 2>; +def : InstAlias<"ret", (JALR X0, X1, 0), 4>; + +// Non-canonical forms for jump targets also accepted by the assembler. +def : InstAlias<"jr $rs, $offset", (JALR X0, GPR:$rs, simm12:$offset), 0>; +def : InstAlias<"jalr $rs, $offset", (JALR X1, GPR:$rs, simm12:$offset), 0>; +def : InstAlias<"jalr $rd, $rs, $offset", (JALR GPR:$rd, GPR:$rs, simm12:$offset), 0>; + // TODO call // TODO tail Index: test/CodeGen/RISCV/branch-relaxation.ll =================================================================== --- test/CodeGen/RISCV/branch-relaxation.ll +++ test/CodeGen/RISCV/branch-relaxation.ll @@ -25,6 +25,7 @@ ret void } +; TODO: Extend simm12's MCOperandPredicate so the jalr zero is printed as a jr. define i32 @relax_jal(i1 %a) { ; CHECK-LABEL: relax_jal: ; CHECK: # %bb.0: @@ -32,7 +33,7 @@ ; CHECK-NEXT: bnez a0, .LBB1_1 ; CHECK-NEXT: # %bb.3: ; CHECK-NEXT: lui a0, %hi(.LBB1_2) -; CHECK-NEXT: jalr zero, a0, %lo(.LBB1_2) +; CHECK-NEXT: jalr zero, %lo(.LBB1_2)(a0) ; CHECK-NEXT: .LBB1_1: # %iftrue ; CHECK-NEXT: #APP ; CHECK-NEXT: #NO_APP Index: test/CodeGen/RISCV/indirectbr.ll =================================================================== --- test/CodeGen/RISCV/indirectbr.ll +++ test/CodeGen/RISCV/indirectbr.ll @@ -25,7 +25,7 @@ ; RV32I: # %bb.0: ; RV32I-NEXT: addi sp, sp, -16 ; RV32I-NEXT: sw ra, 12(sp) -; RV32I-NEXT: jalr zero, a0, 1380 +; RV32I-NEXT: jr 1380(a0) ; RV32I-NEXT: .LBB1_1: ; RV32I-NEXT: mv a0, zero ; RV32I-NEXT: lw ra, 12(sp) Index: test/CodeGen/RISCV/option-rvc.ll =================================================================== --- test/CodeGen/RISCV/option-rvc.ll +++ test/CodeGen/RISCV/option-rvc.ll @@ -8,7 +8,7 @@ define i32 @add(i32 %a, i32 %b) nounwind { ; CHECK-LABEL: add: ; CHECK: add a0, a1, a0 -; CHECK-NEXT: jalr zero, ra, 0 +; CHECK-NEXT: jalr zero, 0(ra) tail call void asm sideeffect ".option rvc", ""() %add = add nsw i32 %b, %a ret i32 %add Index: test/MC/RISCV/compress-rv32i.s =================================================================== --- test/MC/RISCV/compress-rv32i.s +++ test/MC/RISCV/compress-rv32i.s @@ -168,7 +168,7 @@ # CHECK-ALIAS: ret # CHECK-INST: c.jr ra # CHECK: # encoding: [0x82,0x80] -jalr zero, ra, 0 +jalr zero, 0(ra) # CHECK-BYTES: 92 80 # CHECK-ALIAS: add ra, zero, tp @@ -192,7 +192,7 @@ # CHECK-ALIAS: jalr s0 # CHECK-INST: c.jalr s0 # CHECK: # encoding: [0x02,0x94] -jalr ra, s0, 0 +jalr ra, 0(s0) # CHECK-BYTES: 3e 94 # CHECK-ALIAS: add s0, s0, a5 Index: test/MC/RISCV/fixups.s =================================================================== --- test/MC/RISCV/fixups.s +++ test/MC/RISCV/fixups.s @@ -68,16 +68,16 @@ call func # CHECK-FIXUP: fixup A - offset: 0, value: func, kind: fixup_riscv_call # CHECK-INSTR: auipc ra, 0 -# CHECK-INSTR: jalr ra, ra, -100 +# CHECK-INSTR: jalr ra, -100(ra) .fill 10000 call func # CHECK-FIXUP: fixup A - offset: 0, value: func, kind: fixup_riscv_call # CHECK-INSTR: auipc ra, 1048574 -# CHECK-INSTR: jalr ra, ra, -1916 +# CHECK-INSTR: jalr ra, -1916(ra) .fill 20888 call func # CHECK-FIXUP: fixup A - offset: 0, value: func, kind: fixup_riscv_call # CHECK-INSTR: auipc ra, 1048568 -# CHECK-INSTR: jalr ra, ra, 1764 +# CHECK-INSTR: jalr ra, 1764(ra) Index: test/MC/RISCV/rv32i-valid.s =================================================================== --- test/MC/RISCV/rv32i-valid.s +++ test/MC/RISCV/rv32i-valid.s @@ -85,21 +85,21 @@ # CHECK-ASM: encoding: [0x6f,0x05,0xe0,0x01] jal a0, CONST -# CHECK-ASM-AND-OBJ: jalr a0, a1, -2048 +# CHECK-ASM-AND-OBJ: jalr a0, -2048(a1) # CHECK-ASM: encoding: [0x67,0x85,0x05,0x80] -jalr a0, a1, -2048 -# CHECK-ASM-AND-OBJ: jalr a0, a1, -2048 +jalr a0, -2048(a1) +# CHECK-ASM-AND-OBJ: jalr a0, -2048(a1) # CHECK-ASM: encoding: [0x67,0x85,0x05,0x80] -jalr a0, a1, %lo(2048) -# CHECK-ASM-AND-OBJ: jalr t2, t1, 2047 +jalr a0, %lo(2048)(a1) +# CHECK-ASM-AND-OBJ: jalr t2, 2047(t1) # CHECK-ASM: encoding: [0xe7,0x03,0xf3,0x7f] -jalr t2, t1, 2047 -# CHECK-ASM-AND-OBJ: jalr sp, zero, 256 +jalr t2, 2047(t1) +# CHECK-ASM-AND-OBJ: jalr sp, 256(zero) # CHECK-ASM: encoding: [0x67,0x01,0x00,0x10] jalr sp, zero, 256 -# CHECK-ASM-AND-OBJ: jalr a1, a2, 30 +# CHECK-ASM-AND-OBJ: jalr a1, 30(a2) # CHECK-ASM: encoding: [0xe7,0x05,0xe6,0x01] -jalr a1, a2, CONST +jalr a1, CONST(a2) # CHECK-ASM-AND-OBJ: beq s1, s1, 102 # CHECK-ASM: encoding: [0x63,0x83,0x94,0x06] Index: test/MC/RISCV/rvi-aliases-valid.s =================================================================== --- test/MC/RISCV/rvi-aliases-valid.s +++ test/MC/RISCV/rvi-aliases-valid.s @@ -132,13 +132,31 @@ # CHECK-OBJ: jal 0 # CHECK-OBJ: R_RISCV_JAL a0 jal a0 -# CHECK-S-OBJ-NOALIAS: jalr zero, s4, 0 +# CHECK-S-OBJ-NOALIAS: jalr zero, 0(s4) # CHECK-S-OBJ: jr s4 jr x20 -# CHECK-S-OBJ-NOALIAS: jalr ra, s5, 0 -# CHECK-S-OBJ: jalr s5 -jalr x21 -# CHECK-S-OBJ-NOALIAS: jalr zero, ra, 0 +# CHECK-S-OBJ-NOALIAS: jalr zero, 6(s5) +# CHECK-S-OBJ: jr 6(s5) +jr 6(x21) +# CHECK-S-OBJ-NOALIAS: jalr zero, 7(s6) +# CHECK-S-OBJ: jr 7(s6) +jr x22, 7 +# CHECK-S-OBJ-NOALIAS: jalr ra, 0(s4) +# CHECK-S-OBJ: jalr s4 +jalr x20 +# CHECK-S-OBJ-NOALIAS: jalr ra, 8(s5) +# CHECK-S-OBJ: jalr 8(s5) +jalr 8(x21) +# CHECK-S-OBJ-NOALIAS: jalr s6, 0(s7) +# CHECK-S-OBJ: jalr s6, s7 +jalr x22, x23 +# CHECK-S-OBJ-NOALIAS: jalr ra, 9(s8) +# CHECK-S-OBJ: jalr 9(s8) +jalr x24, 9 +# CHECK-S-OBJ-NOALIAS: jalr s9, 11(s10) +# CHECK-S-OBJ: jalr s9, 11(s10) +jalr x25, x26, 11 +# CHECK-S-OBJ-NOALIAS: jalr zero, 0(ra) # CHECK-S-OBJ: ret ret # TODO call