Path: blob/master/debugtools/DDR_VM/binary_operation_investigation/generate_test_suite.pl
6000 views
#!/usr/bin/perl12# Copyright (c) 2009, 2017 IBM Corp. and others3#4# This program and the accompanying materials are made available under5# the terms of the Eclipse Public License 2.0 which accompanies this6# distribution and is available at https://www.eclipse.org/legal/epl-2.0/7# or the Apache License, Version 2.0 which accompanies this distribution and8# is available at https://www.apache.org/licenses/LICENSE-2.0.9#10# This Source Code may also be made available under the following11# Secondary Licenses when the conditions for such availability set12# forth in the Eclipse Public License, v. 2.0 are satisfied: GNU13# General Public License, version 2 with the GNU Classpath14# Exception [1] and GNU General Public License, version 2 with the15# OpenJDK Assembly Exception [2].16#17# [1] https://www.gnu.org/software/classpath/license.html18# [2] http://openjdk.java.net/legal/assembly-exception.html19#20# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception2122# Script to build a C testcase for generating test cases for scalar types2324# Usage: perl generate_test_suite.pl <name of cpp file to generate>2526# Andrew Hall2728use strict;29use warnings;3031my $output_file = shift;3233die "You didn't specify an output file" unless defined $output_file;3435open(my $out,'>',$output_file) or die "Couldn't open $output_file: $!";3637#Operations to generate data for38my @ops = ({op=>'add',operator=>'+'}, {op=>'sub',operator=>'-'});3940my @bitwise_ops = ({op=>'bitAnd',operator=>'&'}, {op=>'bitOr',operator=>'|'});4142#Types to generate data for43my @types = qw{U_8 U_16 U_32 U_64 I_8 I_16 I_32 I_64 UDATA IDATA};4445#Conversion table. Equivalent of the HTML table produced by the prettify script46#Tells us what format to expect all the output in47my %type_conversion_table = (U_8 => {U_8=>'U_8',48U_16=>'I_32',49U_32=>'U_32',50U_64=>'U_64',51I_8=>'I_32',52I_16=>'I_32',53I_32=>'I_32',54I_64=>'I_64',55UDATA=>'UDATA',56IDATA=>'IDATA'57},5859U_16=>{U_8=>'I_32',60U_16=>'U_16',61U_32=>'U_32',62U_64=>'U_64',63I_8=>'I_32',64I_16=>'I_32',65I_32=>'I_32',66I_64=>'I_64',67UDATA=>'UDATA',68IDATA=>'IDATA'69},7071U_32=>{U_8=>'U_32',72U_16=>'U_32',73U_32=>'U_32',74U_64=>'U_64',75I_8=>'U_32',76I_16=>'U_32',77I_32=>'U_32',78I_64=>'I_64',79UDATA=>'UDATA',80IDATA=>'IDATA'81},8283U_64=>{U_8=>'U_64',84U_16=>'U_64',85U_32=>'U_64',86U_64=>'U_64',87I_8=>'U_64',88I_16=>'U_64',89I_32=>'U_64',90I_64=>'U_64',91UDATA=>'U_64',92IDATA=>'ERROR'93},9495I_8=>{U_8=>'I_32',96U_16=>'I_32',97U_32=>'U_32',98U_64=>'U_64',99I_8=>'I_32',100I_16=>'I_32',101I_32=>'I_32',102I_64=>'I_64',103UDATA=>'UDATA',104IDATA=>'IDATA'105},106107I_16=>{U_8=>'I_32',108U_16=>'I_32',109U_32=>'U_32',110U_64=>'U_64',111I_8=>'I_32',112I_16=>'I_16',113I_32=>'I_32',114I_64=>'I_64',115UDATA=>'UDATA',116IDATA=>'IDATA'117},118119I_32=>{U_8=>'I_32',120U_16=>'I_32',121U_32=>'U_32',122U_64=>'U_64',123I_8=>'I_32',124I_16=>'I_32',125I_32=>'I_32',126I_64=>'I_64',127UDATA=>'UDATA',128IDATA=>'IDATA'129},130131I_64=>{U_8=>'I_64',132U_16=>'I_64',133U_32=>'I_64',134U_64=>'U_64',135I_8=>'I_64',136I_16=>'I_64',137I_32=>'I_64',138I_64=>'I_64',139UDATA=>'ERROR',140IDATA=>'I_64'141},142143UDATA=>{U_8=>'UDATA',144U_16=>'UDATA',145U_32=>'UDATA',146U_64=>'U_64',147I_8=>'UDATA',148I_16=>'UDATA',149I_32=>'UDATA',150I_64=>'ERROR',151UDATA=>'UDATA',152IDATA=>'UDATA'153},154155IDATA=>{U_8=>'IDATA',156U_16=>'IDATA',157U_32=>'IDATA',158U_64=>'ERROR',159I_8=>'IDATA',160I_16=>'IDATA',161I_32=>'IDATA',162I_64=>'I_64',163UDATA=>'UDATA',164IDATA=>'IDATA'165},);166167#List of generated functions (called by main at the end)168my @function_list;169170generate_file_header();171172generate_arithmetic_functions();173174generate_bitwise_functions();175176generate_equals_functions();177178generate_main_function();179180close($out);181182exit;183184sub generate_bitwise_functions185{186foreach my $type (@types) {187188foreach my $operation (@bitwise_ops) {189my $op_name = $operation->{op};190my $operator = $operation->{operator};191my $function_name = "test${op_name}${type}";192push @function_list, $function_name;193194generate_type_function_header ($out,$function_name);195my $base_var = generate_locals ($out,$type);196generate_post_local_header($out,$type,$op_name);197198foreach my $second_arg_type (@types) {199200print $out <<END;201202cout << "SUBSECTION $type WITH $second_arg_type" << endl;203END204205my $var_1 = $base_var;206my $var_2 = lc $second_arg_type;207my $expected_type = $type_conversion_table{$type}->{$second_arg_type};208die "No expected type for $type, $second_arg_type" unless defined $expected_type;209210if ($expected_type eq 'ERROR') {211print $out <<END;212213cout << "INVALID: $type,$op_name,$second_arg_type" << endl;214215END216next;217}218219my $bitpattern1a = get_pattern_1a($type);220my $bitpattern1b = get_pattern_1b($second_arg_type);221222#Test max+1223print $out <<END;224$var_1 = $bitpattern1a;225$var_2 = $bitpattern1b;226END227write_testcase_output_line($out,$type,$var_1,$second_arg_type,$var_2,$expected_type,$op_name,$operator);228229my $bitpattern2a = get_pattern_2a($type);230my $bitpattern2b = get_pattern_2b($second_arg_type);231232#Test max+1233print $out <<END;234$var_1 = $bitpattern2a;235$var_2 = $bitpattern2b;236END237write_testcase_output_line($out,$type,$var_1,$second_arg_type,$var_2,$expected_type,$op_name,$operator);238}239240generate_type_function_footer($out);241}242}243}244245sub generate_equals_functions246{247foreach my $type (@types) {248249my $op_name = "equals";250my $operator = "==";251my $function_name = "test${op_name}${type}";252push @function_list, $function_name;253254generate_type_function_header ($out,$function_name);255my $base_var = generate_locals ($out,$type);256generate_post_local_header($out,$type,$op_name);257258foreach my $second_arg_type (@types) {259print $out <<END;260cout << "SUBSECTION $type WITH $second_arg_type" << endl;261END262263my $var_1 = $base_var;264my $var_2 = lc $second_arg_type;265my $expected_type = $type_conversion_table{$type}->{$second_arg_type};266die "No expected type for $type, $second_arg_type" unless defined $expected_type;267268if ($expected_type eq 'ERROR') {269print $out <<END;270271cout << "INVALID: $type,$op_name,$second_arg_type" << endl;272273END274next;275}276277$expected_type = 'bool';278279#Test 0=0280print $out <<END;281$var_1 = 0;282$var_2 = 0;283END284285write_testcase_output_line($out,$type,$var_1,$second_arg_type,$var_2,$expected_type,$op_name,$operator);286287if ( isSigned($type) && isSigned($second_arg_type) ) {288#Try min, max and -1289290print $out <<END;291$var_1 = -1;292$var_2 = -1;293END294write_testcase_output_line($out,$type,$var_1,$second_arg_type,$var_2,$expected_type,$op_name,$operator);295296my $min = (getWidth($type) > getWidth($second_arg_type)) ? getMin($second_arg_type) : getMin($type);297my $max = (getWidth($type) > getWidth($second_arg_type)) ? getMax($second_arg_type) : getMax($type);298299print $out <<END;300$var_1 = $min;301$var_2 = $min;302END303write_testcase_output_line($out,$type,$var_1,$second_arg_type,$var_2,$expected_type,$op_name,$operator);304305print $out <<END;306$var_1 = $min - 1;307$var_2 = $min - 1;308END309write_testcase_output_line($out,$type,$var_1,$second_arg_type,$var_2,$expected_type,$op_name,$operator);310311print $out <<END;312$var_1 = $max;313$var_2 = $max;314END315write_testcase_output_line($out,$type,$var_1,$second_arg_type,$var_2,$expected_type,$op_name,$operator);316317print $out <<END;318$var_1 = $max + 1;319$var_2 = $max + 1;320END321write_testcase_output_line($out,$type,$var_1,$second_arg_type,$var_2,$expected_type,$op_name,$operator);322323} elsif ( !isSigned($type) && isSigned($second_arg_type) ) {324#Test -1 vs. MAX325my $max = getMax($type);326327print $out <<END;328$var_1 = $max;329$var_2 = -1;330END331write_testcase_output_line($out,$type,$var_1,$second_arg_type,$var_2,$expected_type,$op_name,$operator);332333print $out <<END;334$var_1 = $max + 1;335$var_2 = -1;336END337write_testcase_output_line($out,$type,$var_1,$second_arg_type,$var_2,$expected_type,$op_name,$operator);338339} elsif ( isSigned($type) && !isSigned($second_arg_type) ) {340#Test -1 vs. MAX341my $max = getMax($second_arg_type);342343print $out <<END;344$var_1 = -1;345$var_2 = $max;346END347write_testcase_output_line($out,$type,$var_1,$second_arg_type,$var_2,$expected_type,$op_name,$operator);348349print $out <<END;350$var_1 = -1;351$var_2 = $max + 1;352END353write_testcase_output_line($out,$type,$var_1,$second_arg_type,$var_2,$expected_type,$op_name,$operator);354355} else {356my $min = (getWidth($type) > getWidth($second_arg_type)) ? getMin($second_arg_type) : getMin($type);357my $max = (getWidth($type) > getWidth($second_arg_type)) ? getMax($second_arg_type) : getMax($type);358359print $out <<END;360$var_1 = $max;361$var_2 = $max;362END363write_testcase_output_line($out,$type,$var_1,$second_arg_type,$var_2,$expected_type,$op_name,$operator);364365print $out <<END;366$var_1 = $max + 1;367$var_2 = $max + 1;368END369write_testcase_output_line($out,$type,$var_1,$second_arg_type,$var_2,$expected_type,$op_name,$operator);370371}372373#Generate some bit patterns to trigger funny sign extensions etc.374my $bit_pattern1 = (getWidth($type) > getWidth($second_arg_type)) ? get_pattern_1a($second_arg_type) : get_pattern_1a($type);375my $bit_pattern2 = (getWidth($type) > getWidth($second_arg_type)) ? get_pattern_1b($second_arg_type) : get_pattern_1b($type);376my $bit_pattern3 = (getWidth($type) > getWidth($second_arg_type)) ? get_pattern_2a($second_arg_type) : get_pattern_2a($type);377my $bit_pattern4 = (getWidth($type) > getWidth($second_arg_type)) ? get_pattern_2b($second_arg_type) : get_pattern_2b($type);378379print $out <<END;380$var_1 = $bit_pattern1;381$var_2 = $bit_pattern1;382END383write_testcase_output_line($out,$type,$var_1,$second_arg_type,$var_2,$expected_type,$op_name,$operator);384385print $out <<END;386$var_1 = $bit_pattern2;387$var_2 = $bit_pattern2;388END389write_testcase_output_line($out,$type,$var_1,$second_arg_type,$var_2,$expected_type,$op_name,$operator);390391print $out <<END;392$var_1 = $bit_pattern3;393$var_2 = $bit_pattern3;394END395write_testcase_output_line($out,$type,$var_1,$second_arg_type,$var_2,$expected_type,$op_name,$operator);396397print $out <<END;398$var_1 = $bit_pattern4;399$var_2 = $bit_pattern4;400END401write_testcase_output_line($out,$type,$var_1,$second_arg_type,$var_2,$expected_type,$op_name,$operator);402403}404generate_type_function_footer($out);405}406}407408409sub get_pattern_1a410{411my $type = shift;412413my $width = getWidth($type);414415$width /= 8;416417return '0x'.('AA'x$width);418}419420sub get_pattern_1b421{422my $type = shift;423424my $width = getWidth($type);425426$width /= 8;427428return '0x'.('55'x$width);429}430431sub get_pattern_2a432{433my $type = shift;434return get_pattern_1a($type);435}436437sub get_pattern_2b438{439my $type = shift;440441my $width = getWidth($type);442443$width /= 8;444445return '0x'.('A5'x$width);446}447448sub generate_arithmetic_functions449{450foreach my $type (@types) {451452foreach my $operation (@ops) {453my $op_name = $operation->{op};454my $operator = $operation->{operator};455my $function_name = "test${op_name}${type}";456push @function_list, $function_name;457458generate_type_function_header ($out,$function_name);459my $base_var = generate_locals ($out,$type);460generate_post_local_header($out,$type,$op_name);461462foreach my $second_arg_type (@types) {463464print $out <<END;465466cout << "SUBSECTION $type WITH $second_arg_type" << endl;467END468469#Generate 0 + 1 and 0 + 2 operations470my $var_1 = $base_var;471my $var_2 = lc $second_arg_type;472my $expected_type = $type_conversion_table{$type}->{$second_arg_type};473die "No expected type for $type, $second_arg_type" unless defined $expected_type;474475if ($expected_type eq 'ERROR') {476print $out <<END;477478cout << "INVALID: $type,$op_name,$second_arg_type" << endl;479480END481next;482}483484#Test 0+0485print $out <<END;486$var_1 = 0;487$var_2 = 0;488END489write_testcase_output_line($out,$type,$var_1,$second_arg_type,$var_2,$expected_type,$op_name,$operator);490491#Test 0+1492493print $out <<END;494$var_1 = 0;495$var_2 = 1;496END497write_testcase_output_line($out,$type,$var_1,$second_arg_type,$var_2,$expected_type,$op_name,$operator);498499#Test 0+2500print $out <<END;501$var_1 = 0;502$var_2 = 2;503END504write_testcase_output_line($out,$type,$var_1,$second_arg_type,$var_2,$expected_type,$op_name,$operator);505506#For signed secondary types, try 0 + -1507508if (isSigned($second_arg_type)) {509print $out <<END;510$var_1 = 0;511$var_2 = -1;512END513write_testcase_output_line($out,$type,$var_1,$second_arg_type,$var_2,$expected_type,$op_name,$operator);514}515516my $min = getMin($type);517my $max = getMax($type);518519if ($min ne '0') {520#Test min+1521print $out <<END;522$var_1 = $min;523$var_2 = 1;524END525write_testcase_output_line($out,$type,$var_1,$second_arg_type,$var_2,$expected_type,$op_name,$operator);526527if (isSigned($second_arg_type)) {528#Test min-1529print $out <<END;530$var_1 = $min;531$var_2 = -1;532END533write_testcase_output_line($out,$type,$var_1,$second_arg_type,$var_2,$expected_type,$op_name,$operator);534}535}536537538#Test max+1539print $out <<END;540$var_1 = $max;541$var_2 = 1;542END543write_testcase_output_line($out,$type,$var_1,$second_arg_type,$var_2,$expected_type,$op_name,$operator);544545if (isSigned($second_arg_type)) {546#Test max-1547print $out <<END;548$var_1 = $max;549$var_2 = -1;550END551write_testcase_output_line($out,$type,$var_1,$second_arg_type,$var_2,$expected_type,$op_name,$operator);552}553554}555556generate_type_function_footer($out);557}558}559}560561sub isSigned562{563my $type = shift;564565my $firstChar = substr($type,0,1);566567return (lc $firstChar) eq 'i';568}569570sub getWidth571{572my $type = shift;573574if ($type =~ /[UI]_(\d+)/) {575return $1;576} elsif (substr($type,1,4) eq 'DATA') {577#TODO THINK ABOUT TREATING UDATA AS 32 BIT578return 32;579} else {580die "Unknown type $type";581}582}583584sub getMax585{586my $type = shift;587588if (isSigned($type)) {589my $width = getWidth($type);590591$width /= 8;592593return "0x7f".('ff'x($width-1));594} else {595my $width = getWidth($type);596return "0x".('ff'x($width/8));597}598}599600sub getMin601{602my $type = shift;603604if (isSigned($type)) {605my $width = getWidth($type);606607$width /= 8;608609return "0x80".('00'x($width-1));610} else {611return "0";612}613}614615sub protect_chars616{617my ($type,$var) = @_;618619if ($type eq 'U_8') {620return "(unsigned int)$var";621} elsif ($type eq 'I_8') {622return "(int)$var";623} else {624return $var;625}626}627628sub write_testcase_output_line629{630my ($out,$type_1,$var_1,$type_2,$var_2,$expected_type,$op_name,$operator) = @_;631632# When printing the values for chars, they have to be converted to a numeric type so they will print as integers633my $print_var_1 = protect_chars($type_1,$var_1);634my $print_var_2 = protect_chars($type_2,$var_2);635my $print_result1 = protect_chars($expected_type,"result1");636my $print_result2 = protect_chars($expected_type,"result2");637638print $out <<"END";639{640$expected_type result1 = $var_1 $operator $var_2;641$expected_type result2 = $var_2 $operator $var_1;642cout << "$type_1," << hex << $print_var_1 << ",$op_name,$type_2," << hex << $print_var_2 << ",$expected_type," << hex << $print_result1 << "," << hex << $print_result2 << endl;643}644END645}646647sub generate_locals {648my $out = shift;649my $type = shift;650651print $out <<END;652$type base;653END654655#Generate an automatic variable for each type656foreach my $local_type (@types) {657my $var_name = lc $local_type;658print $out <<END;659$local_type $var_name;660END661}662663return "base";664}665666667sub generate_type_function_header {668my $out = shift;669my $function_name = shift;670671print $out <<END;672673static void $function_name(void)674{675//Locals676END677678}679680sub generate_type_function_footer {681my $out = shift;682683#Footer of function684print $out <<END;685686}687END688}689690sub generate_post_local_header {691my $out = shift;692my $type = shift;693my $op = shift;694695print $out <<END;696697cout << "START SECTION $type $op" << endl;698END699}700701702sub generate_main_function703{704705# Header of main function706print $out <<END;707708int main(int argc, char * argv[])709{710END711712#Call each function in turn713foreach my $function (@function_list) {714print $out <<"END"715716${function}();717718END719720}721722#Footer of main method723print $out <<END;724725return 0;726}727728END729730}731732733734sub generate_file_header735{736# Print the header737print $out <<END;738739/* Automatically generated by generate_test_suit.pl. */740741/* DO NOT MODIFY THIS GENERATED FILE. CHANGE THE generate_test_suite.pl SCRIPT INSTEAD */742743#include <iostream>744745#include "j9_types.hpp"746747using namespace std;748749END750751}752753754755756