diff options
author | Andrzej Janik <[email protected]> | 2020-10-26 01:49:25 +0100 |
---|---|---|
committer | Andrzej Janik <[email protected]> | 2020-10-26 01:49:25 +0100 |
commit | 40bdb83e6b80c169e9ab38e332dc3d633e8b0066 (patch) | |
tree | 64cc14dd06d3ed8ae0da18b728657b72487972cd /ptx/src/ptx.lalrpop | |
parent | 17b788f2a70fa78be945878b52ef497f5b76b5b1 (diff) | |
download | ZLUDA-40bdb83e6b80c169e9ab38e332dc3d633e8b0066.tar.gz ZLUDA-40bdb83e6b80c169e9ab38e332dc3d633e8b0066.zip |
Support float constants
Diffstat (limited to 'ptx/src/ptx.lalrpop')
-rw-r--r-- | ptx/src/ptx.lalrpop | 158 |
1 files changed, 122 insertions, 36 deletions
diff --git a/ptx/src/ptx.lalrpop b/ptx/src/ptx.lalrpop index 163a233..d445baa 100644 --- a/ptx/src/ptx.lalrpop +++ b/ptx/src/ptx.lalrpop @@ -15,12 +15,16 @@ match { r"\s+" => { }, r"//[^\n\r]*[\n\r]*" => { }, r"/\*([^\*]*\*+[^\*/])*([^\*]*\*+|[^\*])*\*/" => { }, - r"-?[?:0x]?[0-9]+" => Num, + r"0[fF][0-9a-zA-Z]{8}" => F32NumToken, + r"0[dD][0-9a-zA-Z]{16}" => F64NumToken, + r"0[xX][0-9a-zA-Z]+U?" => HexNumToken, + r"[0-9]+U?" => DecimalNumToken, r#""[^"]*""# => String, r"[0-9]+\.[0-9]+" => VersionNumber, "!", "(", ")", "+", + "-", ",", ".", ":", @@ -181,6 +185,74 @@ ExtendedID : &'input str = { ID } +NumToken: (&'input str, u32, bool) = { + <s:HexNumToken> => { + if s.ends_with('U') { + (&s[2..s.len() - 1], 16, true) + } else { + (&s[2..], 16, false) + } + }, + <s:DecimalNumToken> => { + let radix = if s.starts_with('0') { 8 } else { 10 }; + if s.ends_with('U') { + (&s[..s.len() - 1], radix, true) + } else { + (s, radix, false) + } + } +} + +F32Num: f32 = { + <s:F32NumToken> =>? { + match u32::from_str_radix(&s[2..], 16) { + Ok(x) => Ok(unsafe { std::mem::transmute::<_, f32>(x) }), + Err(err) => Err(ParseError::User { error: ast::PtxError::from(err) }) + } + + } +} + +F64Num: f64 = { + <s:F64NumToken> =>? { + match u64::from_str_radix(&s[2..], 16) { + Ok(x) => Ok(unsafe { std::mem::transmute::<_, f64>(x) }), + Err(err) => Err(ParseError::User { error: ast::PtxError::from(err) }) + } + } +} + +U8Num: u8 = { + <x:NumToken> =>? { + let (text, radix, _) = x; + match u8::from_str_radix(text, radix) { + Ok(x) => Ok(x), + Err(err) => Err(ParseError::User { error: ast::PtxError::from(err) }) + } + } +} + +U32Num: u32 = { + <x:NumToken> =>? { + let (text, radix, _) = x; + match u32::from_str_radix(text, radix) { + Ok(x) => Ok(x), + Err(err) => Err(ParseError::User { error: ast::PtxError::from(err) }) + } + } +} + +// TODO: handle negative number properly +S32Num: i32 = { + <sign:"-"?> <x:NumToken> =>? { + let (text, radix, _) = x; + match i32::from_str_radix(text, radix) { + Ok(x) => Ok(if sign.is_some() { -x } else { x }), + Err(err) => Err(ParseError::User { error: ast::PtxError::from(err) }) + } + } +} + pub Module: ast::Module<'input> = { <v:Version> Target <d:Directive*> => { ast::Module { version: v, directives: without_none(d) } @@ -218,7 +290,7 @@ Directive: Option<ast::Directive<'input, ast::ParsedArgParams<'input>>> = { }; AddressSize = { - ".address_size" Num + ".address_size" U8Num }; Function: ast::Function<'input, &'input str, ast::Statement<ast::ParsedArgParams<'input>>> = { @@ -328,7 +400,7 @@ DebugDirective: () = { // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#debugging-directives-loc DebugLocation = { - ".loc" Num Num Num + ".loc" U32Num U32Num U32Num }; Label: &'input str = { @@ -336,10 +408,7 @@ Label: &'input str = { }; Align: u32 = { - ".align" <a:Num> => { - let align = a.parse::<u32>(); - align.unwrap_with(errors) - } + ".align" <x:U32Num> => x }; // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parameterized-variable-names @@ -348,10 +417,7 @@ MultiVariable: ast::MultiVariable<&'input str> = { } VariableParam: u32 = { - "<" <n:Num> ">" => { - let size = n.parse::<u32>(); - size.unwrap_with(errors) - } + "<" <n:U32Num> ">" => n } Variable: ast::Variable<ast::VariableType, &'input str> = { @@ -1239,28 +1305,50 @@ ArithFloat: ast::ArithFloat = { Operand: ast::Operand<&'input str> = { <r:ExtendedID> => ast::Operand::Reg(r), - <r:ExtendedID> "+" <o:Num> => { - let offset = o.parse::<i32>(); - let offset = offset.unwrap_with(errors); - ast::Operand::RegOffset(r, offset) - }, - // TODO: start parsing whole constants sub-language: - // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#constants - <o:Num> => { - let offset = o.parse::<u32>(); - let offset = offset.unwrap_with(errors); - ast::Operand::Imm(offset) - } + <r:ExtendedID> "+" <offset:S32Num> => ast::Operand::RegOffset(r, offset), + <x:ImmediateValue> => ast::Operand::Imm(x) }; CallOperand: ast::CallOperand<&'input str> = { <r:ExtendedID> => ast::CallOperand::Reg(r), - <o:Num> => { - let offset = o.parse::<u32>(); - let offset = offset.unwrap_with(errors); - ast::CallOperand::Imm(offset) + <x:ImmediateValue> => ast::CallOperand::Imm(x) +}; + +// TODO: start parsing whole constants sub-language: +// https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#constants +ImmediateValue: ast::ImmediateValue = { + // TODO: treat negation correctly + <neg:"-"?> <x:NumToken> =>? { + let (num, radix, is_unsigned) = x; + if neg.is_some() { + match i64::from_str_radix(num, radix) { + Ok(x) => Ok(ast::ImmediateValue::S64(-x)), + Err(err) => Err(ParseError::User { error: ast::PtxError::ParseInt(err) }) + } + } else if is_unsigned { + match u64::from_str_radix(num, radix) { + Ok(x) => Ok(ast::ImmediateValue::U64(x)), + Err(err) => Err(ParseError::User { error: ast::PtxError::ParseInt(err) }) + } + } else { + match i64::from_str_radix(num, radix) { + Ok(x) => Ok(ast::ImmediateValue::S64(x)), + Err(_) => { + match u64::from_str_radix(num, radix) { + Ok(x) => Ok(ast::ImmediateValue::U64(x)), + Err(err) => Err(ParseError::User { error: ast::PtxError::ParseInt(err) }) + } + } + } + } + }, + <f:F32Num> => { + ast::ImmediateValue::F32(f) + }, + <f:F64Num> => { + ast::ImmediateValue::F64(f) } -}; +} Arg1: ast::Arg1<ast::ParsedArgParams<'input>> = { <src:ExtendedID> => ast::Arg1{<>} @@ -1332,7 +1420,7 @@ VectorPrefix: u8 = { // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#debugging-directives-file File = { - ".file" Num String ("," Num "," Num)? + ".file" U32Num String ("," U32Num "," U32Num)? }; // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#debugging-directives-section @@ -1341,11 +1429,11 @@ Section = { }; SectionDwarfLines: () = { - BitType Comma<Num>, + BitType Comma<U32Num>, ".b32" SectionLabel, ".b64" SectionLabel, - ".b32" SectionLabel "+" Num, - ".b64" SectionLabel "+" Num, + ".b32" SectionLabel "+" U32Num, + ".b64" SectionLabel "+" U32Num, }; SectionLabel = { @@ -1409,9 +1497,7 @@ ArrayEmptyDimension = { } ArrayDimension: u32 = { - "[" <n:Num> "]" =>? { - str::parse::<u32>(n).map_err(|e| ParseError::User { error: ast::PtxError::ParseInt(e) }) - } + "[" <n:U32Num> "]" => n, } ArrayInitializer: ast::NumsOrArrays<'input> = { @@ -1424,7 +1510,7 @@ NumsOrArraysBracket: ast::NumsOrArrays<'input> = { NumsOrArrays: ast::NumsOrArrays<'input> = { <n:Comma<NumsOrArraysBracket>> => ast::NumsOrArrays::Arrays(n), - <n:CommaNonEmpty<Num>> => ast::NumsOrArrays::Nums(n), + <n:CommaNonEmpty<NumToken>> => ast::NumsOrArrays::Nums(n.into_iter().map(|(x,radix,_)| (x, radix)).collect()), } Comma<T>: Vec<T> = { |