summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/radeon/AMDGPUGenInstrEnums.pl
blob: 7192accadfa5f045f4758196e507801ed2c51916 (plain)
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";
}