Skip to content

Commit

Permalink
feat(ir): add cast operations
Browse files Browse the repository at this point in the history
  • Loading branch information
JuniMay committed Feb 23, 2024
1 parent 20fcb6f commit 6398a11
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 19 deletions.
7 changes: 3 additions & 4 deletions src/ir/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use super::{
module::{DataFlowGraph, Module},
types::{Type, TypeKind},
values::{
Alloc, Binary, BinaryOp, Block, Branch, Call, Cast, Function, GetElemPtr, GlobalSlot, Jump,
Load, Return, Store, Unary, UnaryOp, Value,
Alloc, Binary, BinaryOp, Block, Branch, Call, Cast, CastOp, Function, GetElemPtr, GlobalSlot, Jump, Load, Return, Store, Unary, UnaryOp, Value
},
};
use thiserror::Error;
Expand Down Expand Up @@ -232,8 +231,8 @@ pub trait LocalValueBuilder: QueryDfgData + AddValue + ConstantBuilder {
}

/// Build a cast instruction
fn cast(&mut self, ty: Type, val: Value) -> Result<Value, BuilderErr> {
self.add_value(Cast::new_value_data(ty, val))
fn cast(&mut self, op: CastOp, ty: Type, val: Value) -> Result<Value, BuilderErr> {
self.add_value(Cast::new_value_data(op, ty, val))
}

/// Build a store instruction.
Expand Down
4 changes: 2 additions & 2 deletions src/ir/frontend.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::values::{BinaryOp, UnaryOp};
use super::values::{BinaryOp, CastOp, UnaryOp};

mod lexer;

Expand Down Expand Up @@ -79,7 +79,7 @@ pub enum InstKind {
Call,

/// `cast`
Cast,
Cast(CastOp),

/// `getelemptr`
GetElemPtr,
Expand Down
11 changes: 8 additions & 3 deletions src/ir/frontend/ast.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::ir::types::Type;
use crate::ir::{types::Type, values::CastOp};

use super::InstKind;

Expand Down Expand Up @@ -283,9 +283,14 @@ impl Inst {
}))
}

pub(super) fn new_boxed_cast(dest: String, ty: Type, val: AstNodeBox) -> AstNodeBox {
pub(super) fn new_boxed_cast(
dest: String,
op: CastOp,
ty: Type,
val: AstNodeBox,
) -> AstNodeBox {
Box::new(AstNode::Inst(Inst {
kind: InstKind::Cast,
kind: InstKind::Cast(op),
dest: Some(dest),
operands: vec![val],
ty: Some(ty),
Expand Down
4 changes: 2 additions & 2 deletions src/ir/frontend/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,12 +221,12 @@ impl Ast {
.builder()
.load(ast_inst.ty.clone().unwrap(), ptr)?
}
InstKind::Cast => {
InstKind::Cast(op) => {
let val = self.operand_to_value(&ast_inst.operands[0], ctx, function)?;

dfg_mut!(ctx.module, function)
.builder()
.cast(ast_inst.ty.clone().unwrap(), val)?
.cast(op.clone(), ast_inst.ty.clone().unwrap(), val)?
}
InstKind::Alloc => dfg_mut!(ctx.module, function)
.builder()
Expand Down
14 changes: 12 additions & 2 deletions src/ir/frontend/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::io;

use crate::ir::{
frontend::tokens::{Span, TokenKind},
values::{BinaryOp, FCmpCond, ICmpCond, UnaryOp},
values::{BinaryOp, CastOp, FCmpCond, ICmpCond, UnaryOp},
GLOBAL_PREFIX_CHAR, LABEL_PREFIX_CHAR, LOCAL_PREFIX_CHAR, TYPE_PREFIX_CHAR,
};

Expand Down Expand Up @@ -265,7 +265,17 @@ where
"ret" => TokenKind::Inst(InstKind::Return),
"call" => TokenKind::Inst(InstKind::Call),
"getelemptr" => TokenKind::Inst(InstKind::GetElemPtr),
"cast" => TokenKind::Inst(InstKind::Cast),

"trunc" => TokenKind::Inst(InstKind::Cast(CastOp::Trunc)),
"zext" => TokenKind::Inst(InstKind::Cast(CastOp::ZExt)),
"sext" => TokenKind::Inst(InstKind::Cast(CastOp::SExt)),
"fptrunc" => TokenKind::Inst(InstKind::Cast(CastOp::FpTrunc)),
"fpext" => TokenKind::Inst(InstKind::Cast(CastOp::FpExt)),
"fptoui" => TokenKind::Inst(InstKind::Cast(CastOp::FpToUI)),
"fptosi" => TokenKind::Inst(InstKind::Cast(CastOp::FpToSI)),
"uitofp" => TokenKind::Inst(InstKind::Cast(CastOp::UIToFp)),
"sitofp" => TokenKind::Inst(InstKind::Cast(CastOp::SIToFp)),
"bitcast" => TokenKind::Inst(InstKind::Cast(CastOp::Bitcast)),

_ => {
if word.starts_with('i') {
Expand Down
5 changes: 3 additions & 2 deletions src/ir/frontend/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,11 +424,12 @@ where
let ptr = self.parse_operand()?;
Inst::new_boxed_load(dest, ty, ptr)
}
InstKind::Cast => {
InstKind::Cast(op) => {
let op = op.clone();
let ty = self.parse_type()?;
self.expect(TokenKind::Comma)?;
let val = self.parse_operand()?;
Inst::new_boxed_cast(dest, ty, val)
Inst::new_boxed_cast(dest, op, ty, val)
}
InstKind::Alloc => {
let ty = self.parse_type()?;
Expand Down
59 changes: 57 additions & 2 deletions src/ir/values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,21 +359,76 @@ impl Load {
}
}

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum CastOp {
/// Truncate
Trunc,

/// Zero extend
ZExt,

/// Sign extend
SExt,

/// Float to unsigned int
FpToUI,

/// Float to signed int
FpToSI,

/// Unsigned int to float
UIToFp,

/// Signed int to float
SIToFp,

/// Float truncation
FpTrunc,

/// Float extension
FpExt,

/// Bitcast
Bitcast,
}

impl fmt::Display for CastOp {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
CastOp::Trunc => write!(f, "trunc"),
CastOp::ZExt => write!(f, "zext"),
CastOp::SExt => write!(f, "sext"),
CastOp::FpToUI => write!(f, "fptoui"),
CastOp::FpToSI => write!(f, "fptosi"),
CastOp::UIToFp => write!(f, "uitofp"),
CastOp::SIToFp => write!(f, "sitofp"),
CastOp::FpTrunc => write!(f, "fptrunc"),
CastOp::FpExt => write!(f, "fpext"),
CastOp::Bitcast => write!(f, "bitcast"),
}
}
}

/// Type cast
///
/// Perform bitcast operation, the type is available in [`ValueData`].
pub struct Cast {
op: CastOp,
val: Value,
}

impl Cast {
pub(super) fn new_value_data(ty: Type, val: Value) -> ValueData {
ValueData::new(ty, ValueKind::Cast(Cast { val }))
pub(super) fn new_value_data(op: CastOp, ty: Type, val: Value) -> ValueData {
ValueData::new(ty, ValueKind::Cast(Cast { op, val }))
}

pub fn val(&self) -> Value {
self.val
}

pub fn op(&self) -> CastOp {
self.op.clone()
}
}

/// Allocation instruction internals.
Expand Down
2 changes: 1 addition & 1 deletion src/passes/printer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ where
self.print_operand(load.ptr(), dfg)
}
ValueKind::Cast(cast) => {
write!(self.buf, "{} = cast {}, ", dfg.value_name(value), data.ty())?;
write!(self.buf, "{} = {} {}, ", dfg.value_name(value), cast.op(), data.ty())?;
self.print_operand(cast.val(), dfg)
}
ValueKind::Store(store) => {
Expand Down
2 changes: 1 addition & 1 deletion tests/ir_cases/06_cast.orzir
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
func @check(i32) -> i32 {
^entry(i32 %0):
%cond = cast i1, i32 %0
%cond = bitcast i1, i32 %0
br i1 %cond, ^true, ^false

^true:
Expand Down

0 comments on commit 6398a11

Please sign in to comment.