RISC-V: far-branch: Handle far jumps and branches for functions larger than 1MB
On RISC-V, branches further than +/-1MB require a longer instruction sequence (3 instructions): we can reuse the jump-construction in the assmbler (which clobbers $ra) and a temporary to set up the jump destination. gcc/ChangeLog: * config/riscv/riscv.cc (struct machine_function): Track if a far-branch/jump is used within a function (and $ra needs to be saved). (riscv_print_operand): Implement 'N' (inverse integer branch). (riscv_far_jump_used_p): Implement. (riscv_save_return_addr_reg_p): New function. (riscv_save_reg_p): Use riscv_save_return_addr_reg_p. * config/riscv/riscv.h (FIXED_REGISTERS): Update $ra. (CALL_USED_REGISTERS): Update $ra. * config/riscv/riscv.md: Add new types "ret" and "jalr". (length attribute): Handle long conditional and unconditional branches. (conditional branch pattern): Handle case where jump can not reach the intended target. (indirect_jump, tablejump): Use new "jalr" type. (simple_return): Use new "ret" type. (simple_return_internal, eh_return_internal): Likewise. (gpr_restore_return, riscv_mret): Likewise. (riscv_uret, riscv_sret): Likewise. * config/riscv/generic.md (generic_branch): Also recognize jalr & ret types. * config/riscv/sifive-7.md (sifive_7_jump): Likewise. Co-authored-by:Philipp Tomsich <philipp.tomsich@vrull.eu> Co-authored-by:
Jeff Law <jlaw@ventanamicro.com>
Showing
- gcc/config/riscv/generic.md 1 addition, 1 deletiongcc/config/riscv/generic.md
- gcc/config/riscv/riscv.cc 68 additions, 5 deletionsgcc/config/riscv/riscv.cc
- gcc/config/riscv/riscv.h 2 additions, 2 deletionsgcc/config/riscv/riscv.h
- gcc/config/riscv/riscv.md 39 additions, 15 deletionsgcc/config/riscv/riscv.md
- gcc/config/riscv/sifive-7.md 1 addition, 1 deletiongcc/config/riscv/sifive-7.md
Loading
Please register or sign in to comment