1use common::Context;
2use ty;
3use std::fmt::{self, Debug, Display, Formatter};
4use std::hash::{Hash, Hasher};
5use std::cell::{Cell, RefCell};
6
7pub type FuncContext<'c> = Context<Function<'c>>;
8
9pub struct Function<'c> {
10 pub name: String,
11 pub ty: ty::Function<'c>,
12 pub blocks: BlockContext<'c>,
13 pub values: ValueContext<'c>,
14}
15
16impl<'c> Function<'c> {
17 pub fn add_block(&'c self) -> &'c Block<'c> {
18 self.blocks.push(
19 Block {
20 number: self.blocks.len() as u32,
21 terminator: Cell::new(Terminator::None),
22 block_values: RefCell::new(vec![]),
23 func: self,
24 })
25 }
26
27 #[inline(always)]
28 pub fn ty(&self) -> &ty::Function<'c> {
29 &self.ty
30 }
31}
32
33impl<'c> Display for Function<'c> {
34 fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
35 try!(writeln!(f, "define {}{} {{", self.name, self.ty));
36 for blk in &self.blocks {
37 try!(write!(f, "{:?}", blk));
38 }
39 write!(f, "}}")
40 }
41}
42
43impl<'c> PartialEq for Function<'c> {
44 fn eq(&self, rhs: &Self) -> bool {
45 self.name == rhs.name
46 }
47}
48impl<'c> Eq for Function<'c> { }
49impl<'c> Hash for Function<'c> {
50 fn hash<H>(&self, state: &mut H) where H: Hasher {
51 self.name.hash(state)
52 }
53}
54
55pub type BlockContext<'c> = Context<Block<'c>>;
56
57#[derive(Copy, Clone)]
58pub enum Terminator<'c> {
59 Branch(&'c Block<'c>),
60 Return(&'c Value<'c>),
62 None,
63}
64
65impl<'c> Terminator<'c> {
66 pub fn is_none(self) -> bool {
67 if let Terminator::None = self {
68 true
69 } else {
70 false
71 }
72 }
73}
74
75impl<'c> Display for Terminator<'c> {
76 fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
77 match *self {
78 Terminator::Branch(b) => {
79 write!(f, "branch {}", b)
80 },
81 Terminator::Return(r) => {
82 write!(f, "return {}", r)
83 }
84 Terminator::None => { Ok(()) }
85 }
86 }
87}
88
89pub struct Block<'c> {
93 pub number: u32,
94 pub terminator: Cell<Terminator<'c>>,
95 pub block_values: RefCell<Vec<&'c Value<'c>>>,
96 pub func: &'c Function<'c>,
97}
98
99impl<'c> Block<'c> {
100 pub fn add_value(&'c self, kind: ValueKind<'c>) -> &'c Value<'c> {
101 let ret = self.func.values.push(
102 Value {
103 number: self.func.values.len() as u32,
104 kind: kind,
105 func: &self.func,
106 });
107 self.block_values.borrow_mut().push(ret);
108 ret
109 }
110}
111
112impl<'c> Debug for Block<'c> {
113 fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
114 try!(writeln!(f, "{}:", self));
115 for value in &*self.block_values.borrow() {
116 try!(writeln!(f, " {}: {} = {:?}", value, value.ty(), value));
117 }
118 try!(writeln!(f, " {}", self.terminator.get()));
119 Ok(())
120 }
121}
122
123impl<'c> Display for Block<'c> {
124 fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
125 write!(f, "bb{}", self.number)
126 }
127}
128
129pub type ValueContext<'c> = Context<Value<'c>>;
130
131pub struct Value<'c> {
132 pub number: u32,
133 pub kind: ValueKind<'c>,
134 pub func: &'c Function<'c>,
135}
136impl<'c> Value<'c> {
137 pub fn ty(&self) -> &'c ty::Type {
138 match self.kind {
139 ValueKind::ConstInt {
140 ty,
141 ..
142 } => ty,
143 ValueKind::Call {
144 function,
145 ..
146 } => function.ty.output,
147 ValueKind::Mul(lhs, _) => lhs.ty(),
148 ValueKind::UDiv(lhs, _) => lhs.ty(),
149 ValueKind::SDiv(lhs, _) => lhs.ty(),
150 ValueKind::URem(lhs, _) => lhs.ty(),
151 ValueKind::SRem(lhs, _) => lhs.ty(),
152
153 ValueKind::Add(lhs, _) => lhs.ty(),
154 ValueKind::Sub(lhs, _) => lhs.ty(),
155
156 ValueKind::Shl(lhs, _) => lhs.ty(),
157 ValueKind::ZShr(lhs, _) => lhs.ty(),
158 ValueKind::SShr(lhs, _) => lhs.ty(),
159
160 ValueKind::And(lhs, _) => lhs.ty(),
161 ValueKind::Xor(lhs, _) => lhs.ty(),
162 ValueKind::Or(lhs, _) => lhs.ty(),
163
164 ValueKind::Eq(_, _) => unimplemented!(),
165 ValueKind::Neq(_, _) => unimplemented!(),
166 ValueKind::Lt(_, _) => unimplemented!(),
167 ValueKind::Gt(_, _) => unimplemented!(),
168 ValueKind::Lte(_, _) => unimplemented!(),
169 ValueKind::Gte(_, _) => unimplemented!(),
170 ValueKind::Parameter(ty) => ty,
171 }
172 }
173
174}
175
176pub enum ValueKind<'c> {
177 ConstInt {
178 ty: &'c ty::Type,
179 value: u64,
180 },
181 Call {
182 function: &'c Function<'c>,
183 parameters: Box<[&'c Value<'c>]>
184 },
185
186 Mul(&'c Value<'c>, &'c Value<'c>),
188 UDiv(&'c Value<'c>, &'c Value<'c>),
189 SDiv(&'c Value<'c>, &'c Value<'c>),
190 URem(&'c Value<'c>, &'c Value<'c>),
191 SRem(&'c Value<'c>, &'c Value<'c>),
192
193 Add(&'c Value<'c>, &'c Value<'c>),
194 Sub(&'c Value<'c>, &'c Value<'c>),
195
196 Shl(&'c Value<'c>, &'c Value<'c>),
197 ZShr(&'c Value<'c>, &'c Value<'c>), SShr(&'c Value<'c>, &'c Value<'c>), And(&'c Value<'c>, &'c Value<'c>),
201 Xor(&'c Value<'c>, &'c Value<'c>),
202 Or(&'c Value<'c>, &'c Value<'c>),
203
204 Eq(&'c Value<'c>, &'c Value<'c>),
205 Neq(&'c Value<'c>, &'c Value<'c>),
206 Lt(&'c Value<'c>, &'c Value<'c>),
207 Gt(&'c Value<'c>, &'c Value<'c>),
208 Lte(&'c Value<'c>, &'c Value<'c>),
209 Gte(&'c Value<'c>, &'c Value<'c>),
210
211 Parameter(&'c ty::Type),
213}
214
215impl<'c> Debug for Value<'c> {
216 fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
217 match self.kind {
218 ValueKind::ConstInt {
219 value,
220 ..
221 } => {
222 try!(write!(f, "{}", value));
223 }
224 ValueKind::Call {
225 function,
226 ref parameters
227 } => {
228 try!(write!(f, "call {}(", function.name));
229 if !parameters.is_empty() {
230 for i in 0..parameters.len() - 1 {
231 try!(write!(f, "%{}, ", i));
232 }
233 try!(write!(f, "%{}", parameters.len() - 1));
234 }
235 try!(write!(f, ")"));
236 }
237 ValueKind::Mul(lhs, rhs) => try!(write!(f, "mul {} {}", lhs, rhs)),
238 ValueKind::UDiv(lhs, rhs) => try!(write!(f, "udiv {} {}", lhs, rhs)),
239 ValueKind::SDiv(lhs, rhs) => try!(write!(f, "sdiv {} {}", lhs, rhs)),
240 ValueKind::URem(lhs, rhs) => try!(write!(f, "urem {} {}", lhs, rhs)),
241 ValueKind::SRem(lhs, rhs) => try!(write!(f, "srem {} {}", lhs, rhs)),
242
243 ValueKind::Add(lhs, rhs) => try!(write!(f, "add {} {}", lhs, rhs)),
244 ValueKind::Sub(lhs, rhs) => try!(write!(f, "sub {} {}", lhs, rhs)),
245
246 ValueKind::Shl(lhs, rhs) => try!(write!(f, "shl {} {}", lhs, rhs)),
247 ValueKind::ZShr(lhs, rhs) => try!(write!(f, "zshr {} {}", lhs, rhs)), ValueKind::SShr(lhs, rhs) => try!(write!(f, "sshr {} {}", lhs, rhs)), ValueKind::And(lhs, rhs) => try!(write!(f, "and {} {}", lhs, rhs)),
251 ValueKind::Xor(lhs, rhs) => try!(write!(f, "xor {} {}", lhs, rhs)),
252 ValueKind::Or(lhs, rhs) => try!(write!(f, "or {} {}", lhs, rhs)),
253
254 ValueKind::Eq(lhs, rhs) => try!(write!(f, "eq {} {}", lhs, rhs)),
255 ValueKind::Neq(lhs, rhs) => try!(write!(f, "neq {} {}", lhs, rhs)),
256 ValueKind::Lt(lhs, rhs) => try!(write!(f, "lt {} {}", lhs, rhs)),
257 ValueKind::Gt(lhs, rhs) => try!(write!(f, "gt {} {}", lhs, rhs)),
258 ValueKind::Lte(lhs, rhs) => try!(write!(f, "lte {} {}", lhs, rhs)),
259 ValueKind::Gte(lhs, rhs) => try!(write!(f, "gte {} {}", lhs, rhs)),
260
261 ValueKind::Parameter(_) => panic!("pcb_ice: Parameters should not be \
262 displayed"),
263 }
264 Ok(())
265 }
266}
267
268impl<'c> Display for Value<'c> {
269 fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
270 write!(f, "%{}", self.number)
271 }
272}