mirror of
https://github.com/vosen/ZLUDA.git
synced 2025-04-20 00:14:45 +00:00
Simply id type handling
This commit is contained in:
parent
47b06ebcb6
commit
4a0e91949c
3 changed files with 148 additions and 217 deletions
102
ptx/src/ast.rs
102
ptx/src/ast.rs
|
@ -55,7 +55,7 @@ pub struct Function<'a> {
|
|||
pub kernel: bool,
|
||||
pub name: &'a str,
|
||||
pub args: Vec<Argument<'a>>,
|
||||
pub body: Vec<Statement<'a>>,
|
||||
pub body: Vec<Statement<&'a str>>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -102,16 +102,16 @@ impl Default for ScalarType {
|
|||
}
|
||||
}
|
||||
|
||||
pub enum Statement<'a> {
|
||||
Label(&'a str),
|
||||
Variable(Variable<'a>),
|
||||
Instruction(Option<PredAt<'a>>, Instruction<'a>),
|
||||
pub enum Statement<ID> {
|
||||
Label(ID),
|
||||
Variable(Variable<ID>),
|
||||
Instruction(Option<PredAt<ID>>, Instruction<ID>),
|
||||
}
|
||||
|
||||
pub struct Variable<'a> {
|
||||
pub struct Variable<ID> {
|
||||
pub space: StateSpace,
|
||||
pub v_type: Type,
|
||||
pub name: &'a str,
|
||||
pub name: ID,
|
||||
pub count: Option<u32>,
|
||||
}
|
||||
|
||||
|
@ -124,71 +124,71 @@ pub enum StateSpace {
|
|||
Shared,
|
||||
}
|
||||
|
||||
pub struct PredAt<'a> {
|
||||
pub struct PredAt<ID> {
|
||||
pub not: bool,
|
||||
pub label: &'a str,
|
||||
pub label: ID,
|
||||
}
|
||||
|
||||
pub enum Instruction<'a> {
|
||||
Ld(LdData, Arg2<'a>),
|
||||
Mov(MovData, Arg2Mov<'a>),
|
||||
Mul(MulData, Arg3<'a>),
|
||||
Add(AddData, Arg3<'a>),
|
||||
Setp(SetpData, Arg4<'a>),
|
||||
SetpBool(SetpBoolData, Arg5<'a>),
|
||||
Not(NotData, Arg2<'a>),
|
||||
Bra(BraData, Arg1<'a>),
|
||||
Cvt(CvtData, Arg2<'a>),
|
||||
Shl(ShlData, Arg3<'a>),
|
||||
St(StData, Arg2<'a>),
|
||||
At(AtData, Arg1<'a>),
|
||||
pub enum Instruction<ID> {
|
||||
Ld(LdData, Arg2<ID>),
|
||||
Mov(MovData, Arg2Mov<ID>),
|
||||
Mul(MulData, Arg3<ID>),
|
||||
Add(AddData, Arg3<ID>),
|
||||
Setp(SetpData, Arg4<ID>),
|
||||
SetpBool(SetpBoolData, Arg5<ID>),
|
||||
Not(NotData, Arg2<ID>),
|
||||
Bra(BraData, Arg1<ID>),
|
||||
Cvt(CvtData, Arg2<ID>),
|
||||
Shl(ShlData, Arg3<ID>),
|
||||
St(StData, Arg2<ID>),
|
||||
At(AtData, Arg1<ID>),
|
||||
Ret(RetData),
|
||||
}
|
||||
|
||||
pub struct Arg1<'a> {
|
||||
pub dst: &'a str,
|
||||
pub struct Arg1<ID> {
|
||||
pub dst: ID,
|
||||
}
|
||||
|
||||
pub struct Arg2<'a> {
|
||||
pub dst: &'a str,
|
||||
pub src: Operand<'a>,
|
||||
pub struct Arg2<ID> {
|
||||
pub dst: ID,
|
||||
pub src: Operand<ID>,
|
||||
}
|
||||
|
||||
pub struct Arg2Mov<'a> {
|
||||
pub dst: &'a str,
|
||||
pub src: MovOperand<'a>,
|
||||
pub struct Arg2Mov<ID> {
|
||||
pub dst: ID,
|
||||
pub src: MovOperand<ID>,
|
||||
}
|
||||
|
||||
pub struct Arg3<'a> {
|
||||
pub dst: &'a str,
|
||||
pub src1: Operand<'a>,
|
||||
pub src2: Operand<'a>,
|
||||
pub struct Arg3<ID> {
|
||||
pub dst: ID,
|
||||
pub src1: Operand<ID>,
|
||||
pub src2: Operand<ID>,
|
||||
}
|
||||
|
||||
pub struct Arg4<'a> {
|
||||
pub dst1: &'a str,
|
||||
pub dst2: Option<&'a str>,
|
||||
pub src1: Operand<'a>,
|
||||
pub src2: Operand<'a>,
|
||||
pub struct Arg4<ID> {
|
||||
pub dst1: ID,
|
||||
pub dst2: Option<ID>,
|
||||
pub src1: Operand<ID>,
|
||||
pub src2: Operand<ID>,
|
||||
}
|
||||
|
||||
pub struct Arg5<'a> {
|
||||
pub dst1: &'a str,
|
||||
pub dst2: Option<&'a str>,
|
||||
pub src1: Operand<'a>,
|
||||
pub src2: Operand<'a>,
|
||||
pub src3: Operand<'a>,
|
||||
pub struct Arg5<ID> {
|
||||
pub dst1: ID,
|
||||
pub dst2: Option<ID>,
|
||||
pub src1: Operand<ID>,
|
||||
pub src2: Operand<ID>,
|
||||
pub src3: Operand<ID>,
|
||||
}
|
||||
|
||||
pub enum Operand<'a> {
|
||||
Reg(&'a str),
|
||||
RegOffset(&'a str, i32),
|
||||
pub enum Operand<ID> {
|
||||
Reg(ID),
|
||||
RegOffset(ID, i32),
|
||||
Imm(i128),
|
||||
}
|
||||
|
||||
pub enum MovOperand<'a> {
|
||||
Op(Operand<'a>),
|
||||
Vec(&'a str, &'a str),
|
||||
pub enum MovOperand<ID> {
|
||||
Op(Operand<ID>),
|
||||
Vec(String, String),
|
||||
}
|
||||
|
||||
pub struct LdData {}
|
||||
|
|
|
@ -86,7 +86,7 @@ FunctionInput: ast::Argument<'input> = {
|
|||
}
|
||||
};
|
||||
|
||||
FunctionBody: Vec<ast::Statement<'input>> = {
|
||||
FunctionBody: Vec<ast::Statement<&'input str>> = {
|
||||
"{" <s:Statement*> "}" => { without_none(s) }
|
||||
};
|
||||
|
||||
|
@ -135,7 +135,7 @@ BaseType = {
|
|||
".f32", ".f64"
|
||||
};
|
||||
|
||||
Statement: Option<ast::Statement<'input>> = {
|
||||
Statement: Option<ast::Statement<&'input str>> = {
|
||||
<l:Label> => Some(ast::Statement::Label(l)),
|
||||
DebugDirective => None,
|
||||
<v:Variable> ";" => Some(ast::Statement::Variable(v)),
|
||||
|
@ -155,7 +155,7 @@ Label: &'input str = {
|
|||
<id:ID> ":" => id
|
||||
};
|
||||
|
||||
Variable: ast::Variable<'input> = {
|
||||
Variable: ast::Variable<&'input str> = {
|
||||
<s:StateSpaceSpecifier> <t:Type> <v:VariableName> => {
|
||||
let (name, count) = v;
|
||||
ast::Variable { space: s, v_type: t, name: name, count: count }
|
||||
|
@ -175,7 +175,7 @@ VariableName: (&'input str, Option<u32>) = {
|
|||
}
|
||||
};
|
||||
|
||||
Instruction: ast::Instruction<'input> = {
|
||||
Instruction: ast::Instruction<&'input str> = {
|
||||
InstLd,
|
||||
InstMov,
|
||||
InstMul,
|
||||
|
@ -190,7 +190,7 @@ Instruction: ast::Instruction<'input> = {
|
|||
};
|
||||
|
||||
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-ld
|
||||
InstLd: ast::Instruction<'input> = {
|
||||
InstLd: ast::Instruction<&'input str> = {
|
||||
"ld" LdQualifier? LdStateSpace? LdCacheOperator? Vector? BaseType <dst:ID> "," "[" <src:Operand> "]" => {
|
||||
ast::Instruction::Ld(ast::LdData{}, ast::Arg2{dst:dst, src:src})
|
||||
}
|
||||
|
@ -224,7 +224,7 @@ LdCacheOperator = {
|
|||
};
|
||||
|
||||
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-mov
|
||||
InstMov: ast::Instruction<'input> = {
|
||||
InstMov: ast::Instruction<&'input str> = {
|
||||
"mov" MovType <a:Arg2Mov> => {
|
||||
ast::Instruction::Mov(ast::MovData{}, a)
|
||||
}
|
||||
|
@ -241,7 +241,7 @@ MovType = {
|
|||
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-mul
|
||||
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-mul
|
||||
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#half-precision-floating-point-instructions-mul
|
||||
InstMul: ast::Instruction<'input> = {
|
||||
InstMul: ast::Instruction<&'input str> = {
|
||||
"mul" <d:InstMulMode> <a:Arg3> => ast::Instruction::Mul(d, a)
|
||||
};
|
||||
|
||||
|
@ -270,7 +270,7 @@ IntType = {
|
|||
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#integer-arithmetic-instructions-add
|
||||
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#floating-point-instructions-add
|
||||
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#half-precision-floating-point-instructions-add
|
||||
InstAdd: ast::Instruction<'input> = {
|
||||
InstAdd: ast::Instruction<&'input str> = {
|
||||
"add" <d:InstAddMode> <a:Arg3> => ast::Instruction::Add(d, a)
|
||||
};
|
||||
|
||||
|
@ -286,7 +286,7 @@ InstAddMode: ast::AddData = {
|
|||
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#comparison-and-selection-instructions-setp
|
||||
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#half-precision-comparison-instructions-setp
|
||||
// TODO: support f16 setp
|
||||
InstSetp: ast::Instruction<'input> = {
|
||||
InstSetp: ast::Instruction<&'input str> = {
|
||||
"setp" <d:SetpMode> <a:Arg4> => ast::Instruction::Setp(d, a),
|
||||
"setp" <d:SetpBoolMode> <a:Arg5> => ast::Instruction::SetpBool(d, a),
|
||||
};
|
||||
|
@ -316,7 +316,7 @@ SetpType = {
|
|||
};
|
||||
|
||||
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-not
|
||||
InstNot: ast::Instruction<'input> = {
|
||||
InstNot: ast::Instruction<&'input str> = {
|
||||
"not" NotType <a:Arg2> => ast::Instruction::Not(ast::NotData{}, a)
|
||||
};
|
||||
|
||||
|
@ -325,18 +325,18 @@ NotType = {
|
|||
};
|
||||
|
||||
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#control-flow-instructions-at
|
||||
PredAt: ast::PredAt<'input> = {
|
||||
PredAt: ast::PredAt<&'input str> = {
|
||||
"@" <label:ID> => ast::PredAt { not: false, label:label },
|
||||
"@" "!" <label:ID> => ast::PredAt { not: true, label:label }
|
||||
};
|
||||
|
||||
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#control-flow-instructions-bra
|
||||
InstBra: ast::Instruction<'input> = {
|
||||
InstBra: ast::Instruction<&'input str> = {
|
||||
"bra" ".uni"? <a:Arg1> => ast::Instruction::Bra(ast::BraData{}, a)
|
||||
};
|
||||
|
||||
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-cvt
|
||||
InstCvt: ast::Instruction<'input> = {
|
||||
InstCvt: ast::Instruction<&'input str> = {
|
||||
"cvt" CvtRnd? ".ftz"? ".sat"? CvtType CvtType <a:Arg2> => {
|
||||
ast::Instruction::Cvt(ast::CvtData{}, a)
|
||||
}
|
||||
|
@ -362,7 +362,7 @@ CvtType = {
|
|||
};
|
||||
|
||||
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-shl
|
||||
InstShl: ast::Instruction<'input> = {
|
||||
InstShl: ast::Instruction<&'input str> = {
|
||||
"shl" ShlType <a:Arg3> => ast::Instruction::Shl(ast::ShlData{}, a)
|
||||
};
|
||||
|
||||
|
@ -371,7 +371,7 @@ ShlType = {
|
|||
};
|
||||
|
||||
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-st
|
||||
InstSt: ast::Instruction<'input> = {
|
||||
InstSt: ast::Instruction<&'input str> = {
|
||||
"st" LdQualifier? StStateSpace? StCacheOperator? Vector? BaseType "[" <dst:ID> "]" "," <src:Operand> => {
|
||||
ast::Instruction::St(ast::StData{}, ast::Arg2{dst:dst, src:src})
|
||||
}
|
||||
|
@ -392,11 +392,11 @@ StCacheOperator = {
|
|||
};
|
||||
|
||||
// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#control-flow-instructions-ret
|
||||
InstRet: ast::Instruction<'input> = {
|
||||
InstRet: ast::Instruction<&'input str> = {
|
||||
"ret" ".uni"? => ast::Instruction::Ret(ast::RetData{})
|
||||
};
|
||||
|
||||
Operand: ast::Operand<'input> = {
|
||||
Operand: ast::Operand<&'input str> = {
|
||||
<r:ID> => ast::Operand::Reg(r),
|
||||
<r:ID> "+" <o:Num> => {
|
||||
let offset = o.parse::<i32>();
|
||||
|
@ -412,11 +412,11 @@ Operand: ast::Operand<'input> = {
|
|||
}
|
||||
};
|
||||
|
||||
MovOperand: ast::MovOperand<'input> = {
|
||||
MovOperand: ast::MovOperand<&'input str> = {
|
||||
<o:Operand> => ast::MovOperand::Op(o),
|
||||
<o:VectorOperand> => {
|
||||
let (pref, suf) = o;
|
||||
ast::MovOperand::Vec(pref, suf)
|
||||
ast::MovOperand::Vec(pref.to_string(), suf.to_string())
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -425,28 +425,28 @@ VectorOperand: (&'input str, &'input str) = {
|
|||
<pref:ID> <suf:DotID> => (pref, &suf[1..]),
|
||||
};
|
||||
|
||||
Arg1: ast::Arg1<'input> = {
|
||||
Arg1: ast::Arg1<&'input str> = {
|
||||
<dst:ID> => ast::Arg1{<>}
|
||||
};
|
||||
|
||||
Arg2: ast::Arg2<'input> = {
|
||||
Arg2: ast::Arg2<&'input str> = {
|
||||
<dst:ID> "," <src:Operand> => ast::Arg2{<>}
|
||||
};
|
||||
|
||||
Arg2Mov: ast::Arg2Mov<'input> = {
|
||||
Arg2Mov: ast::Arg2Mov<&'input str> = {
|
||||
<dst:ID> "," <src:MovOperand> => ast::Arg2Mov{<>}
|
||||
};
|
||||
|
||||
Arg3: ast::Arg3<'input> = {
|
||||
Arg3: ast::Arg3<&'input str> = {
|
||||
<dst:ID> "," <src1:Operand> "," <src2:Operand> => ast::Arg3{<>}
|
||||
};
|
||||
|
||||
Arg4: ast::Arg4<'input> = {
|
||||
Arg4: ast::Arg4<&'input str> = {
|
||||
<dst1:ID> <dst2:OptionalDst?> "," <src1:Operand> "," <src2:Operand> => ast::Arg4{<>}
|
||||
};
|
||||
|
||||
// TODO: pass src3 negation somewhere
|
||||
Arg5: ast::Arg5<'input> = {
|
||||
Arg5: ast::Arg5<&'input str> = {
|
||||
<dst1:ID> <dst2:OptionalDst?> "," <src1:Operand> "," <src2:Operand> "," "!"? <src3:Operand> => ast::Arg5{<>}
|
||||
};
|
||||
|
||||
|
|
|
@ -138,7 +138,7 @@ fn emit_function<'a>(
|
|||
}
|
||||
|
||||
// TODO: support scopes
|
||||
fn normalize_identifiers<'a>(func: Vec<ast::Statement<'a>>) -> Vec<Statement> {
|
||||
fn normalize_identifiers<'a>(func: Vec<ast::Statement<&'a str>>) -> Vec<Statement> {
|
||||
let mut result = Vec::with_capacity(func.len());
|
||||
let mut id: u32 = 0;
|
||||
let mut known_ids = HashMap::new();
|
||||
|
@ -162,193 +162,124 @@ fn ssa_legalize(func: Vec<Statement>) -> Vec<Statement> {
|
|||
|
||||
enum Statement {
|
||||
Label(u32),
|
||||
Instruction(Option<PredAt>, Instruction),
|
||||
Instruction(Option<ast::PredAt<u32>>, ast::Instruction<u32>),
|
||||
Phi(Vec<spirv::Word>),
|
||||
}
|
||||
|
||||
impl Statement {
|
||||
fn from_ast<'a, F: FnMut(&'a str) -> u32>(s: ast::Statement<'a>, f: &mut F) -> Option<Self> {
|
||||
fn from_ast<'a, F: FnMut(&'a str) -> u32>(s: ast::Statement<&'a str>, f: &mut F) -> Option<Self> {
|
||||
match s {
|
||||
ast::Statement::Label(name) => Some(Statement::Label(f(name))),
|
||||
ast::Statement::Instruction(p, i) => Some(Statement::Instruction(
|
||||
p.map(|p| PredAt::from_ast(p, f)),
|
||||
Instruction::from_ast(i, f),
|
||||
p.map(|p| p.map_id(f)),
|
||||
i.map_id(f),
|
||||
)),
|
||||
ast::Statement::Variable(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct PredAt {
|
||||
pub not: bool,
|
||||
pub label: u32,
|
||||
}
|
||||
|
||||
impl PredAt {
|
||||
fn from_ast<'a, F: FnMut(&'a str) -> u32>(p: ast::PredAt<'a>, f: &mut F) -> Self {
|
||||
PredAt {
|
||||
not: p.not,
|
||||
label: f(p.label),
|
||||
impl<T> ast::PredAt<T> {
|
||||
fn map_id<U, F: FnMut(T) -> U>(self, f: &mut F) -> ast::PredAt<U> {
|
||||
ast::PredAt {
|
||||
not: self.not,
|
||||
label: f(self.label),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum Instruction {
|
||||
Ld(ast::LdData, Arg2),
|
||||
Mov(ast::MovData, Arg2Mov),
|
||||
Mul(ast::MulData, Arg3),
|
||||
Add(ast::AddData, Arg3),
|
||||
Setp(ast::SetpData, Arg4),
|
||||
SetpBool(ast::SetpBoolData, Arg5),
|
||||
Not(ast::NotData, Arg2),
|
||||
Bra(ast::BraData, Arg1),
|
||||
Cvt(ast::CvtData, Arg2),
|
||||
Shl(ast::ShlData, Arg3),
|
||||
St(ast::StData, Arg2),
|
||||
At(ast::AtData, Arg1),
|
||||
Ret(ast::RetData),
|
||||
}
|
||||
|
||||
impl Instruction {
|
||||
fn from_ast<'a, F: FnMut(&'a str) -> u32>(i: ast::Instruction<'a>, f: &mut F) -> Self {
|
||||
match i {
|
||||
ast::Instruction::Ld(d, a) => Instruction::Ld(d, Arg2::from_ast(a, f)),
|
||||
ast::Instruction::Mov(d, a) => Instruction::Mov(d, Arg2Mov::from_ast(a, f)),
|
||||
ast::Instruction::Mul(d, a) => Instruction::Mul(d, Arg3::from_ast(a, f)),
|
||||
ast::Instruction::Add(d, a) => Instruction::Add(d, Arg3::from_ast(a, f)),
|
||||
ast::Instruction::Setp(d, a) => Instruction::Setp(d, Arg4::from_ast(a, f)),
|
||||
ast::Instruction::SetpBool(d, a) => Instruction::SetpBool(d, Arg5::from_ast(a, f)),
|
||||
ast::Instruction::Not(d, a) => Instruction::Not(d, Arg2::from_ast(a, f)),
|
||||
ast::Instruction::Bra(d, a) => Instruction::Bra(d, Arg1::from_ast(a, f)),
|
||||
ast::Instruction::Cvt(d, a) => Instruction::Cvt(d, Arg2::from_ast(a, f)),
|
||||
ast::Instruction::Shl(d, a) => Instruction::Shl(d, Arg3::from_ast(a, f)),
|
||||
ast::Instruction::St(d, a) => Instruction::St(d, Arg2::from_ast(a, f)),
|
||||
ast::Instruction::At(d, a) => Instruction::At(d, Arg1::from_ast(a, f)),
|
||||
ast::Instruction::Ret(d) => Instruction::Ret(d),
|
||||
impl<T> ast::Instruction<T> {
|
||||
fn map_id<U, F: FnMut(T) -> U>(self, f: &mut F) -> ast::Instruction<U> {
|
||||
match self {
|
||||
ast::Instruction::Ld(d, a) => ast::Instruction::Ld(d, a.map_id(f)),
|
||||
ast::Instruction::Mov(d, a) => ast::Instruction::Mov(d, a.map_id(f)),
|
||||
ast::Instruction::Mul(d, a) => ast::Instruction::Mul(d, a.map_id(f)),
|
||||
ast::Instruction::Add(d, a) => ast::Instruction::Add(d, a.map_id(f)),
|
||||
ast::Instruction::Setp(d, a) => ast::Instruction::Setp(d, a.map_id(f)),
|
||||
ast::Instruction::SetpBool(d, a) => ast::Instruction::SetpBool(d, a.map_id(f)),
|
||||
ast::Instruction::Not(d, a) => ast::Instruction::Not(d, a.map_id(f)),
|
||||
ast::Instruction::Bra(d, a) => ast::Instruction::Bra(d, a.map_id(f)),
|
||||
ast::Instruction::Cvt(d, a) => ast::Instruction::Cvt(d, a.map_id(f)),
|
||||
ast::Instruction::Shl(d, a) => ast::Instruction::Shl(d, a.map_id(f)),
|
||||
ast::Instruction::St(d, a) => ast::Instruction::St(d, a.map_id(f)),
|
||||
ast::Instruction::At(d, a) => ast::Instruction::At(d, a.map_id(f)),
|
||||
ast::Instruction::Ret(d) => ast::Instruction::Ret(d),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Arg1 {
|
||||
pub dst: u32,
|
||||
}
|
||||
|
||||
impl Arg1 {
|
||||
fn from_ast<'a, F: FnMut(&'a str) -> u32>(a: ast::Arg1<'a>, f: &mut F) -> Self {
|
||||
Arg1 { dst: f(a.dst) }
|
||||
impl<T> ast::Arg1<T> {
|
||||
fn map_id<U, F: FnMut(T) -> U>(self, f: &mut F) -> ast::Arg1<U> {
|
||||
ast::Arg1 { dst: f(self.dst) }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Arg2 {
|
||||
pub dst: u32,
|
||||
pub src: Operand,
|
||||
}
|
||||
|
||||
impl Arg2 {
|
||||
fn from_ast<'a, F: FnMut(&'a str) -> u32>(a: ast::Arg2<'a>, f: &mut F) -> Self {
|
||||
Arg2 {
|
||||
dst: f(a.dst),
|
||||
src: Operand::from_ast(a.src, f),
|
||||
impl<T> ast::Arg2<T> {
|
||||
fn map_id<U, F: FnMut(T) -> U>(self, f: &mut F) -> ast::Arg2<U> {
|
||||
ast::Arg2 {
|
||||
dst: f(self.dst),
|
||||
src: self.src.map_id(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Arg2Mov {
|
||||
pub dst: u32,
|
||||
pub src: MovOperand,
|
||||
}
|
||||
|
||||
impl Arg2Mov {
|
||||
fn from_ast<'a, F: FnMut(&'a str) -> u32>(a: ast::Arg2Mov<'a>, f: &mut F) -> Self {
|
||||
Arg2Mov {
|
||||
dst: f(a.dst),
|
||||
src: MovOperand::from_ast(a.src, f),
|
||||
impl<T> ast::Arg2Mov<T> {
|
||||
fn map_id<U, F: FnMut(T) -> U>(self, f: &mut F) -> ast::Arg2Mov<U> {
|
||||
ast::Arg2Mov {
|
||||
dst: f(self.dst),
|
||||
src: self.src.map_id(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Arg3 {
|
||||
pub dst: u32,
|
||||
pub src1: Operand,
|
||||
pub src2: Operand,
|
||||
}
|
||||
|
||||
impl Arg3 {
|
||||
fn from_ast<'a, F: FnMut(&'a str) -> u32>(a: ast::Arg3<'a>, f: &mut F) -> Self {
|
||||
Arg3 {
|
||||
dst: f(a.dst),
|
||||
src1: Operand::from_ast(a.src1, f),
|
||||
src2: Operand::from_ast(a.src2, f),
|
||||
impl<T> ast::Arg3<T> {
|
||||
fn map_id<U, F: FnMut(T) -> U>(self, f: &mut F) -> ast::Arg3<U> {
|
||||
ast::Arg3 {
|
||||
dst: f(self.dst),
|
||||
src1: self.src1.map_id(f),
|
||||
src2: self.src2.map_id(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Arg4 {
|
||||
pub dst1: u32,
|
||||
pub dst2: Option<u32>,
|
||||
pub src1: Operand,
|
||||
pub src2: Operand,
|
||||
}
|
||||
|
||||
impl Arg4 {
|
||||
fn from_ast<'a, F: FnMut(&'a str) -> u32>(a: ast::Arg4<'a>, f: &mut F) -> Self {
|
||||
Arg4 {
|
||||
dst1: f(a.dst1),
|
||||
dst2: a.dst2.map(|i| f(i)),
|
||||
src1: Operand::from_ast(a.src1, f),
|
||||
src2: Operand::from_ast(a.src2, f),
|
||||
impl<T> ast::Arg4<T> {
|
||||
fn map_id<U, F: FnMut(T) -> U>(self, f: &mut F) -> ast::Arg4<U> {
|
||||
ast::Arg4 {
|
||||
dst1: f(self.dst1),
|
||||
dst2: self.dst2.map(|i| f(i)),
|
||||
src1: self.src1.map_id(f),
|
||||
src2: self.src2.map_id(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Arg5 {
|
||||
pub dst1: u32,
|
||||
pub dst2: Option<u32>,
|
||||
pub src1: Operand,
|
||||
pub src2: Operand,
|
||||
pub src3: Operand,
|
||||
}
|
||||
|
||||
impl Arg5 {
|
||||
fn from_ast<'a, F: FnMut(&'a str) -> u32>(a: ast::Arg5<'a>, f: &mut F) -> Self {
|
||||
Arg5 {
|
||||
dst1: f(a.dst1),
|
||||
dst2: a.dst2.map(|i| f(i)),
|
||||
src1: Operand::from_ast(a.src1, f),
|
||||
src2: Operand::from_ast(a.src2, f),
|
||||
src3: Operand::from_ast(a.src3, f),
|
||||
impl<T> ast::Arg5<T> {
|
||||
fn map_id<U, F: FnMut(T) -> U>(self, f: &mut F) -> ast::Arg5<U> {
|
||||
ast::Arg5 {
|
||||
dst1: f(self.dst1),
|
||||
dst2: self.dst2.map(|i| f(i)),
|
||||
src1: self.src1.map_id(f),
|
||||
src2: self.src2.map_id(f),
|
||||
src3: self.src3.map_id(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Operand {
|
||||
Reg(u32),
|
||||
RegOffset(u32, i32),
|
||||
Imm(i128),
|
||||
}
|
||||
|
||||
impl Operand {
|
||||
fn from_ast<'a, F: FnMut(&'a str) -> u32>(a: ast::Operand<'a>, f: &mut F) -> Self {
|
||||
match a {
|
||||
ast::Operand::Reg(i) => Operand::Reg(f(i)),
|
||||
ast::Operand::RegOffset(i, o) => Operand::RegOffset(f(i), o),
|
||||
ast::Operand::Imm(v) => Operand::Imm(v),
|
||||
impl<T> ast::Operand<T> {
|
||||
fn map_id<U, F: FnMut(T) -> U>(self, f: &mut F) -> ast::Operand<U> {
|
||||
match self {
|
||||
ast::Operand::Reg(i) => ast::Operand::Reg(f(i)),
|
||||
ast::Operand::RegOffset(i, o) => ast::Operand::RegOffset(f(i), o),
|
||||
ast::Operand::Imm(v) => ast::Operand::Imm(v),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum MovOperand {
|
||||
Op(Operand),
|
||||
Vec(String, String),
|
||||
}
|
||||
|
||||
impl MovOperand {
|
||||
fn from_ast<'a, F: FnMut(&'a str) -> u32>(a: ast::MovOperand<'a>, f: &mut F) -> Self {
|
||||
match a {
|
||||
ast::MovOperand::Op(o) => MovOperand::Op(Operand::from_ast(o, f)),
|
||||
ast::MovOperand::Vec(var, idx) => {
|
||||
MovOperand::Vec(var.to_owned(), idx.to_string())
|
||||
}
|
||||
impl<T> ast::MovOperand<T> {
|
||||
fn map_id<U, F: FnMut(T) -> U>(self, f: &mut F) -> ast::MovOperand<U> {
|
||||
match self {
|
||||
ast::MovOperand::Op(o) => ast::MovOperand::Op(o.map_id(f)),
|
||||
ast::MovOperand::Vec(s1, s2) => ast::MovOperand::Vec(s1, s2)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue