diff --git a/ptx/Cargo.toml b/ptx/Cargo.toml index 62050b9..64c3547 100644 --- a/ptx/Cargo.toml +++ b/ptx/Cargo.toml @@ -9,6 +9,7 @@ edition = "2018" [dependencies] lalrpop-util = "0.18.1" regex = "1" +rspirv = "0.6" [build-dependencies.lalrpop] version = "0.18.1" diff --git a/ptx/doc/NOTES.md b/ptx/doc/NOTES.md index 8954b4b..b4d2ad3 100644 --- a/ptx/doc/NOTES.md +++ b/ptx/doc/NOTES.md @@ -3,4 +3,16 @@ I'm convinced nobody actually uses parser generators in Rust: * pest can't do parse actions, you have to convert your parse tree to ast manually * lalrpop can't do comments * and the day I wrote the line above it can -* antlr4rust is untried and requires java to build \ No newline at end of file + * reports parsing errors as byte offsets + * if you want to skip parsing one of the alternatives functional design gets quite awkward +* antlr4rust is untried and requires java to build +* no library supports island grammars + +What to emit? +* SPIR-V + * Better library support, easier to emit + * Can by optimized by IGC + * Can't do some things (not sure what exactly yet) + * But we can work around things with inline VISA +* VISA + * Quicker compilation \ No newline at end of file diff --git a/ptx/src/ast.rs b/ptx/src/ast.rs index 56b299e..645e3a1 100644 --- a/ptx/src/ast.rs +++ b/ptx/src/ast.rs @@ -1,18 +1,39 @@ - -pub struct Module { - version: (u8, u8), - target: Target +pub struct Module<'a> { + pub version: (u8, u8), + pub functions: Vec> } -pub struct Target { - arch: String, - texturing: TexturingMode, - debug: bool, - f64_to_f32: bool +pub struct Function<'a> { + pub kernel: bool, + pub name: &'a str, + pub args: Vec, + pub body: Vec>, } -pub enum TexturingMode { - Unspecified, - Unified, - Independent +pub struct Argument { + +} + +pub enum Statement<'a> { + Label(&'a str), + Variable(Variable), + Instruction(Instruction) +} + +pub struct Variable { + +} + +pub enum Instruction { + Ld, + Mov, + Mul, + Add, + Setp, + Not, + Bra, + Cvt, + Shl, + At, + Ret } \ No newline at end of file diff --git a/ptx/src/lib.rs b/ptx/src/lib.rs index dc24b59..a29270f 100644 --- a/ptx/src/lib.rs +++ b/ptx/src/lib.rs @@ -1,9 +1,11 @@ #[macro_use] extern crate lalrpop_util; -lalrpop_mod!(pub ptx); +lalrpop_mod!(ptx); mod test; - +mod spirv; pub mod ast; + pub use ast::Module as Module; +pub use spirv::translate as to_spirv; diff --git a/ptx/src/ptx.lalrpop b/ptx/src/ptx.lalrpop index 6062be2..96288b9 100644 --- a/ptx/src/ptx.lalrpop +++ b/ptx/src/ptx.lalrpop @@ -1,5 +1,6 @@ use std::str::FromStr; -use super::ast; +use crate::ast; +use std::convert::identity; grammar; @@ -15,15 +16,21 @@ match { _ } -pub Module: () = { - Version - Target - Directive* +pub Module: Option> = { + Target => v.map(|v| ast::Module { version: v, functions: f.into_iter().filter_map(identity).collect::>() }) }; -Version = { - ".version" VersionNumber -}; +Version: Option<(u8, u8)> = { + ".version" => { + let dot = v.find('.').unwrap(); + let major = v[..dot].parse::(); + major.ok().and_then(|major| { + v[dot+1..].parse::().ok().map(|minor| { + (major, minor) + }) + }) + } +} // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#ptx-module-directives-target Target = { @@ -38,19 +45,19 @@ TargetSpecifier = { "map_f64_to_f32" }; -Directive : () = { - AddressSize, - Function, - File, - Section +Directive: Option> = { + AddressSize => None, + => Some(f), + File => None, + Section => None }; AddressSize = { ".address_size" Num }; -Function: (bool, &'input str) = { - LinkingDirective* "(" Comma ")" FunctionBody => (is, id) +Function: ast::Function<'input> = { + LinkingDirective* "(" > ")" => ast::Function {<>} }; LinkingDirective = { @@ -64,12 +71,12 @@ IsKernel: bool = { ".func" => false }; -FunctionInput = { - ".param" Type ID +FunctionInput: ast::Argument = { + ".param" Type ID => ast::Argument {} }; -FunctionBody = { - "{" Statement* "}" +FunctionBody: Vec> = { + "{" "}" => { s.into_iter().filter_map(identity).collect() } }; StateSpaceSpecifier = { @@ -95,14 +102,14 @@ BaseType = { ".f32", ".f64" }; -Statement: () = { - Label, - DebugDirective, - Variable ";", - Instruction ";" +Statement: Option> = { + => Some(ast::Statement::Label(l)), + DebugDirective => None, + ";" => Some(ast::Statement::Variable(v)), + ";" => Some(ast::Statement::Instruction(i)) }; -DebugDirective = { +DebugDirective: () = { DebugLocation }; @@ -111,12 +118,12 @@ DebugLocation = { ".loc" Num Num Num }; -Label = { - ID ":" +Label: &'input str = { + ":" => id }; -Variable = { - StateSpaceSpecifier Type VariableName +Variable: ast::Variable = { + StateSpaceSpecifier Type VariableName => ast::Variable {} }; VariableName = { @@ -124,7 +131,7 @@ VariableName = { ParametrizedID }; -Instruction: () = { +Instruction = { InstLd, InstMov, InstMul, @@ -139,8 +146,8 @@ Instruction: () = { }; // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-ld -InstLd = { - "ld" LdQualifier? LdStateSpace? LdCacheOperator? Vector? BaseType ID "," "[" ID "]" +InstLd: ast::Instruction = { + "ld" LdQualifier? LdStateSpace? LdCacheOperator? Vector? BaseType ID "," "[" ID "]" => ast::Instruction::Ld }; LdQualifier: () = { @@ -171,8 +178,8 @@ LdCacheOperator = { }; // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-mov -InstMov = { - "mov" MovType ID "," Operand +InstMov: ast::Instruction = { + "mov" MovType ID "," Operand => ast::Instruction::Mov }; MovType = { @@ -186,12 +193,12 @@ 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: () = { - "mul" MulIntControl? IntType ID "," Operand "," Operand, - "mul" RoundingMode? ".ftz"? ".sat"? ".f32" ID "," Operand "," Operand, - "mul" RoundingMode? ".f64" ID "," Operand "," Operand, - "mul" ".rn"? ".ftz"? ".sat"? ".f16" ID "," Operand "," Operand, - "mul" ".rn"? ".ftz"? ".sat"? ".f16x2" ID "," Operand "," Operand, +InstMul: ast::Instruction = { + "mul" MulIntControl? IntType ID "," Operand "," Operand => ast::Instruction::Mul, + "mul" RoundingMode? ".ftz"? ".sat"? ".f32" ID "," Operand "," Operand => ast::Instruction::Mul, + "mul" RoundingMode? ".f64" ID "," Operand "," Operand => ast::Instruction::Mul, + "mul" ".rn"? ".ftz"? ".sat"? ".f16" ID "," Operand "," Operand => ast::Instruction::Mul, + "mul" ".rn"? ".ftz"? ".sat"? ".f16x2" ID "," Operand "," Operand => ast::Instruction::Mul, }; MulIntControl = { @@ -211,19 +218,19 @@ 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: () = { - "add" IntType ID "," Operand "," Operand, - "add" ".sat" ".s32" ID "," Operand "," Operand, - "add" RoundingMode? ".ftz"? ".sat"? ".f32" ID "," Operand "," Operand, - "add" RoundingMode? ".f64" ID "," Operand "," Operand, - "add" ".rn"? ".ftz"? ".sat"? ".f16" ID "," Operand "," Operand, - "add" ".rn"? ".ftz"? ".sat"? ".f16x2" ID "," Operand "," Operand, +InstAdd: ast::Instruction = { + "add" IntType ID "," Operand "," Operand => ast::Instruction::Add, + "add" ".sat" ".s32" ID "," Operand "," Operand => ast::Instruction::Add, + "add" RoundingMode? ".ftz"? ".sat"? ".f32" ID "," Operand "," Operand => ast::Instruction::Add, + "add" RoundingMode? ".f64" ID "," Operand "," Operand => ast::Instruction::Add, + "add" ".rn"? ".ftz"? ".sat"? ".f16" ID "," Operand "," Operand => ast::Instruction::Add, + "add" ".rn"? ".ftz"? ".sat"? ".f16x2" ID "," Operand "," Operand => ast::Instruction::Add, }; // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#comparison-and-selection-instructions-setp -InstSetp: () = { - "setp" SetpCmpOp ".ftz"? SetpType ID ("|" ID)? "," Operand "," Operand, - "setp" SetpCmpOp SetpBoolOp ".ftz"? SetpType ID ("|" ID)? "," Operand "," Operand "," "!"? ID +InstSetp: ast::Instruction = { + "setp" SetpCmpOp ".ftz"? SetpType ID ("|" ID)? "," Operand "," Operand => ast::Instruction::Setp, + "setp" SetpCmpOp SetpBoolOp ".ftz"? SetpType ID ("|" ID)? "," Operand "," Operand "," "!"? ID => ast::Instruction::Setp }; SetpCmpOp = { @@ -243,8 +250,8 @@ SetpType = { }; // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-not -InstNot: () = { - "not" NotType ID "," Operand +InstNot: ast::Instruction = { + "not" NotType ID "," Operand => ast::Instruction::Not }; NotType = { @@ -252,18 +259,18 @@ NotType = { }; // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#control-flow-instructions-at -InstAt = { - "@" "!"? ID +InstAt: ast::Instruction = { + "@" "!"? ID => ast::Instruction::At }; // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#control-flow-instructions-bra -InstBra = { - InstAt? "bra" ".uni"? ID +InstBra: ast::Instruction = { + InstAt? "bra" ".uni"? ID => ast::Instruction::Bra }; // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-cvt -InstCvt = { - "cvt" CvtRnd? ".ftz"? ".sat"? CvtType CvtType ID "," Operand +InstCvt: ast::Instruction = { + "cvt" CvtRnd? ".ftz"? ".sat"? CvtType CvtType ID "," Operand => ast::Instruction::Cvt }; CvtRnd = { @@ -286,8 +293,8 @@ CvtType = { }; // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#logic-and-shift-instructions-shl -InstShl = { - "shl" ShlType ID "," Operand "," Operand +InstShl: ast::Instruction = { + "shl" ShlType ID "," Operand "," Operand => ast::Instruction::Shl }; ShlType = { @@ -295,8 +302,8 @@ ShlType = { }; // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-st -InstSt = { - "st" LdQualifier? StStateSpace? StCacheOperator? Vector? BaseType "[" ID "]" "," Operand +InstSt: ast::Instruction = { + "st" LdQualifier? StStateSpace? StCacheOperator? Vector? BaseType "[" ID "]" "," Operand => ast::Instruction::Shl }; StStateSpace = { @@ -314,8 +321,8 @@ StCacheOperator = { }; // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#control-flow-instructions-ret -InstRet: () = { - "ret" ".uni"? +InstRet: ast::Instruction = { + "ret" ".uni"? => ast::Instruction::Ret }; Operand: () = { @@ -384,7 +391,6 @@ Comma: Vec = { String = r#""[^"]*""#; VersionNumber = r"[0-9]+\.[0-9]+"; -//Num: i128 = => i128::from_str(s).unwrap(); // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#identifiers ID: &'input str = => s; DotID: &'input str = => s; \ No newline at end of file diff --git a/ptx/src/spirv.rs b/ptx/src/spirv.rs new file mode 100644 index 0000000..a43692d --- /dev/null +++ b/ptx/src/spirv.rs @@ -0,0 +1,9 @@ +use super::ast; + +pub struct TranslateError { + +} + +pub fn translate(ast: ast::Module) -> Result, TranslateError> { + Ok(vec!()) +} \ No newline at end of file