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:
@@ -14,7 +14,6 @@ ebb0:
|
|||||||
; sub
|
; sub
|
||||||
[-,%x7] v12 = isub v1, v2 ; bin: 415503b3
|
[-,%x7] v12 = isub v1, v2 ; bin: 415503b3
|
||||||
[-,%x16] v13 = isub v2, v1 ; bin: 40aa8833
|
[-,%x16] v13 = isub v2, v1 ; bin: 40aa8833
|
||||||
; TBD: slt/sltu
|
|
||||||
; and
|
; and
|
||||||
[-,%x7] v20 = band v1, v2 ; bin: 015573b3
|
[-,%x7] v20 = band v1, v2 ; bin: 015573b3
|
||||||
[-,%x16] v21 = band v2, v1 ; bin: 00aaf833
|
[-,%x16] v21 = band v2, v1 ; bin: 00aaf833
|
||||||
@@ -33,5 +32,12 @@ ebb0:
|
|||||||
; sra
|
; sra
|
||||||
[-,%x7] v34 = sshr v1, v2 ; bin: 415553b3
|
[-,%x7] v34 = sshr v1, v2 ; bin: 415553b3
|
||||||
[-,%x16] v35 = sshr v2, v1 ; bin: 40aad833
|
[-,%x16] v35 = sshr v2, v1 ; bin: 40aad833
|
||||||
|
; slt
|
||||||
|
[-,%x7] v42 = icmp slt, v1, v2 ; bin: 015523b3
|
||||||
|
[-,%x16] v43 = icmp slt, v2, v1 ; bin: 00aaa833
|
||||||
|
; sltu
|
||||||
|
[-,%x7] v44 = icmp ult, v1, v2 ; bin: 015533b3
|
||||||
|
[-,%x16] v45 = icmp ult, v2, v1 ; bin: 00aab833
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,15 @@ RISC-V Encodings.
|
|||||||
"""
|
"""
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from base import instructions as base
|
from base import instructions as base
|
||||||
|
from base.immediates import intcc
|
||||||
from .defs import RV32, RV64
|
from .defs import RV32, RV64
|
||||||
from .recipes import OPIMM, OPIMM32, OP, OP32, JALR, R, Rshamt, I, Iret
|
from .recipes import OPIMM, OPIMM32, OP, OP32, JALR, R, Rshamt, Ricmp, I, Iret
|
||||||
from .settings import use_m
|
from .settings import use_m
|
||||||
|
from cdsl.ast import Var
|
||||||
|
|
||||||
|
# Dummies for instruction predicates.
|
||||||
|
x = Var('x')
|
||||||
|
y = Var('y')
|
||||||
|
|
||||||
# Basic arithmetic binary instructions are encoded in an R-type instruction.
|
# Basic arithmetic binary instructions are encoded in an R-type instruction.
|
||||||
for inst, inst_imm, f3, f7 in [
|
for inst, inst_imm, f3, f7 in [
|
||||||
@@ -47,6 +53,13 @@ for inst, inst_imm, f3, f7 in [
|
|||||||
RV64.enc(inst_imm.i64, Rshamt, OPIMM(f3, f7))
|
RV64.enc(inst_imm.i64, Rshamt, OPIMM(f3, f7))
|
||||||
RV64.enc(inst_imm.i32, Rshamt, OPIMM32(f3, f7))
|
RV64.enc(inst_imm.i32, Rshamt, OPIMM32(f3, f7))
|
||||||
|
|
||||||
|
# Signed and unsigned integer 'less than'. There are no 'w' variants for
|
||||||
|
# comparing 32-bit numbers in RV64.
|
||||||
|
RV32.enc(base.icmp.i32(intcc.slt, x, y), Ricmp, OP(0b010, 0b0000000))
|
||||||
|
RV64.enc(base.icmp.i64(intcc.slt, x, y), Ricmp, OP(0b010, 0b0000000))
|
||||||
|
RV32.enc(base.icmp.i32(intcc.ult, x, y), Ricmp, OP(0b011, 0b0000000))
|
||||||
|
RV64.enc(base.icmp.i64(intcc.ult, x, y), Ricmp, OP(0b011, 0b0000000))
|
||||||
|
|
||||||
# "M" Standard Extension for Integer Multiplication and Division.
|
# "M" Standard Extension for Integer Multiplication and Division.
|
||||||
# Gated by the `use_m` flag.
|
# Gated by the `use_m` flag.
|
||||||
RV32.enc(base.imul.i32, R, OP(0b000, 0b0000001), isap=use_m)
|
RV32.enc(base.imul.i32, R, OP(0b000, 0b0000001), isap=use_m)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ instruction formats described in the reference:
|
|||||||
from __future__ import absolute_import
|
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
|
from base.formats import Binary, BinaryImm, MultiAry, IntCompare
|
||||||
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
|
||||||
@@ -79,6 +79,9 @@ R = EncRecipe('R', Binary, ins=(GPR, GPR), outs=GPR)
|
|||||||
# R-type with an immediate shift amount instead of rs2.
|
# R-type with an immediate shift amount instead of rs2.
|
||||||
Rshamt = EncRecipe('Rshamt', BinaryImm, ins=GPR, outs=GPR)
|
Rshamt = EncRecipe('Rshamt', BinaryImm, ins=GPR, outs=GPR)
|
||||||
|
|
||||||
|
# R-type encoding of an integer comparison.
|
||||||
|
Ricmp = EncRecipe('Ricmp', IntCompare, ins=(GPR, GPR), outs=GPR)
|
||||||
|
|
||||||
I = EncRecipe(
|
I = EncRecipe(
|
||||||
'I', BinaryImm, ins=GPR, outs=GPR,
|
'I', BinaryImm, ins=GPR, outs=GPR,
|
||||||
instp=IsSignedInt(BinaryImm.imm, 12))
|
instp=IsSignedInt(BinaryImm.imm, 12))
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
use binemit::{CodeSink, bad_encoding};
|
use binemit::{CodeSink, bad_encoding};
|
||||||
use ir::{Function, Inst, InstructionData};
|
use ir::{Function, Inst, InstructionData};
|
||||||
|
use isa::RegUnit;
|
||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/binemit-riscv.rs"));
|
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
|
/// 25 20 15 12 7 0
|
||||||
///
|
///
|
||||||
/// Encoding bits: `opcode[6:2] | (funct3 << 5) | (funct7 << 8)`.
|
/// Encoding bits: `opcode[6:2] | (funct3 << 5) | (funct7 << 8)`.
|
||||||
fn recipe_r<CS: CodeSink + ?Sized>(func: &Function, inst: Inst, sink: &mut CS) {
|
fn put_r<CS: CodeSink + ?Sized>(bits: u16,
|
||||||
if let InstructionData::Binary { args, .. } = func.dfg[inst] {
|
rs1: RegUnit,
|
||||||
let bits = func.encodings[inst].bits();
|
rs2: RegUnit,
|
||||||
let rs1 = func.locations[args[0]].unwrap_reg();
|
rd: RegUnit,
|
||||||
let rs2 = func.locations[args[1]].unwrap_reg();
|
sink: &mut CS) {
|
||||||
let rd = func.locations[func.dfg.first_result(inst)].unwrap_reg();
|
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
|
// 0-6: opcode
|
||||||
let mut i = 0x3;
|
let mut i = 0x3;
|
||||||
i |= (bits as u32 & 0x1f) << 2;
|
i |= opcode5 << 2;
|
||||||
// 7-11: rd
|
i |= rd << 7;
|
||||||
i |= (rd as u32 & 0x1f) << 7;
|
i |= funct3 << 12;
|
||||||
// 12-14: funct3
|
i |= rs1 << 15;
|
||||||
i |= ((bits as u32 >> 5) & 0x7) << 12;
|
i |= rs2 << 20;
|
||||||
// 15-19: rs1
|
i |= funct7 << 25;
|
||||||
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);
|
sink.put4(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recipe_r<CS: CodeSink + ?Sized>(func: &Function, inst: Inst, sink: &mut CS) {
|
||||||
|
if let InstructionData::Binary { 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 {
|
} else {
|
||||||
panic!("Expected Binary format: {:?}", func.dfg[inst]);
|
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) {
|
fn recipe_rshamt<CS: CodeSink + ?Sized>(_func: &Function, _inst: Inst, _sink: &mut CS) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
//! Encoding tables for RISC-V.
|
//! Encoding tables for RISC-V.
|
||||||
|
|
||||||
|
use ir::condcodes::IntCC;
|
||||||
use ir::{Opcode, InstructionData};
|
use ir::{Opcode, InstructionData};
|
||||||
use ir::types;
|
use ir::types;
|
||||||
use predicates;
|
use predicates;
|
||||||
|
|||||||
Reference in New Issue
Block a user