Add RISC-V encodings for brz and brnz.
These branches compare a register to zero. RISC-V implements this with the %x0 hard-coded zero register.
This commit is contained in:
@@ -91,5 +91,10 @@ ebb0:
|
|||||||
; bgeu
|
; bgeu
|
||||||
br_icmp uge, v1, v2, ebb0 ; bin: Branch(ebb0) 01557063
|
br_icmp uge, v1, v2, ebb0 ; bin: Branch(ebb0) 01557063
|
||||||
|
|
||||||
|
; beq x, %x0
|
||||||
|
brz v1, ebb0 ; bin: Branch(ebb0) 00050063
|
||||||
|
; bne x, %x0
|
||||||
|
brnz v1, ebb0 ; bin: Branch(ebb0) 00051063
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from base import instructions as base
|
|||||||
from base.immediates import intcc
|
from base.immediates import intcc
|
||||||
from .defs import RV32, RV64
|
from .defs import RV32, RV64
|
||||||
from .recipes import OPIMM, OPIMM32, OP, OP32, LUI, BRANCH
|
from .recipes import OPIMM, OPIMM32, OP, OP32, LUI, BRANCH
|
||||||
from .recipes import JALR, R, Rshamt, Ricmp, I, Iicmp, Iret, U, SB
|
from .recipes import JALR, R, Rshamt, Ricmp, I, Iicmp, Iret, U, SB, SBzero
|
||||||
from .settings import use_m
|
from .settings import use_m
|
||||||
from cdsl.ast import Var
|
from cdsl.ast import Var
|
||||||
|
|
||||||
@@ -93,6 +93,15 @@ for cond, f3 in [
|
|||||||
RV32.enc(base.br_icmp.i32(cond, x, y, dest, args), SB, BRANCH(f3))
|
RV32.enc(base.br_icmp.i32(cond, x, y, dest, args), SB, BRANCH(f3))
|
||||||
RV64.enc(base.br_icmp.i64(cond, x, y, dest, args), SB, BRANCH(f3))
|
RV64.enc(base.br_icmp.i64(cond, x, y, dest, args), SB, BRANCH(f3))
|
||||||
|
|
||||||
|
for inst, f3 in [
|
||||||
|
(base.brz, 0b000),
|
||||||
|
(base.brnz, 0b001)
|
||||||
|
]:
|
||||||
|
RV32.enc(inst.i32, SBzero, BRANCH(f3))
|
||||||
|
RV64.enc(inst.i64, SBzero, BRANCH(f3))
|
||||||
|
RV32.enc(inst.b1, SBzero, BRANCH(f3))
|
||||||
|
RV64.enc(inst.b1, SBzero, BRANCH(f3))
|
||||||
|
|
||||||
# Returns are a special case of JALR.
|
# Returns are a special case of JALR.
|
||||||
# Note: Return stack predictors will only recognize this as a return when the
|
# Note: Return stack predictors will only recognize this as a return when the
|
||||||
# return address is provided in `x1`. We may want a special encoding to enforce
|
# return address is provided in `x1`. We may want a special encoding to enforce
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ from __future__ import absolute_import
|
|||||||
from cdsl.isa import EncRecipe
|
from cdsl.isa import EncRecipe
|
||||||
from cdsl.predicates import IsSignedInt
|
from cdsl.predicates import IsSignedInt
|
||||||
from base.formats import Binary, BinaryImm, MultiAry, IntCompare, IntCompareImm
|
from base.formats import Binary, BinaryImm, MultiAry, IntCompare, IntCompareImm
|
||||||
from base.formats import UnaryImm, BranchIcmp
|
from base.formats import UnaryImm, BranchIcmp, Branch
|
||||||
from .registers import GPR
|
from .registers import GPR
|
||||||
|
|
||||||
# The low 7 bits of a RISC-V instruction is the base opcode. All 32-bit
|
# The low 7 bits of a RISC-V instruction is the base opcode. All 32-bit
|
||||||
@@ -116,3 +116,6 @@ U = EncRecipe(
|
|||||||
# TODO: These instructions have a +/- 4 KB branch range. How to encode that
|
# TODO: These instructions have a +/- 4 KB branch range. How to encode that
|
||||||
# constraint?
|
# constraint?
|
||||||
SB = EncRecipe('SB', BranchIcmp, ins=(GPR, GPR), outs=())
|
SB = EncRecipe('SB', BranchIcmp, ins=(GPR, GPR), outs=())
|
||||||
|
|
||||||
|
# SB-type branch instruction with rs2 fixed to zero.
|
||||||
|
SBzero = EncRecipe('SBzero', Branch, ins=(GPR), outs=())
|
||||||
|
|||||||
@@ -246,3 +246,16 @@ fn recipe_sb<CS: CodeSink + ?Sized>(func: &Function, inst: Inst, sink: &mut CS)
|
|||||||
panic!("Expected BranchIcmp format: {:?}", func.dfg[inst]);
|
panic!("Expected BranchIcmp format: {:?}", func.dfg[inst]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn recipe_sbzero<CS: CodeSink + ?Sized>(func: &Function, inst: Inst, sink: &mut CS) {
|
||||||
|
if let InstructionData::Branch { destination, ref args, .. } = func.dfg[inst] {
|
||||||
|
let args = &args.as_slice(&func.dfg.value_lists)[0..1];
|
||||||
|
sink.reloc_ebb(RelocKind::Branch.into(), destination);
|
||||||
|
put_sb(func.encodings[inst].bits(),
|
||||||
|
func.locations[args[0]].unwrap_reg(),
|
||||||
|
0,
|
||||||
|
sink);
|
||||||
|
} else {
|
||||||
|
panic!("Expected Branch format: {:?}", func.dfg[inst]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user