1use std::collections::HashMap;23#[derive(Debug, PartialEq, Clone, Copy)]4pub enum BaseType {5 Word,6 Long,7 Single,8 Double,9}1011#[derive(Debug, PartialEq, Clone, Copy)]12pub enum ExtType {13 Base(BaseType),14 Byte,15 Halfword,16}1718#[derive(Debug, PartialEq, Clone, Copy)]19pub enum SubWordType {20 SignedByte,21 UnsignedByte,22 SignedHalf,23 UnsignedHalf,24}2526impl SubWordType {27 pub fn is_signed(&self) -> bool {28 match self {29 SubWordType::SignedByte => true,30 SubWordType::UnsignedByte => false,31 SubWordType::SignedHalf => true,32 SubWordType::UnsignedHalf => false,33 }34 }35}3637#[derive(Debug, PartialEq, Clone, Copy)]38pub enum SubLongType {39 SubWord(SubWordType),40 SignedWord,41 UnsignedWord,42}4344impl SubLongType {45 pub fn is_signed(&self) -> bool {46 match self {47 SubLongType::SubWord(x) => x.is_signed(),48 SubLongType::SignedWord => true,49 SubLongType::UnsignedWord => false,50 }51 }52}5354#[derive(Debug, PartialEq)]55pub enum SubType {56 ExtType(ExtType),57 UserDef(String),58}5960#[derive(Debug, PartialEq)]61pub enum Type {62 Base(BaseType),63 SubWordType(SubWordType),64 UserDef(String),65}6667#[derive(Debug, PartialEq, Clone, Copy)]68pub enum LoadType {69 Base(BaseType),70 SubLong(SubLongType),71}7273impl LoadType {74 pub fn is_signed(&self) -> bool {75 match self {76 LoadType::Base(_) => false,77 LoadType::SubLong(x) => x.is_signed(),78 }79 }80}8182#[derive(Debug, PartialEq)]83pub enum Const {84 Number(i64),85 SFP(f32),86 DFP(f64),87 Global(String),88}8990#[derive(Debug, PartialEq)]91pub enum DynConst {92 Const(Const),93 Thread(String),94}9596#[derive(Debug, PartialEq)]97pub enum Linkage {98 Export,99 Thread,100 Section(String, Option<String>),101}102103#[derive(Debug, PartialEq)]104pub struct TypeDef {105 pub name: String,106 pub defn: AggregateType,107}108109#[derive(Debug, PartialEq)]110pub enum AggregateType {111 Regular(Option<u64>, Vec<(SubType, u64)>),112 Opaque(u64, u64),113}114115#[derive(Debug, PartialEq)]116pub struct DataDef {117 pub linkage: Vec<Linkage>,118 pub name: String,119 pub align: Option<u64>,120 pub objs: Vec<DataObj>,121}122123#[derive(Debug, PartialEq)]124pub enum DataObj {125 DataItem(ExtType, Vec<DataItem>),126 ZeroFill(u64),127}128129#[derive(Debug, PartialEq)]130pub enum DataItem {131 Symbol(String, Option<u64>),132 String(String),133 Const(Const),134}135136#[derive(Debug, PartialEq)]137pub struct FuncDef {138 pub linkage: Vec<Linkage>,139 pub name: String,140 pub abity: Option<Type>,141 pub params: Vec<FuncParam>,142 pub body: Vec<Block>,143}144145#[derive(Debug, PartialEq)]146pub enum FuncParam {147 Regular(Type, String),148 Env(String),149 Variadic,150}151152impl FuncParam {153 pub fn get_name(&self) -> Option<&str> {154 match self {155 FuncParam::Regular(_, n) => Some(n),156 FuncParam::Env(n) => Some(n),157 FuncParam::Variadic => None,158 }159 }160}161162#[derive(Debug, PartialEq)]163pub struct Block {164 pub label: String,165 pub phi: Vec<Phi>,166 pub inst: Vec<Statement>,167 pub jump: Option<JumpInstr>,168}169170#[derive(Debug, PartialEq)]171pub enum Value {172 LocalVar(String),173 Const(DynConst),174}175176#[derive(Debug, PartialEq)]177pub enum JumpInstr {178 Jump(String), // jmp179 Jnz(Value, String, String), // jnz180 Return(Option<Value>), // ret181 Halt, // hlt182}183184#[derive(Debug, PartialEq, Clone, Copy)]185pub enum CmpOp {186 Eq,187 Ne,188 Sle,189 Slt,190 Sge,191 Sgt,192 Ule,193 Ult,194 Uge,195 Ugt,196}197198#[derive(Debug, PartialEq, Copy, Clone)]199pub enum AllocAlign {200 Word, // Align on 4-byte boundary201 Long, // Align on 8-byte boundary202 LongLong, // Align on 16-byte boundary203}204205impl AllocAlign {206 pub fn byte_align(&self) -> u8 {207 match self {208 AllocAlign::Word => 4,209 AllocAlign::Long => 8,210 AllocAlign::LongLong => 16,211 }212 }213}214215#[derive(Debug, PartialEq)]216pub struct Phi {217 pub ident: String,218 pub base_type: BaseType,219 pub labels: HashMap<String, Value>,220}221222#[derive(Debug, PartialEq)]223pub enum Instr {224 // Arithmetic and Bits225 Add(Value, Value),226 Sub(Value, Value),227 Mul(Value, Value),228 Neg(Value),229 UDiv(Value, Value),230 Rem(Value, Value),231 URem(Value, Value),232 Or(Value, Value),233 Xor(Value, Value),234 And(Value, Value),235 Sar(Value, Value),236 Shr(Value, Value),237 Shl(Value, Value),238239 // Memory240 Load(LoadType, Value),241242 // Stack Allocation243 Alloc(AllocAlign, u64),244245 // Comparision246 Compare(BaseType, CmpOp, Value, Value),247248 // Conversions249 Ext(SubLongType, Value),250}251252#[derive(Debug, PartialEq)]253pub enum VolatileInstr {254 Store(ExtType, Value, Value),255 Blit(Value, Value, u64),256}257258#[derive(Debug, PartialEq)]259pub enum Statement {260 Assign(String, BaseType, Instr),261 Call(String, Type, String, Vec<FuncParam>),262 Volatile(VolatileInstr),263}