Use EBB offsets for encoding RISC-V branches.
Stop emitting EBB relocations. Use the offsets computed by relax_branches() to encode the correct displacements immediately.
This commit is contained in:
@@ -80,23 +80,40 @@ ebb0:
|
|||||||
; Control Transfer Instructions
|
; Control Transfer Instructions
|
||||||
|
|
||||||
ebb1:
|
ebb1:
|
||||||
; beq
|
; beq 0x000
|
||||||
br_icmp eq, v1, v2, ebb0 ; bin: Branch(ebb0) 01550063
|
br_icmp eq, v1, v2, ebb1 ; bin: 01550063
|
||||||
; bne
|
; bne 0xffc
|
||||||
br_icmp ne, v1, v2, ebb0 ; bin: Branch(ebb0) 01551063
|
br_icmp ne, v1, v2, ebb1 ; bin: ff551ee3
|
||||||
; blt
|
; blt 0xff8
|
||||||
br_icmp slt, v1, v2, ebb0 ; bin: Branch(ebb0) 01554063
|
br_icmp slt, v1, v2, ebb1 ; bin: ff554ce3
|
||||||
; bge
|
; bge 0xff4
|
||||||
br_icmp sge, v1, v2, ebb0 ; bin: Branch(ebb0) 01555063
|
br_icmp sge, v1, v2, ebb1 ; bin: ff555ae3
|
||||||
; bltu
|
; bltu 0xff0
|
||||||
br_icmp ult, v1, v2, ebb0 ; bin: Branch(ebb0) 01556063
|
br_icmp ult, v1, v2, ebb1 ; bin: ff5568e3
|
||||||
; bgeu
|
; bgeu 0xfec
|
||||||
br_icmp uge, v1, v2, ebb0 ; bin: Branch(ebb0) 01557063
|
br_icmp uge, v1, v2, ebb1 ; bin: ff5576e3
|
||||||
|
|
||||||
|
; Forward branches.
|
||||||
|
; beq 0x018
|
||||||
|
br_icmp eq, v2, v1, ebb2 ; bin: 00aa8c63
|
||||||
|
; bne 0x014
|
||||||
|
br_icmp ne, v2, v1, ebb2 ; bin: 00aa9a63
|
||||||
|
; blt 0x010
|
||||||
|
br_icmp slt, v2, v1, ebb2 ; bin: 00aac863
|
||||||
|
; bge 0x00c
|
||||||
|
br_icmp sge, v2, v1, ebb2 ; bin: 00aad663
|
||||||
|
; bltu 0x008
|
||||||
|
br_icmp ult, v2, v1, ebb2 ; bin: 00aae463
|
||||||
|
; bgeu 0x004
|
||||||
|
br_icmp uge, v2, v1, ebb2 ; bin: 00aaf263
|
||||||
|
|
||||||
|
jump ebb2
|
||||||
|
|
||||||
|
ebb2:
|
||||||
; beq x, %x0
|
; beq x, %x0
|
||||||
brz v1, ebb0 ; bin: Branch(ebb0) 00050063
|
brz v1, ebb2 ; bin: 00050063
|
||||||
; bne x, %x0
|
; bne x, %x0
|
||||||
brnz v1, ebb0 ; bin: Branch(ebb0) 00051063
|
brnz v1, ebb2 ; bin: fe051ee3
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,12 @@
|
|||||||
use binemit::{CodeSink, Reloc, bad_encoding};
|
use binemit::{CodeSink, Reloc, bad_encoding};
|
||||||
use ir::{Function, Inst, InstructionData};
|
use ir::{Function, Inst, InstructionData};
|
||||||
use isa::RegUnit;
|
use isa::RegUnit;
|
||||||
|
use predicates::is_signed_int;
|
||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/binemit-riscv.rs"));
|
include!(concat!(env!("OUT_DIR"), "/binemit-riscv.rs"));
|
||||||
|
|
||||||
/// RISC-V relocation kinds.
|
/// RISC-V relocation kinds.
|
||||||
|
#[allow(dead_code)]
|
||||||
pub enum RelocKind {
|
pub enum RelocKind {
|
||||||
/// A conditional (SB-type) branch to an EBB.
|
/// A conditional (SB-type) branch to an EBB.
|
||||||
Branch,
|
Branch,
|
||||||
@@ -213,17 +215,17 @@ fn recipe_u<CS: CodeSink + ?Sized>(func: &Function, inst: Inst, sink: &mut CS) {
|
|||||||
/// imm rs2 rs1 funct3 imm opcode
|
/// imm rs2 rs1 funct3 imm opcode
|
||||||
/// 25 20 15 12 7 0
|
/// 25 20 15 12 7 0
|
||||||
///
|
///
|
||||||
/// The imm bits are not encoded by this function. They encode the relative distance to the
|
|
||||||
/// destination block, handled by a relocation.
|
|
||||||
///
|
|
||||||
/// Encoding bits: `opcode[6:2] | (funct3 << 5)`
|
/// Encoding bits: `opcode[6:2] | (funct3 << 5)`
|
||||||
fn put_sb<CS: CodeSink + ?Sized>(bits: u16, rs1: RegUnit, rs2: RegUnit, sink: &mut CS) {
|
fn put_sb<CS: CodeSink + ?Sized>(bits: u16, imm: i64, rs1: RegUnit, rs2: RegUnit, sink: &mut CS) {
|
||||||
let bits = bits as u32;
|
let bits = bits as u32;
|
||||||
let opcode5 = bits & 0x1f;
|
let opcode5 = bits & 0x1f;
|
||||||
let funct3 = (bits >> 5) & 0x7;
|
let funct3 = (bits >> 5) & 0x7;
|
||||||
let rs1 = rs1 as u32 & 0x1f;
|
let rs1 = rs1 as u32 & 0x1f;
|
||||||
let rs2 = rs2 as u32 & 0x1f;
|
let rs2 = rs2 as u32 & 0x1f;
|
||||||
|
|
||||||
|
assert!(is_signed_int(imm, 13, 1), "SB out of range {:#x}", imm);
|
||||||
|
let imm = imm as u32;
|
||||||
|
|
||||||
// 0-6: opcode
|
// 0-6: opcode
|
||||||
let mut i = 0x3;
|
let mut i = 0x3;
|
||||||
i |= opcode5 << 2;
|
i |= opcode5 << 2;
|
||||||
@@ -231,6 +233,12 @@ fn put_sb<CS: CodeSink + ?Sized>(bits: u16, rs1: RegUnit, rs2: RegUnit, sink: &m
|
|||||||
i |= rs1 << 15;
|
i |= rs1 << 15;
|
||||||
i |= rs2 << 20;
|
i |= rs2 << 20;
|
||||||
|
|
||||||
|
// The displacement is completely hashed up.
|
||||||
|
i |= ((imm >> 11) & 0x1) << 7;
|
||||||
|
i |= ((imm >> 1) & 0xf) << 8;
|
||||||
|
i |= ((imm >> 5) & 0x3f) << 25;
|
||||||
|
i |= ((imm >> 12) & 0x1) << 31;
|
||||||
|
|
||||||
sink.put4(i);
|
sink.put4(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,9 +248,11 @@ fn recipe_sb<CS: CodeSink + ?Sized>(func: &Function, inst: Inst, sink: &mut CS)
|
|||||||
ref args,
|
ref args,
|
||||||
..
|
..
|
||||||
} = func.dfg[inst] {
|
} = func.dfg[inst] {
|
||||||
|
let dest = func.offsets[destination] as i64;
|
||||||
|
let disp = dest - sink.offset() as i64;
|
||||||
let args = &args.as_slice(&func.dfg.value_lists)[0..2];
|
let args = &args.as_slice(&func.dfg.value_lists)[0..2];
|
||||||
sink.reloc_ebb(RelocKind::Branch.into(), destination);
|
|
||||||
put_sb(func.encodings[inst].bits(),
|
put_sb(func.encodings[inst].bits(),
|
||||||
|
disp,
|
||||||
func.locations[args[0]].unwrap_reg(),
|
func.locations[args[0]].unwrap_reg(),
|
||||||
func.locations[args[1]].unwrap_reg(),
|
func.locations[args[1]].unwrap_reg(),
|
||||||
sink);
|
sink);
|
||||||
@@ -257,9 +267,11 @@ fn recipe_sbzero<CS: CodeSink + ?Sized>(func: &Function, inst: Inst, sink: &mut
|
|||||||
ref args,
|
ref args,
|
||||||
..
|
..
|
||||||
} = func.dfg[inst] {
|
} = func.dfg[inst] {
|
||||||
|
let dest = func.offsets[destination] as i64;
|
||||||
|
let disp = dest - sink.offset() as i64;
|
||||||
let args = &args.as_slice(&func.dfg.value_lists)[0..1];
|
let args = &args.as_slice(&func.dfg.value_lists)[0..1];
|
||||||
sink.reloc_ebb(RelocKind::Branch.into(), destination);
|
|
||||||
put_sb(func.encodings[inst].bits(),
|
put_sb(func.encodings[inst].bits(),
|
||||||
|
disp,
|
||||||
func.locations[args[0]].unwrap_reg(),
|
func.locations[args[0]].unwrap_reg(),
|
||||||
0,
|
0,
|
||||||
sink);
|
sink);
|
||||||
|
|||||||
Reference in New Issue
Block a user