Support generating signed numbers.
This commit is contained in:
@@ -43,7 +43,7 @@ declareSafeAddOperators bitsize _ =
|
||||
let sname = mkIdent ("U" ++ show bitsize)
|
||||
dname = mkIdent ("U" ++ show (bitsize + 64))
|
||||
fullRippleAdd = makeRippleAdder True (bitsize `div` 64) "res"
|
||||
testFileLit = Lit [] (Str (testFile bitsize) Cooked Unsuffixed mempty) mempty
|
||||
testFileLit = Lit [] (Str (testFile True bitsize) Cooked Unsuffixed mempty) mempty
|
||||
in [sourceFile|
|
||||
use core::ops::Add;
|
||||
use crate::CryptoNum;
|
||||
@@ -119,7 +119,7 @@ declareUnsafeAddOperators :: Word -> [Word] -> SourceFile Span
|
||||
declareUnsafeAddOperators bitsize _ =
|
||||
let sname = mkIdent ("U" ++ show bitsize)
|
||||
fullRippleAdd = makeRippleAdder False (bitsize `div` 64) "self"
|
||||
testFileLit = Lit [] (Str (testFile bitsize) Cooked Unsuffixed mempty) mempty
|
||||
testFileLit = Lit [] (Str (testFile True bitsize) Cooked Unsuffixed mempty) mempty
|
||||
in [sourceFile|
|
||||
use core::ops::AddAssign;
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -4,7 +4,6 @@ module Base(
|
||||
)
|
||||
where
|
||||
|
||||
-- This is a comment
|
||||
import File
|
||||
import Language.Rust.Data.Ident
|
||||
import Language.Rust.Data.Position
|
||||
|
||||
@@ -37,7 +37,7 @@ declareBinaryOperators bitsize _ =
|
||||
xorOps = generateBinOps "BitXor" struct_name "bitxor" BitXorOp entries
|
||||
baseNegationStmts = negationStatements "self" entries
|
||||
refNegationStmts = negationStatements "output" entries
|
||||
testFileLit = Lit [] (Str (testFile bitsize) Cooked Unsuffixed mempty) mempty
|
||||
testFileLit = Lit [] (Str (testFile True bitsize) Cooked Unsuffixed mempty) mempty
|
||||
in [sourceFile|
|
||||
use core::ops::{BitAnd,BitAndAssign};
|
||||
use core::ops::{BitOr,BitOrAssign};
|
||||
|
||||
@@ -30,7 +30,7 @@ declareComparators bitsize _ =
|
||||
entries = bitsize `div` 64
|
||||
eqStatements = buildEqStatements 0 entries
|
||||
compareExp = buildCompareExp 0 entries
|
||||
testFileLit = Lit [] (Str (testFile bitsize) Cooked Unsuffixed mempty) mempty
|
||||
testFileLit = Lit [] (Str (testFile True bitsize) Cooked Unsuffixed mempty) mempty
|
||||
in [sourceFile|
|
||||
use core::cmp::{Eq,Ordering,PartialEq};
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -43,7 +43,7 @@ declareCryptoNumInstance bitsize _ =
|
||||
Tree (Token mempty (LiteralTok (IntegerTok (show bytelen)) Nothing))
|
||||
])
|
||||
entrieslit = toLit entries
|
||||
testFileLit = Lit [] (Str (testFile bitsize) Cooked Unsuffixed mempty) mempty
|
||||
testFileLit = Lit [] (Str (testFile True bitsize) Cooked Unsuffixed mempty) mempty
|
||||
in [sourceFile|
|
||||
use core::cmp::min;
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -30,7 +30,7 @@ declareDivision size _ =
|
||||
let sname = mkIdent ("U" ++ show size)
|
||||
entries = size `div` 64
|
||||
copyAssign = map doCopy [0..entries-1]
|
||||
testFileLit = Lit [] (Str (testFile size) Cooked Unsuffixed mempty) mempty
|
||||
testFileLit = Lit [] (Str (testFile True size) Cooked Unsuffixed mempty) mempty
|
||||
in [sourceFile|
|
||||
use core::ops::{Div, DivAssign};
|
||||
use core::ops::{Rem, RemAssign};
|
||||
|
||||
@@ -35,8 +35,9 @@ data Task = Task {
|
||||
writer :: Handle -> IO ()
|
||||
}
|
||||
|
||||
testFile :: Word -> FilePath
|
||||
testFile size = "U" ++ show5 size ++ ".test"
|
||||
testFile :: Bool -> Word -> FilePath
|
||||
testFile True size = "U" ++ show5 size ++ ".test"
|
||||
testFile False size = "I" ++ show5 size ++ ".test"
|
||||
|
||||
show5 :: Word -> String
|
||||
show5 = go . show
|
||||
@@ -58,9 +59,10 @@ generateTasks rng files sizes = basicTasks ++ moduleTasks
|
||||
| otherwise =
|
||||
let (myg, theirg) = split g
|
||||
tasks = go theirg files' rest
|
||||
signedBit = if isUnsigned file then "unsigned" else "signed"
|
||||
(signedBit, prefix) | isUnsigned file = ("unsigned", "u")
|
||||
| otherwise = ("signed", "i")
|
||||
mainTask = Task {
|
||||
outputFile = "src" </> signedBit </> ("u" ++ show size) </>
|
||||
outputFile = "src" </> signedBit </> (prefix ++ show size) </>
|
||||
outputName file ++ ".rs",
|
||||
writer = \ hndl -> writeSourceFile hndl (generator file size sizes)
|
||||
}
|
||||
@@ -69,16 +71,16 @@ generateTasks rng files sizes = basicTasks ++ moduleTasks
|
||||
mainTask : tasks
|
||||
Just caseGenerator ->
|
||||
let testTask = Task {
|
||||
outputFile = "testdata" </> outputName file </> testFile size,
|
||||
outputFile = "testdata" </> outputName file </> testFile (isUnsigned file) size,
|
||||
writer = \ hndl -> writeTestCase hndl (caseGenerator size myg)
|
||||
}
|
||||
in testTask : mainTask : tasks
|
||||
|
||||
generateModules :: [Task] -> [Task]
|
||||
generateModules tasks = Map.foldrWithKey maddModule [] fileMap ++ [unsignedTask]
|
||||
generateModules tasks = Map.foldrWithKey maddModule [] fileMap ++ [signedTask, unsignedTask]
|
||||
where
|
||||
maddModule path mods acc
|
||||
| "src/unsigned" `isPrefixOf` path =
|
||||
| ("src/unsigned" `isPrefixOf` path) || ("src/signed" `isPrefixOf` path) =
|
||||
let (basePath, lowerName) = splitFileName (init path)
|
||||
upperName = map toUpper lowerName
|
||||
task = Task {
|
||||
@@ -97,26 +99,28 @@ generateModules tasks = Map.foldrWithKey maddModule [] fileMap ++ [unsignedTask]
|
||||
file = dropExtension fileext
|
||||
in Map.insertWith (++) dir [file] acc
|
||||
--
|
||||
unsignedTask =
|
||||
let mods = Map.foldrWithKey topModule [] fileMap
|
||||
pubuses = Map.foldrWithKey pubUse [] fileMap
|
||||
signedTask = moduleTask "signed"
|
||||
unsignedTask = moduleTask "unsigned"
|
||||
moduleTask kind =
|
||||
let mods = Map.foldrWithKey (topModule kind) [] fileMap
|
||||
pubuses = Map.foldrWithKey (pubUse kind) [] fileMap
|
||||
in Task {
|
||||
outputFile = "src" </> "unsigned.rs",
|
||||
outputFile = "src" </> (kind ++ ".rs"),
|
||||
writer = \ hndl ->
|
||||
writeSourceFile hndl [sourceFile|
|
||||
$@{mods}
|
||||
$@{pubuses}
|
||||
|]
|
||||
}
|
||||
topModule path _ acc
|
||||
| "src/unsigned" `isPrefixOf` path =
|
||||
topModule kind path _ acc
|
||||
| ("src/" ++ kind) `isPrefixOf` path =
|
||||
let lowerName = takeFileName (init path)
|
||||
modl = mkIdent lowerName
|
||||
in [item| mod $$modl; |] : acc
|
||||
| otherwise =
|
||||
acc
|
||||
pubUse path _ acc
|
||||
| "src/unsigned" `isPrefixOf` path =
|
||||
pubUse kind path _ acc
|
||||
| ("src/" ++ kind) `isPrefixOf` path =
|
||||
let lowerName = takeFileName (init path)
|
||||
tname = mkIdent (map toUpper lowerName)
|
||||
modl = mkIdent lowerName
|
||||
|
||||
@@ -29,7 +29,7 @@ declareModOps :: Word -> [Word] -> SourceFile Span
|
||||
declareModOps bitsize _ =
|
||||
let sname = mkIdent ("U" ++ show bitsize)
|
||||
bname = mkIdent ("U" ++ show (bitsize * 2))
|
||||
testFileLit = Lit [] (Str (testFile bitsize) Cooked Unsuffixed mempty) mempty
|
||||
testFileLit = Lit [] (Str (testFile True bitsize) Cooked Unsuffixed mempty) mempty
|
||||
in [sourceFile|
|
||||
use core::convert::TryFrom;
|
||||
use crate::unsigned::{$$sname, $$bname};
|
||||
|
||||
@@ -45,7 +45,7 @@ declareSafeMulOperators bitsize _ =
|
||||
let sname = mkIdent ("U" ++ show bitsize)
|
||||
dname = mkIdent ("U" ++ show (bitsize * 2))
|
||||
fullRippleMul = generateMultiplier True (bitsize `div` 64) "rhs" "res"
|
||||
testFileLit = Lit [] (Str (testFile bitsize) Cooked Unsuffixed mempty) mempty
|
||||
testFileLit = Lit [] (Str (testFile True bitsize) Cooked Unsuffixed mempty) mempty
|
||||
in [sourceFile|
|
||||
use core::ops::Mul;
|
||||
use crate::CryptoNum;
|
||||
@@ -121,7 +121,7 @@ declareUnsafeMulOperators :: Word -> [Word] -> SourceFile Span
|
||||
declareUnsafeMulOperators bitsize _ =
|
||||
let sname = mkIdent ("U" ++ show bitsize)
|
||||
halfRippleMul = generateMultiplier False (bitsize `div` 64) "rhs" "self"
|
||||
testFileLit = Lit [] (Str (testFile bitsize) Cooked Unsuffixed mempty) mempty
|
||||
testFileLit = Lit [] (Str (testFile True bitsize) Cooked Unsuffixed mempty) mempty
|
||||
in [sourceFile|
|
||||
use core::ops::MulAssign;
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -43,7 +43,7 @@ declareSafeScaleOperators bitsize _ =
|
||||
let sname = mkIdent ("U" ++ show bitsize)
|
||||
dname = mkIdent ("U" ++ show (bitsize + 64))
|
||||
fullRippleScale = generateScaletiplier True (bitsize `div` 64) "rhs" "res"
|
||||
testFileLit = Lit [] (Str (testFile bitsize) Cooked Unsuffixed mempty) mempty
|
||||
testFileLit = Lit [] (Str (testFile True bitsize) Cooked Unsuffixed mempty) mempty
|
||||
in [sourceFile|
|
||||
use core::ops::Mul;
|
||||
use crate::CryptoNum;
|
||||
@@ -158,7 +158,7 @@ declareUnsafeScaleOperators :: Word -> [Word] -> SourceFile Span
|
||||
declareUnsafeScaleOperators bitsize _ =
|
||||
let sname = mkIdent ("U" ++ show bitsize)
|
||||
halfRippleScale = generateScaletiplier False (bitsize `div` 64) "rhs" "self"
|
||||
testFileLit = Lit [] (Str (testFile bitsize) Cooked Unsuffixed mempty) mempty
|
||||
testFileLit = Lit [] (Str (testFile True bitsize) Cooked Unsuffixed mempty) mempty
|
||||
in [sourceFile|
|
||||
use core::ops::MulAssign;
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -35,7 +35,7 @@ declareShiftOperators bitsize _ =
|
||||
shlActualImpl = concatMap actualShlImplLines [1..entries-1]
|
||||
shrActualImpl = concatMap (actualShrImplLines entries) (reverse [0..entries-1])
|
||||
resAssign = map reassignSelf [0..entries-1]
|
||||
testFileLit = Lit [] (Str (testFile bitsize) Cooked Unsuffixed mempty) mempty
|
||||
testFileLit = Lit [] (Str (testFile True bitsize) Cooked Unsuffixed mempty) mempty
|
||||
in [sourceFile|
|
||||
#[cfg(test)]
|
||||
use core::convert::TryFrom;
|
||||
|
||||
182
generation/src/Signed.hs
Normal file
182
generation/src/Signed.hs
Normal file
@@ -0,0 +1,182 @@
|
||||
{-# LANGUAGE QuasiQuotes #-}
|
||||
module Signed(signedBaseOps)
|
||||
where
|
||||
|
||||
import File
|
||||
import Language.Rust.Data.Ident
|
||||
import Language.Rust.Data.Position
|
||||
import Language.Rust.Quote
|
||||
import Language.Rust.Syntax
|
||||
|
||||
|
||||
signedBaseOps :: File
|
||||
signedBaseOps = File {
|
||||
predicate = const (const True),
|
||||
outputName = "base",
|
||||
isUnsigned = False,
|
||||
generator = declareSigned,
|
||||
testCase = Nothing
|
||||
}
|
||||
|
||||
declareSigned :: Word -> [Word] -> SourceFile Span
|
||||
declareSigned bitsize _ =
|
||||
let sname = mkIdent ("I" ++ show bitsize)
|
||||
uname = mkIdent ("U" ++ show bitsize)
|
||||
in [sourceFile|
|
||||
use core::fmt;
|
||||
use core::ops::{Neg, Not};
|
||||
use crate::CryptoNum;
|
||||
use crate::unsigned::$$uname;
|
||||
use quickcheck::{Arbitrary,Gen};
|
||||
#[cfg(test)]
|
||||
use quickcheck::quickcheck;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct $$sname {
|
||||
contents: $$uname,
|
||||
}
|
||||
|
||||
impl Neg for $$sname {
|
||||
type Output = $$sname;
|
||||
|
||||
fn neg(mut self) -> $$sname {
|
||||
for x in self.contents.value.iter_mut() {
|
||||
*x = !*x;
|
||||
}
|
||||
let one = $$uname::from(1u64);
|
||||
self.contents += one;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Neg for &'a $$sname {
|
||||
type Output = $$sname;
|
||||
|
||||
fn neg(self) -> $$sname {
|
||||
let res = self.clone();
|
||||
res.neg()
|
||||
}
|
||||
}
|
||||
|
||||
impl Not for $$sname {
|
||||
type Output = $$sname;
|
||||
|
||||
fn not(mut self) -> $$sname {
|
||||
for x in self.contents.value.iter_mut() {
|
||||
*x = !*x;
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Not for &'a $$sname {
|
||||
type Output = $$sname;
|
||||
|
||||
fn not(self) -> $$sname {
|
||||
self.clone().not()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for $$sname {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{:?}", self.contents)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::UpperHex for $$sname {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let mut temp = self.clone();
|
||||
|
||||
if temp.contents.value[temp.contents.value.len()-1] >> 63 == 1 {
|
||||
write!(f, "-")?;
|
||||
temp = !temp;
|
||||
}
|
||||
|
||||
write!(f, "{:X}", temp.contents)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::LowerHex for $$sname {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let mut temp = self.clone();
|
||||
|
||||
if temp.contents.value[temp.contents.value.len()-1] >> 63 == 1 {
|
||||
write!(f, "-")?;
|
||||
temp = !temp;
|
||||
}
|
||||
|
||||
write!(f, "{:x}", temp.contents)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for $$sname {
|
||||
fn eq(&self, other: &$$sname) -> bool {
|
||||
let mut all_equal = true;
|
||||
|
||||
for (l, r) in self.contents.value.iter().zip(other.contents.value.iter()) {
|
||||
all_equal &= *l == *r;
|
||||
}
|
||||
|
||||
all_equal
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for $$sname { }
|
||||
|
||||
impl Arbitrary for $$sname {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> $$sname {
|
||||
$$sname{
|
||||
contents: $$uname::arbitrary(g),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CryptoNum for $$sname {
|
||||
fn zero() -> $$sname {
|
||||
$$sname{ contents: $$uname::zero() }
|
||||
}
|
||||
fn is_zero(&self) -> bool {
|
||||
self.contents.is_zero()
|
||||
}
|
||||
fn is_even(&self) -> bool {
|
||||
self.contents.is_even()
|
||||
}
|
||||
fn is_odd(&self) -> bool {
|
||||
self.contents.is_odd()
|
||||
}
|
||||
fn bit_length() -> usize {
|
||||
$$uname::bit_length()
|
||||
}
|
||||
fn mask(&mut self, len: usize) {
|
||||
self.contents.mask(len);
|
||||
}
|
||||
fn testbit(&self, bit: usize) -> bool {
|
||||
self.contents.testbit(bit)
|
||||
}
|
||||
fn from_bytes(bytes: &[u8]) -> $$sname {
|
||||
$$sname{ contents: $$uname::from_bytes(bytes) }
|
||||
}
|
||||
fn to_bytes(&self, bytes: &mut [u8]) {
|
||||
self.contents.to_bytes(bytes);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
quickcheck! {
|
||||
fn equality_reflexive(x: $$sname) -> bool {
|
||||
&x == &x
|
||||
}
|
||||
|
||||
fn equality_symmetric(x: $$sname, y: $$sname) -> bool {
|
||||
(&x == &y) == (&y == &x)
|
||||
}
|
||||
|
||||
fn double_not(x: $$sname) -> bool {
|
||||
x == !!&x
|
||||
}
|
||||
|
||||
fn double_neg(x: $$sname) -> bool {
|
||||
x == --&x
|
||||
}
|
||||
}
|
||||
|]
|
||||
@@ -43,7 +43,7 @@ declareSafeSubtractOperators bitsize _ =
|
||||
let sname = mkIdent ("U" ++ show bitsize)
|
||||
dname = mkIdent ("U" ++ show (bitsize + 64))
|
||||
fullRippleSubtract = makeRippleSubtracter True (bitsize `div` 64) "res"
|
||||
testFileLit = Lit [] (Str (testFile bitsize) Cooked Unsuffixed mempty) mempty
|
||||
testFileLit = Lit [] (Str (testFile True bitsize) Cooked Unsuffixed mempty) mempty
|
||||
in [sourceFile|
|
||||
use core::ops::Sub;
|
||||
use crate::CryptoNum;
|
||||
@@ -110,7 +110,7 @@ declareUnsafeSubtractOperators :: Word -> [Word] -> SourceFile Span
|
||||
declareUnsafeSubtractOperators bitsize _ =
|
||||
let sname = mkIdent ("U" ++ show bitsize)
|
||||
fullRippleSubtract = makeRippleSubtracter False (bitsize `div` 64) "self"
|
||||
testFileLit = Lit [] (Str (testFile bitsize) Cooked Unsuffixed mempty) mempty
|
||||
testFileLit = Lit [] (Str (testFile True bitsize) Cooked Unsuffixed mempty) mempty
|
||||
in [sourceFile|
|
||||
use core::ops::SubAssign;
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user