#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AsmType {
Byte,
Word,
Longword,
Quadword,
Double,
Float,
}
#[derive(Debug, Clone, PartialEq)]
#[allow(clippy::enum_variant_names)]
pub enum StaticInit {
IntInit(i64),
FloatInit(f32),
DoubleInit(f64),
ZeroInit(usize),
StringInit(String, usize),
ByteArrayInit(Vec<u8>),
PointerArrayInit(Vec<String>),
ArrayInit(Vec<StaticInit>),
}
#[derive(Debug, Clone, PartialEq)]
pub struct AsmStaticConstant {
pub name: String,
pub alignment: usize,
pub init: StaticInit,
}
#[derive(Debug, Clone, PartialEq)]
pub struct AsmProgram {
pub functions: Vec<AsmFunction>,
pub static_vars: Vec<AsmStaticVar>,
pub static_constants: Vec<AsmStaticConstant>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct AsmFunction {
pub name: String,
pub instructions: Vec<Instruction>,
pub global: bool,
}
#[derive(Debug, Clone, PartialEq)]
pub struct AsmStaticVar {
pub name: String,
pub global: bool,
pub init: StaticInit,
pub asm_type: AsmType,
pub var_type: Option<crate::parse::ast::Type>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Instruction {
Mov {
asm_type: AsmType,
src: Operand,
dst: Operand,
},
Unary {
asm_type: AsmType,
op: AsmUnaryOp,
operand: Operand,
},
Cmp {
asm_type: AsmType,
src: Operand,
dst: Operand,
},
SetCC {
condition: CondCode,
operand: Operand,
},
Binary {
asm_type: AsmType,
op: AsmBinaryOp,
src: Operand,
dst: Operand,
},
Idiv { asm_type: AsmType, operand: Operand },
Div { asm_type: AsmType, operand: Operand },
SignExtend(AsmType),
Movsx { src: Operand, dst: Operand },
MovsxByte {
asm_type: AsmType,
src: Operand,
dst: Operand,
},
MovsxWord {
asm_type: AsmType,
src: Operand,
dst: Operand,
},
MovZeroExtend { src: Operand, dst: Operand },
MovZeroExtendByte {
asm_type: AsmType,
src: Operand,
dst: Operand,
},
MovZeroExtendWord {
asm_type: AsmType,
src: Operand,
dst: Operand,
},
Truncate { src: Operand, dst: Operand },
Push(Operand),
Pop(Operand),
Jmp(String),
JmpCC(CondCode, String),
Label(String),
AllocateStack(usize),
DeallocateStack(usize),
Call(String),
Ret,
Cvtsi2sd {
asm_type: AsmType,
src: Operand,
dst: Operand,
},
Cvttsd2si {
asm_type: AsmType,
src: Operand,
dst: Operand,
},
Cvtsi2ss {
asm_type: AsmType,
src: Operand,
dst: Operand,
},
Cvttss2si {
asm_type: AsmType,
src: Operand,
dst: Operand,
},
Cvtss2sd { src: Operand, dst: Operand },
Cvtsd2ss { src: Operand, dst: Operand },
Lea { src: Operand, dst: Operand },
JmpIndirect(Operand, Vec<String>),
CallIndirect(Operand),
RawBytes(Vec<u8>),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AsmUnaryOp {
Neg,
Not,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AsmBinaryOp {
Add,
Sub,
Mult,
DivDouble,
Xor,
And,
Or,
BitXor,
Sal,
Sar,
Shr,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CondCode {
E,
NE,
L,
LE,
G,
GE,
A,
AE,
B,
BE,
P,
NP,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Operand {
Imm(i64),
Register(Reg),
Pseudo(String),
Stack(i32),
Data(String),
Memory(Reg),
MemoryOffset(Reg, i32),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum Reg {
AX,
BX,
CX,
DX,
DI,
SI,
R8,
R9,
R10,
R11,
R12,
R13,
R14,
R15,
SP,
BP,
XMM0,
XMM1,
XMM2,
XMM3,
XMM4,
XMM5,
XMM6,
XMM7,
XMM8,
XMM9,
XMM10,
XMM11,
XMM12,
XMM13,
XMM14,
XMM15,
}
pub const GP_ALLOCATABLE: [Reg; 12] = [
Reg::AX,
Reg::BX,
Reg::CX,
Reg::DX,
Reg::SI,
Reg::DI,
Reg::R8,
Reg::R9,
Reg::R12,
Reg::R13,
Reg::R14,
Reg::R15,
];
pub const GP_CALLEE_SAVED: [Reg; 5] = [Reg::BX, Reg::R12, Reg::R13, Reg::R14, Reg::R15];
pub const GP_CALLER_SAVED: [Reg; 9] = [
Reg::AX,
Reg::CX,
Reg::DX,
Reg::SI,
Reg::DI,
Reg::R8,
Reg::R9,
Reg::R10,
Reg::R11,
];
pub const XMM_ALLOCATABLE: [Reg; 15] = [
Reg::XMM0,
Reg::XMM1,
Reg::XMM2,
Reg::XMM3,
Reg::XMM4,
Reg::XMM5,
Reg::XMM6,
Reg::XMM7,
Reg::XMM8,
Reg::XMM9,
Reg::XMM10,
Reg::XMM11,
Reg::XMM12,
Reg::XMM13,
Reg::XMM14,
];
pub const XMM_ALL: [Reg; 16] = [
Reg::XMM0,
Reg::XMM1,
Reg::XMM2,
Reg::XMM3,
Reg::XMM4,
Reg::XMM5,
Reg::XMM6,
Reg::XMM7,
Reg::XMM8,
Reg::XMM9,
Reg::XMM10,
Reg::XMM11,
Reg::XMM12,
Reg::XMM13,
Reg::XMM14,
Reg::XMM15,
];