17c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin# Copyright (C) 2014 The Android Open Source Project
27c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin#
37c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin# Licensed under the Apache License, Version 2.0 (the "License");
47c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin# you may not use this file except in compliance with the License.
57c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin# You may obtain a copy of the License at
67c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin#
77c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin#      http://www.apache.org/licenses/LICENSE-2.0
87c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin#
97c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin# Unless required by applicable law or agreed to in writing, software
107c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin# distributed under the License is distributed on an "AS IS" BASIS,
117c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin# See the License for the specific language governing permissions and
137c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin# limitations under the License.
147c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin
15c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xuupper_bound_int_pow2 = 31
1668f6289fbc1b14ed814722c023b3f343c1e59a79Nicolas Geoffrayupper_bound_int_pow2_neg = 32
17c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xuupper_bound_long_pow2 = 63
1868f6289fbc1b14ed814722c023b3f343c1e59a79Nicolas Geoffrayupper_bound_long_pow2_neg = 64
19c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xuupper_bound_constant = 100
207c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchinall_tests = [
217c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin    ({'@INT@': 'int', '@SUFFIX@':''},
22c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu     [('CheckDiv', 'idiv_by_pow2_', [2**i for i in range(upper_bound_int_pow2)]),
2368f6289fbc1b14ed814722c023b3f343c1e59a79Nicolas Geoffray      ('CheckDiv', 'idiv_by_pow2_neg_', [-2**i for i in range(upper_bound_int_pow2_neg)]),
24c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu      ('CheckDiv', 'idiv_by_constant_', [i for i in range(1, upper_bound_constant)]),
25c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu      ('CheckDiv', 'idiv_by_constant_neg_', [-i for i in range(1, upper_bound_constant)]),
26c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu      ('CheckRem', 'irem_by_pow2_', [2**i for i in range(upper_bound_int_pow2)]),
2768f6289fbc1b14ed814722c023b3f343c1e59a79Nicolas Geoffray      ('CheckRem', 'irem_by_pow2_neg_', [-2**i for i in range(upper_bound_int_pow2_neg)]),
28c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu      ('CheckRem', 'irem_by_constant_', [i for i in range(1, upper_bound_constant)]),
29c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu      ('CheckRem', 'irem_by_constant_neg_', [-i for i in range(1, upper_bound_constant)])]),
307c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin    ({'@INT@': 'long', '@SUFFIX@': 'l'},
31c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu     [('CheckDiv', 'ldiv_by_pow2_', [2**i for i in range(upper_bound_long_pow2)]),
3268f6289fbc1b14ed814722c023b3f343c1e59a79Nicolas Geoffray      ('CheckDiv', 'ldiv_by_pow2_neg_', [-2**i for i in range(upper_bound_long_pow2_neg)]),
33c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu      ('CheckDiv', 'ldiv_by_constant_', [i for i in range(1, upper_bound_constant)]),
34c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu      ('CheckDiv', 'ldiv_by_constant_neg_', [-i for i in range(1, upper_bound_constant)]),
35c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu      ('CheckRem', 'lrem_by_pow2_', [2**i for i in range(upper_bound_long_pow2)]),
3668f6289fbc1b14ed814722c023b3f343c1e59a79Nicolas Geoffray      ('CheckRem', 'lrem_by_pow2_neg_', [-2**i for i in range(upper_bound_long_pow2_neg)]),
37c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu      ('CheckRem', 'lrem_by_constant_', [i for i in range(1, upper_bound_constant)]),
38c66671076b12a0ee8b9d1ae782732cc91beacb73Zheng Xu      ('CheckRem', 'lrem_by_constant_neg_', [-i for i in range(1, upper_bound_constant)])])
397c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin]
407c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin
417c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchindef subst_vars(variables, text):
427c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin    '''Substitute variables in text.'''
437c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin    for key, value in variables.iteritems():
447c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin        text = text.replace(str(key), str(value))
457c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin    return text
467c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin
477c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin# Generate all the function bodies (in decls) and all the function calls (in calls).
487c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchindecls, calls = '', {}
497c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchinfor default_vars, tests in all_tests:
507c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin    local_vars = default_vars.copy()
517c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin    int_type = local_vars['@INT@']
527c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin    for checker, name, values in tests:
537c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin        local_vars['@CHECKER@'] = checker
547c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin        for i, value in enumerate(values):
557c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin            local_vars['@NAME@'] = name + str(i)
567c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin            local_vars['@VALUE@'] = value
577c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin            local_vars['@OP@'] = '/' if 'div' in name else '%'
587c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin
597c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin            # Function body.
607c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin            decls += subst_vars(local_vars, '''
617c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin    public static @INT@ @NAME@(@INT@ x) {return x @OP@ @VALUE@@SUFFIX@;}''')
627c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin
637c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin            # Function call and test.
647c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin            calls[int_type] = calls.get(int_type, '') + subst_vars(local_vars, '''
657c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin        @INT@@CHECKER@("@NAME@", @NAME@(x), x, @VALUE@@SUFFIX@);''')
667c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin
677c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin# Generate the checkers.
687c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchincheckers = ''
697c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchinlocal_vars = {}
707c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchinfor int_type in ('int', 'long'):
717c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin    local_vars['@INT@'] = int_type
727c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin    for op, op_name in (('/', 'Div'), ('%', 'Rem')):
737c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin        local_vars['@OP@'] = op
747c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin        local_vars['@OP_NAME@'] = op_name
757c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin        checkers += subst_vars(local_vars, '''
767c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin    public static void @INT@Check@OP_NAME@(String desc, @INT@ result, @INT@ dividend, @INT@ divisor) {
777c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin        @INT@ correct_result = dividend @OP@ divisor;
787c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin        if (result != correct_result) {
797c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin            reportError(desc + "(" + dividend + ") == " + result +
807c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin                        " should be " + correct_result);
817c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin        }
827c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin    }''')
837c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin
847c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin
857c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchincode = \
867c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin'''/*
877c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin * Copyright (C) 2014 The Android Open Source Project
887c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin *
897c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin * Licensed under the Apache License, Version 2.0 (the "License");
907c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin * you may not use this file except in compliance with the License.
917c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin * You may obtain a copy of the License at
927c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin *
937c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin *      http://www.apache.org/licenses/LICENSE-2.0
947c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin *
957c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin * Unless required by applicable law or agreed to in writing, software
967c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin * distributed under the License is distributed on an "AS IS" BASIS,
977c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
987c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin * See the License for the specific language governing permissions and
997c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin * limitations under the License.
1007c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin */
1017c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin
1027c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchinpublic class Main {
1037c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin    public static int num_errors = 0;
1047c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin
1057c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin    public static void reportError(String message) {
1067c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin        if (num_errors == 10) {
1077c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin            System.out.println("Omitting other error messages...");
1087c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin        } else if (num_errors < 10) {
1097c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin            System.out.println(message);
1107c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin        }
1117c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin        num_errors += 1;
1127c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin    }
1137c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin%s
1147c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin%s
1157c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin
1167c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin    public static void intCheckAll(int x) {%s
1177c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin    }
1187c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin
1197c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin    public static void longCheckAll(long x) {%s
1207c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin    }
1217c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin
1227c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin    public static void main(String[] args) {
1237c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin      int i;
1247c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin      long l;
1257c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin
1267c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin      System.out.println("Begin");
1277c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin
1287c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin      System.out.println("Int: checking some equally spaced dividends...");
1297c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin      for (i = -1000; i < 1000; i += 300) {
1307c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin          intCheckAll(i);
1317c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin          intCheckAll(-i);
1327c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin      }
1337c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin
1347c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin      System.out.println("Int: checking small dividends...");
1357c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin      for (i = 1; i < 100; i += 1) {
1367c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin          intCheckAll(i);
1377c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin          intCheckAll(-i);
1387c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin      }
1397c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin
1407c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin      System.out.println("Int: checking big dividends...");
1417c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin      for (i = 0; i < 100; i += 1) {
1427c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin          intCheckAll(Integer.MAX_VALUE - i);
1437c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin          intCheckAll(Integer.MIN_VALUE + i);
1447c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin      }
1457c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin
1467c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin      System.out.println("Long: checking some equally spaced dividends...");
1477c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin      for (l = 0l; l < 1000000000000l; l += 300000000000l) {
1487c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin          longCheckAll(l);
1497c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin          longCheckAll(-l);
1507c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin      }
1517c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin
1527c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin      System.out.println("Long: checking small dividends...");
1537c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin      for (l = 1l; l < 100l; l += 1l) {
1547c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin          longCheckAll(l);
1557c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin          longCheckAll(-l);
1567c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin      }
1577c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin
1587c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin      System.out.println("Long: checking big dividends...");
1597c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin      for (l = 0l; l < 100l; l += 1l) {
1607c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin          longCheckAll(Long.MAX_VALUE - l);
1617c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin          longCheckAll(Long.MIN_VALUE + l);
1627c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin      }
1637c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin
1647c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin      System.out.println("End");
1657c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin    }
1667c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin}
1677c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin''' % (checkers, decls, calls['int'], calls['long'])
1687c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin
1697c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchinwith open('src/Main.java', 'w') as f:
1707c6c2ac4252ac31b42967e0f0233e8d32c5b5abeMatteo Franchin    f.write(code)
171