From d66a9d196ea1ef0d226b03c35211f772f2cb6f9e Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Wed, 19 Apr 2017 16:26:04 -0700 Subject: [PATCH] Implement binary emission of RISC-V return instructions. The return address is now always supplied in %x1, so the return address predictor will recognize the jalr as a return and not some indirect branch. --- cranelift/filetests/isa/riscv/binary32.cton | 9 ++++++--- lib/cretonne/meta/isa/riscv/recipes.py | 2 +- lib/cretonne/src/isa/riscv/binemit.rs | 10 ++++++++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/cranelift/filetests/isa/riscv/binary32.cton b/cranelift/filetests/isa/riscv/binary32.cton index 984b7b8a80..f62a6187e0 100644 --- a/cranelift/filetests/isa/riscv/binary32.cton +++ b/cranelift/filetests/isa/riscv/binary32.cton @@ -2,10 +2,10 @@ test binemit isa riscv -function RV32I() { +function RV32I(i32 link [%x1]) -> i32 link [%x1] { fn0 = function foo() -ebb0: +ebb0(v9999: i32): [-,%x10] v1 = iconst.i32 1 [-,%x21] v2 = iconst.i32 2 @@ -83,7 +83,10 @@ ebb0: call fn0() ; bin: Call(fn0) 000000ef brz v1, ebb3 - fallthrough ebb1 + brnz v1, ebb1 + + ; jalr %x0, %x1, 0 + return v9999 ; bin: 00008067 ebb1: ; beq 0x000 diff --git a/lib/cretonne/meta/isa/riscv/recipes.py b/lib/cretonne/meta/isa/riscv/recipes.py index ad682fa74b..b5aa56bc85 100644 --- a/lib/cretonne/meta/isa/riscv/recipes.py +++ b/lib/cretonne/meta/isa/riscv/recipes.py @@ -110,7 +110,7 @@ Iicmp = EncRecipe( # I-type encoding for `jalr` as a return instruction. We won't use the # immediate offset. # The variable return values are not encoded. -Iret = EncRecipe('Iret', MultiAry, size=4, ins=GPR, outs=()) +Iret = EncRecipe('Iret', MultiAry, size=4, ins=(), outs=()) # U-type instructions have a 20-bit immediate that targets bits 12-31. U = EncRecipe( diff --git a/lib/cretonne/src/isa/riscv/binemit.rs b/lib/cretonne/src/isa/riscv/binemit.rs index 94ba8b53bf..12a3eb462f 100644 --- a/lib/cretonne/src/isa/riscv/binemit.rs +++ b/lib/cretonne/src/isa/riscv/binemit.rs @@ -172,8 +172,14 @@ fn recipe_iicmp(func: &Function, inst: Inst, sink: &mut C } } -fn recipe_iret(_func: &Function, _inst: Inst, _sink: &mut CS) { - unimplemented!() +fn recipe_iret(func: &Function, inst: Inst, sink: &mut CS) { + // Return instructions are always a jalr to %x1. + // The return address is provided as a special-purpose link argument. + put_i(func.encodings[inst].bits(), + 1, // rs1 = %x1 + 0, // no offset. + 0, // rd = %x0: no address written. + sink); } /// U-type instructions.