1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
#===-- AMDGPUGenInstrEnums.pl - Script for generating instruction enums ----===#
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
#===-----------------------------------------------------------------------===#
#
# This perl script is used to generate the following files:
#
# 1. perl AMDGPUGenInstrEnums.pl td > AMDGPUInstrEnums.td
#
# This file contains Tablegen constants used for matching hw instructions
# from R600 and SI with functionally similar AMDIL instruction. It aslo
# contains definitions of floating point constants like pi (in hex notation)
# that are used in some of the shader patterns.
#
# 2. perl AMDGPUGenInstrEnums.pl h > AMDGPUInstrEnums.h
#
# This file contains cpp enums that match the constant values in
# AMDGPUInstrEnums.td
#
# 3. perl AMDGPUGenInstrEnums.pl inc > AMDGPUInstrEnums.include
#
# This file contains a function called GetRealAMDILOpcode which maps the
# constant values defined in AMDGPUInstrEnums.h to the corresponding AMDIL
# instructions.
#===-----------------------------------------------------------------------===#
use warnings;
use strict;
my @GENERATION_ENUM = qw {
R600_CAYMAN
R600
EG
EG_CAYMAN
CAYMAN
SI
};
my $FILE_TYPE = $ARGV[0];
open AMDIL, '<', 'AMDILInstructions.td';
my @INST_ENUMS = ('NONE', 'FEQ', 'FGE', 'FLT', 'FNE', 'MOVE_f32', 'MOVE_i32', 'UGT', 'IGE', 'INE', 'UGE', 'IEQ', 'SMULHI_i32', 'SMUL_i32', 'LOG_f32', 'RSQ_f32', 'SIN_f32', 'COS_f32');
while (<AMDIL>) {
if ($_ =~ /defm\s+([A-Z_]+)\s+:\s+([A-Za-z0-9]+)</) {
} elsif ($_ =~ /def\s+([A-Z_]+)(_[fi]32)/) {
push @INST_ENUMS, "$1$2";
}
}
if ($FILE_TYPE eq 'td') {
print_td_enum('AMDILInst', 'AMDILInstEnums', 'field bits<16>', @INST_ENUMS);
print_td_enum('AMDGPUGen', 'AMDGPUGenEnums', 'field bits<3>', @GENERATION_ENUM);
my %constants = (
'PI' => '0x40490fdb',
'TWO_PI' => '0x40c90fdb',
'TWO_PI_INV' => '0x3e22f983'
);
print "class Constants {\n";
foreach (keys(%constants)) {
print "int $_ = $constants{$_};\n";
}
print "}\n";
print "def CONST : Constants;\n";
} elsif ($FILE_TYPE eq 'h') {
print "unsigned GetRealAMDILOpcode(unsigned internalOpcode) const;\n";
print_h_enum('AMDILTblgenOpcode', @INST_ENUMS);
print_h_enum('AMDGPUGen', @GENERATION_ENUM);
} elsif ($FILE_TYPE eq 'inc') {
print "unsigned AMDGPUInstrInfo::GetRealAMDILOpcode(unsigned internalOpcode) const\n{\n";
print " switch(internalOpcode) {\n";
#Start at 1 so we skip NONE
for (my $i = 1; $i < scalar(@INST_ENUMS); $i++) {
my $inst = $INST_ENUMS[$i];
print " case AMDGPUInstrInfo::$inst: return AMDIL::$inst;\n";
}
print " default: abort();\n";
print " }\n}\n";
}
sub print_td_enum {
my ($instance, $class, $field, @values) = @_;
print "class $class {\n";
for (my $i = 0; $i < scalar(@values); $i++) {
print " $field $values[$i] = $i;\n";
}
print "}\n";
print "def $instance : $class;\n";
}
sub print_h_enum {
my ($enum, @list) = @_;
print "enum $enum {\n";
for (my $i = 0; $i < scalar(@list); $i++) {
print " $list[$i] = $i";
if ($i != $#list) {
print ',';
}
print "\n";
}
print "};\n";
}
|