Add RISC-V encodings for supported icmp variants.
Only slt and ult variants are in the instruction set. Other condition codes must be synthesized.
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
use binemit::{CodeSink, bad_encoding};
|
||||
use ir::{Function, Inst, InstructionData};
|
||||
use isa::RegUnit;
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/binemit-riscv.rs"));
|
||||
|
||||
@@ -12,33 +13,55 @@ include!(concat!(env!("OUT_DIR"), "/binemit-riscv.rs"));
|
||||
/// 25 20 15 12 7 0
|
||||
///
|
||||
/// Encoding bits: `opcode[6:2] | (funct3 << 5) | (funct7 << 8)`.
|
||||
fn put_r<CS: CodeSink + ?Sized>(bits: u16,
|
||||
rs1: RegUnit,
|
||||
rs2: RegUnit,
|
||||
rd: RegUnit,
|
||||
sink: &mut CS) {
|
||||
let bits = bits as u32;
|
||||
let opcode5 = bits & 0x1f;
|
||||
let funct3 = (bits >> 5) & 0x7;
|
||||
let funct7 = (bits >> 8) & 0x7f;
|
||||
let rs1 = rs1 as u32 & 0x1f;
|
||||
let rs2 = rs2 as u32 & 0x1f;
|
||||
let rd = rd as u32 & 0x1f;
|
||||
|
||||
// 0-6: opcode
|
||||
let mut i = 0x3;
|
||||
i |= opcode5 << 2;
|
||||
i |= rd << 7;
|
||||
i |= funct3 << 12;
|
||||
i |= rs1 << 15;
|
||||
i |= rs2 << 20;
|
||||
i |= funct7 << 25;
|
||||
|
||||
sink.put4(i);
|
||||
}
|
||||
|
||||
fn recipe_r<CS: CodeSink + ?Sized>(func: &Function, inst: Inst, sink: &mut CS) {
|
||||
if let InstructionData::Binary { args, .. } = func.dfg[inst] {
|
||||
let bits = func.encodings[inst].bits();
|
||||
let rs1 = func.locations[args[0]].unwrap_reg();
|
||||
let rs2 = func.locations[args[1]].unwrap_reg();
|
||||
let rd = func.locations[func.dfg.first_result(inst)].unwrap_reg();
|
||||
|
||||
// 0-6: opcode
|
||||
let mut i = 0x3;
|
||||
i |= (bits as u32 & 0x1f) << 2;
|
||||
// 7-11: rd
|
||||
i |= (rd as u32 & 0x1f) << 7;
|
||||
// 12-14: funct3
|
||||
i |= ((bits as u32 >> 5) & 0x7) << 12;
|
||||
// 15-19: rs1
|
||||
i |= (rs1 as u32 & 0x1f) << 15;
|
||||
// 20-24: rs1
|
||||
i |= (rs2 as u32 & 0x1f) << 20;
|
||||
// 25-31: funct7
|
||||
i |= ((bits as u32 >> 8) & 0x7f) << 25;
|
||||
|
||||
sink.put4(i);
|
||||
put_r(func.encodings[inst].bits(),
|
||||
func.locations[args[0]].unwrap_reg(),
|
||||
func.locations[args[1]].unwrap_reg(),
|
||||
func.locations[func.dfg.first_result(inst)].unwrap_reg(),
|
||||
sink);
|
||||
} else {
|
||||
panic!("Expected Binary format: {:?}", func.dfg[inst]);
|
||||
}
|
||||
}
|
||||
|
||||
fn recipe_ricmp<CS: CodeSink + ?Sized>(func: &Function, inst: Inst, sink: &mut CS) {
|
||||
if let InstructionData::IntCompare { args, .. } = func.dfg[inst] {
|
||||
put_r(func.encodings[inst].bits(),
|
||||
func.locations[args[0]].unwrap_reg(),
|
||||
func.locations[args[1]].unwrap_reg(),
|
||||
func.locations[func.dfg.first_result(inst)].unwrap_reg(),
|
||||
sink);
|
||||
} else {
|
||||
panic!("Expected IntCompare format: {:?}", func.dfg[inst]);
|
||||
}
|
||||
}
|
||||
|
||||
fn recipe_rshamt<CS: CodeSink + ?Sized>(_func: &Function, _inst: Inst, _sink: &mut CS) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
//! Encoding tables for RISC-V.
|
||||
|
||||
use ir::condcodes::IntCC;
|
||||
use ir::{Opcode, InstructionData};
|
||||
use ir::types;
|
||||
use predicates;
|
||||
|
||||
Reference in New Issue
Block a user