diff options
author | Jacek Blaszczynski <biosciencenow@outlook.com> | 2017-06-14 08:16:26 +0200 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2017-06-13 23:16:26 -0700 |
commit | 116a6cc7dd0ff0912251f7d1febed36460ea11cd (patch) | |
tree | f4ab85c2060b4aaa7e635c7431b22dc30b4ee95f /src/inc | |
parent | d7e2ca54816f6a8bda589fde91a5e395f0896d29 (diff) | |
download | coreclr-116a6cc7dd0ff0912251f7d1febed36460ea11cd.tar.gz coreclr-116a6cc7dd0ff0912251f7d1febed36460ea11cd.tar.bz2 coreclr-116a6cc7dd0ff0912251f7d1febed36460ea11cd.zip |
Rewrite of OpCodeGen.pl script to generate correctly IL OpCodes (#12040)
* Rewrite of OpCodeGen.pl script to generate correctly IL OpCodes related C# code: FlowControl.cs, OpCodes.cs, OpCodeTypes.cs, OperandType.cs, StackBehaviour.cs from opcode.def file
* Update OpcodeType.cs to OpCodeType.cs in System.Private.CorLib.csproj
Diffstat (limited to 'src/inc')
-rw-r--r-- | src/inc/OpCodeGen.pl | 460 |
1 files changed, 221 insertions, 239 deletions
diff --git a/src/inc/OpCodeGen.pl b/src/inc/OpCodeGen.pl index d9294519b0..c29d4976e7 100644 --- a/src/inc/OpCodeGen.pl +++ b/src/inc/OpCodeGen.pl @@ -2,7 +2,7 @@ # The .NET Foundation licenses this file to you under the MIT license. # See the LICENSE file in the project root for more information. # -# GENREFOPS.PL +# OpCodeGen.pl # # PERL script used to generate the numbering of the reference opcodes # @@ -12,6 +12,7 @@ my $ret = 0; +my %opcodeEnum; my %oneByte; my %twoByte; my %controlFlow; @@ -36,114 +37,75 @@ foreach $letter (@lowercaseAlphabet) { $upcaseAlphabet{$letter}=$j; } +$license = "// Licensed to the .NET Foundation under one or more agreements.\n"; +$license .= "// The .NET Foundation licenses this file to you under the MIT license.\n"; +$license .= "// See the LICENSE file in the project root for more information.\n\n"; + +$startHeaderComment = "/*============================================================\n**\n"; +$endHeaderComment = "**\n** THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT BY HAND!\n"; +$endHeaderComment .= "** See \$(RepoRoot)\\src\\inc\\OpCodeGen.pl for more information.**\n"; +$endHeaderComment .= "==============================================================*/\n\n"; + +$usingAndRefEmitNmsp = "using System;\n\nnamespace System.Reflection.Emit\n{\n\n"; +$obsoleteAttr = " [Obsolete(\"This API has been deprecated. http://go.microsoft.com/fwlink/?linkid=14202\")]\n"; + +# Open source file and target files + open (OPCODE, "opcode.def") or die "Couldn't open opcode.def: $!\n"; open (OUTPUT, ">OpCodes.cs") or die "Couldn't open OpCodes.cs: $!\n"; open (FCOUTPUT, ">FlowControl.cs") or die "Couldn't open FlowControl.cs: $!\n"; open (SOUTPUT, ">StackBehaviour.cs") or die "Couldn't open StackBehaviour.cs: $!\n"; open (OCOUTPUT, ">OpCodeType.cs") or die "Couldn't open OpCodeType.cs: $!\n"; -open (OPOUTPUT, ">OperandType.cs") or die "Couldn't open OprandType.cs: $!\n"; +open (OPOUTPUT, ">OperandType.cs") or die "Couldn't open OperandType.cs: $!\n"; - -print OUTPUT "/*============================================================\n"; -print OUTPUT "**\n"; -print OUTPUT "**Class: OpCodes\n"; -print OUTPUT "**\n"; -print OUTPUT "**Purpose: Exposes all of the il instructions supported by the runtime.\n"; +print OUTPUT $license; +print OUTPUT $startHeaderComment; +print OUTPUT "** Class: OpCodes\n"; print OUTPUT "**\n"; -print OUTPUT "**Licensed to the .NET Foundation under one or more agreements.\n"; -print OUTPUT "**The .NET Foundation licenses this file to you under the MIT license.\n"; -print OUTPUT "**See the LICENSE file in the project root for more information.\n"; -print OUTPUT "**\n"; -print OUTPUT "** THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT BY HAND!\n"; -print OUTPUT "** See clr\src\inc\opcodegen.pl for more information.**\n"; -print OUTPUT "============================================================*/\n"; - -print OUTPUT "namespace System.Reflection.Emit {\n\n"; -print OUTPUT "using System;\n\n";; -print OUTPUT "public class OpCodes {\n\n";; -print OUTPUT "/// <summary>\n"; -print OUTPUT "/// <para>\n"; -print OUTPUT "/// The IL instruction opcodes supported by the\n"; -print OUTPUT "/// runtime. The IL Instruction Specification describes each\n"; -print OUTPUT "/// Opcode.\n"; -print OUTPUT "/// </para>\n"; -print OUTPUT "/// </summary>\n"; -print OUTPUT "/// <seealso topic='IL Instruction Set Specification'/>\n"; -print OUTPUT "\n"; -print OUTPUT "\tprivate OpCodes() { \n\t}\n\n"; - - -print FCOUTPUT "/*============================================================\n"; -print FCOUTPUT "**\n"; -print FCOUTPUT "**Class: FlowControl\n"; -print FCOUTPUT "**\n"; -print FCOUTPUT "**Purpose: Exposes FlowControl Attribute of IL .\n"; -print FCOUTPUT "**\n"; -print FCOUTPUT "**Licensed to the .NET Foundation under one or more agreements.\n"; -print FCOUTPUT "**The .NET Foundation licenses this file to you under the MIT license.\n"; -print FCOUTPUT "**See the LICENSE file in the project root for more information.\n"; +print OUTPUT "** Purpose: Exposes all of the IL instructions supported by the runtime.\n"; +print OUTPUT $endHeaderComment; + +print OUTPUT $usingAndRefEmitNmsp; + +print FCOUTPUT $license; +print FCOUTPUT $startHeaderComment; +print FCOUTPUT "** Enumeration: FlowControl\n"; print FCOUTPUT "**\n"; -print FCOUTPUT "** THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT BY HAND!\n"; -print FCOUTPUT "** See clr\src\inc\opcodegen.pl for more information.**\n"; -print FCOUTPUT "============================================================*/\n"; +print FCOUTPUT "** Purpose: Exposes FlowControl Attribute of IL.\n"; +print FCOUTPUT $endHeaderComment; -print FCOUTPUT "namespace System.Reflection.Emit {\n\n"; -print FCOUTPUT "using System;\n\n"; -print FCOUTPUT "public enum FlowControl\n{\n\n"; +print FCOUTPUT $usingAndRefEmitNmsp; +print FCOUTPUT " public enum FlowControl\n {\n"; -print SOUTPUT "/*============================================================\n"; -print SOUTPUT "**\n"; -print SOUTPUT "**Class: StackBehaviour\n"; +print SOUTPUT $license; +print SOUTPUT $startHeaderComment; +print SOUTPUT "** Enumeration: StackBehaviour\n"; print SOUTPUT "**\n"; -print SOUTPUT "**Purpose: Exposes StackBehaviour Attribute of IL .\n"; -print SOUTPUT "**\n"; -print SOUTPUT "**Licensed to the .NET Foundation under one or more agreements.\n"; -print SOUTPUT "**The .NET Foundation licenses this file to you under the MIT license.\n"; -print SOUTPUT "**See the LICENSE file in the project root for more information.\n"; -print SOUTPUT "**\n"; -print SOUTPUT "** THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT BY HAND!\n"; -print SOUTPUT "** See clr\src\inc\opcodegen.pl for more information.**\n"; -print SOUTPUT "============================================================*/\n"; +print SOUTPUT "** Purpose: Exposes StackBehaviour Attribute of IL.\n"; +print SOUTPUT $endHeaderComment; -print SOUTPUT "namespace System.Reflection.Emit {\n\n"; -print SOUTPUT "using System;\n\n"; -print SOUTPUT "public enum StackBehaviour\n{\n\n"; +print SOUTPUT $usingAndRefEmitNmsp; +print SOUTPUT " public enum StackBehaviour\n {\n"; -print OCOUTPUT "/*============================================================\n"; -print OCOUTPUT "**\n"; -print OCOUTPUT "**Class: OpCodeType\n"; -print OCOUTPUT "**\n"; -print OCOUTPUT "**Purpose: Exposes OpCodeType Attribute of IL .\n"; +print OCOUTPUT $license; +print OCOUTPUT $startHeaderComment; +print OCOUTPUT "** Enumeration: OpCodeType\n"; print OCOUTPUT "**\n"; -print OCOUTPUT "**Licensed to the .NET Foundation under one or more agreements.\n"; -print OCOUTPUT "**The .NET Foundation licenses this file to you under the MIT license.\n"; -print OCOUTPUT "**See the LICENSE file in the project root for more information.\n"; -print OCOUTPUT "**\n"; -print OCOUTPUT "** THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT BY HAND!\n"; -print OCOUTPUT "** See clr\src\inc\opcodegen.pl for more information.**\n"; -print OCOUTPUT "============================================================*/\n"; +print OCOUTPUT "** Purpose: Exposes OpCodeType Attribute of IL.\n"; +print OCOUTPUT $endHeaderComment; -print OCOUTPUT "namespace System.Reflection.Emit {\n\n"; -print OCOUTPUT "using System;\n\n"; -print OCOUTPUT "public enum OpCodeType\n{\n\n"; +print OCOUTPUT $usingAndRefEmitNmsp; +print OCOUTPUT " public enum OpCodeType\n {\n"; -print OPOUTPUT "/*============================================================\n"; -print OPOUTPUT "**\n"; -print OPOUTPUT "**Class: OperandType\n"; -print OPOUTPUT "**\n"; -print OPOUTPUT "**Purpose: Exposes OperandType Attribute of IL .\n"; +print OPOUTPUT $license; +print OPOUTPUT $startHeaderComment; +print OPOUTPUT "** Enumeration: OperandType\n"; print OPOUTPUT "**\n"; -print OPOUTPUT "**Licensed to the .NET Foundation under one or more agreements.\n"; -print OPOUTPUT "**The .NET Foundation licenses this file to you under the MIT license.\n"; -print OPOUTPUT "**See the LICENSE file in the project root for more information.\n"; -print OPOUTPUT "**\n"; -print OPOUTPUT "** THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT BY HAND!\n"; -print OPOUTPUT "** See clr\src\inc\opcodegen.pl for more information.**\n"; -print OPOUTPUT "============================================================*/\n"; +print OPOUTPUT "** Purpose: Exposes OperandType Attribute of IL.\n"; +print OPOUTPUT $endHeaderComment; -print OPOUTPUT "namespace System.Reflection.Emit {\n\n"; -print OPOUTPUT "using System;\n\n"; -print OPOUTPUT "public enum OperandType\n{\n\n"; +print OPOUTPUT $usingAndRefEmitNmsp; +print OPOUTPUT " public enum OperandType\n {\n"; while (<OPCODE>) { @@ -152,9 +114,9 @@ while (<OPCODE>) { chop; # Strip off trailing CR s/^OPDEF\(\s*//; # Strip off "OP(" - s/\)$//; # Strip off ")" at end s/,\s*/,/g; # Remove whitespace - + s/\).*$//; # Strip off ")" and everything behind it at end + # Split the line up into its basic parts ($enumname, $stringname, $pop, $push, $operand, $type, $size, $s1, $s2, $ctrl) = split(/,/); $s1 =~ s/0x//; @@ -177,19 +139,16 @@ while (<OPCODE>) $enumname=~s/^(.)/\u$1/g; $enumname=~s/_(.)/_\u$1/g; - #Convert pop to our casing convention $pop=~tr/A-Z/a-z/; $pop=~s/^(.)/\u$1/g; $pop=~s/_(.)/_\u$1/g; - #Convert push to our casing convention $push=~tr/A-Z/a-z/; $push=~s/^(.)/\u$1/g; $push=~s/_(.)/_\u$1/g; - #Convert operand to our casing convention #$operand=~tr/A-Z/a-z/; #$operand=~s/^(.)/\u$1/g; @@ -203,39 +162,31 @@ while (<OPCODE>) $type=~s/^(.)/\u$1/g; $type=~s/_(.)/_\u$1/g; - #Convert ctrl to our casing convention $ctrl=~tr/A-Z/a-z/; $ctrl=~s/^(.)/\u$1/g; $ctrl=~s/_(.)/_\u$1/g; - - - # Make a list of the flow Control type - # Make a list of the opcodes and there values + # Make a list of the opcodes and their values if ($opcodes{$enumname}) { - } - else + elsif ($size == 1) { - if ($size == 1) - { - $opcodes{$enumname} = $s2; - } - else - { - $opcodes{$enumname} = ($s2 + 256 * $s1); - } + $opcodes{$enumname} = $s2; + } + elsif ($size == 2) + { + $opcodes{$enumname} = ($s2 + 256 * $s1); } #Make a list of the instructions which only take one-byte arguments if ($enumname =~ /^.*_S$/) { #but exclude the deprecated expressions (sometimes spelled "depricated") if (!($enumname=~/^Depr.cated.*/)) { - my $caseStatement = sprintf("\t\tcase %-20s: \n", $enumname); + my $caseStatement = sprintf(" case %-20s: \n", $enumname); push(@singleByteArg, $caseStatement); } } @@ -252,11 +203,11 @@ while (<OPCODE>) } $ctrlflowcount = 0; - #make a list of the control Flow Types + #make a list of the StackBehaviour Types $pop=~s/\+/_/g; if ($stackbehav{$pop}) { - #printf("DUPE Control Flow\n"); + #printf("DUPE stack behaviour pop\n"); } else { @@ -264,11 +215,11 @@ while (<OPCODE>) $ctrlflowcount++; } - #make a list of the control Flow Types + #make a list of the StackBehaviour Types $push=~s/\+/_/g; if ($stackbehav{$push}) { - #printf("DUPE Control Flow\n"); + #printf("DUPE stack behaviour push\n"); } else { @@ -278,7 +229,7 @@ while (<OPCODE>) #make a list of operand types if ($operandtype{$operand}) { - #printf("DUPE Control Flow\n"); + #printf("DUPE operand type\n"); } else { @@ -290,7 +241,7 @@ while (<OPCODE>) #make a list of opcode types if ($opcodetype{$type}) { - #printf("DUPE Control Flow\n"); + #printf("DUPE opcode type\n"); } else { @@ -298,58 +249,78 @@ while (<OPCODE>) $ctrlflowcount++; } - print "$enumname\n"; - print "$stringname\n"; + my $opcodeName = $enumname; + + # Tailcall OpCode enum name does not comply with convention + # that all enum names are exactly the same as names in opcode.def + # file less leading CEE_ and changed casing convention + $enumname = substr $enumname, 0, 4 unless $enumname !~ m/Tailcall$/; + + # If string name ends with dot OpCode enum name ends with underscore + $enumname .= "_" unless $stringname !~ m/\."$/; + + printf(" OpCode name:%20s,\t\tEnum label:%20s,\t\tString name:%20s\n", $opcodeName, $enumname, $stringname); if ($stringname eq "arglist") { print "This is arglist----------\n"; } - my $line = sprintf("\tpublic static readonly OpCode %-20s = ", $enumname); - if ($size == 1) - { - $line .= sprintf("new OpCode(%s, StackBehaviour.%s, StackBehaviour.%s, OperandType.%s, OpCodeType.%s, %u, (byte)0x%x, (byte)0x%x, FlowControl.%s, " , $stringname, $pop, $push, $operand, $type, $size, $s1, $s2, $ctrl); - - if ($ctrl eq "Return" || $ctrl eq "Branch" || $ctrl eq "Throw" || $stringname eq "\"jmp\"" || $stringname eq "\"jmpi\"") - { - $line .= sprintf("true, "); + my $lineEnum; + if ($size == 1) + { + $lineEnum = sprintf(" %s = 0x%.2x,\n", $enumname, $s2); + $opcodeEnum{$s2} = $lineEnum; + } + elsif ($size == 2) + { + $lineEnum = sprintf(" %s = 0x%.4x,\n", $enumname, $s2 + 256 * $s1); + $opcodeEnum{$s2 + 256 * $s1} = $lineEnum; + } - } - else - { - $line .= sprintf("false, "); - } + my $line; + $line = sprintf(" public static readonly OpCode %s = new OpCode(OpCodeValues.%s,\n", $opcodeName, $enumname); + $line .= sprintf(" ((int)OperandType.%s) |\n", $operand); + $line .= sprintf(" ((int)FlowControl.%s << OpCode.FlowControlShift) |\n", $ctrl); + $line .= sprintf(" ((int)OpCodeType.%s << OpCode.OpCodeTypeShift) |\n", $type); + $line .= sprintf(" ((int)StackBehaviour.%s << OpCode.StackBehaviourPopShift) |\n", $pop); + $line .= sprintf(" ((int)StackBehaviour.%s << OpCode.StackBehaviourPushShift) |\n", $push); - $popstate = 0; - if($pop eq "Pop0" || $pop eq "Varpop") - { - $popstate = 0; - } - elsif ($pop eq "Pop1" || $pop eq "Popi" || $pop eq "Popref") - { - $popstate = $popstate -1; - } - elsif ($pop eq "Pop1_pop1" || $pop eq "Popi_pop1" || $pop eq "Popi_popi" || $pop eq "Popi_popi8" || $pop eq "Popi_popr4" || $pop eq "Popi_popr8" || $pop eq "Popref_pop1" || $pop eq "Popref_popi") - { - $popstate = $popstate -2; - } - elsif ($pop eq "Popi_popi_popi" || $pop eq "Popref_popi_popi" || $pop eq "Popref_popi_popi8" || $pop eq "Popref_popi_popr4" || $pop eq "Popref_popi_popr8" || $pop eq "Popref_popi_popref") - { - $popstate = $popstate -3; - } + $popstate = 0; + if($pop eq "Pop0" || $pop eq "Varpop") + { + $popstate = 0; + } + elsif ($pop eq "Pop1" || $pop eq "Popi" || $pop eq "Popref") + { + $popstate = $popstate -1; + } + elsif ($pop eq "Pop1_pop1" || $pop eq "Popi_pop1" || $pop eq "Popi_popi" || $pop eq "Popi_popi8" || $pop eq "Popi_popr4" || $pop eq "Popi_popr8" || $pop eq "Popref_pop1" || $pop eq "Popref_popi") + { + $popstate = $popstate -2; + } + elsif ($pop eq "Popi_popi_popi" || $pop eq "Popref_popi_popi" || $pop eq "Popref_popi_popi8" || $pop eq "Popref_popi_popr4" || $pop eq "Popref_popi_popr8" || $pop eq "Popref_popi_popref") + { + $popstate = $popstate -3; + } - if ($push eq "Push1" || $push eq "Pushi" ||$push eq "Pushi8" ||$push eq "Pushr4" ||$push eq "Pushr8" ||$push eq "Pushref") - { - $popstate = $popstate + 1; - } - elsif($push eq "Push1_push1") - { - $popstate = $popstate + 2; - } + if ($push eq "Push1" || $push eq "Pushi" ||$push eq "Pushi8" ||$push eq "Pushr4" ||$push eq "Pushr8" ||$push eq "Pushref") + { + $popstate = $popstate + 1; + } + elsif($push eq "Push1_push1") + { + $popstate = $popstate + 2; + } + $line .= sprintf(" (%s << OpCode.SizeShift) |\n", $size); + if ($ctrl =~ m/Return/ || $ctrl =~ m/^Branch/ || $ctrl =~ m/^Throw/ || $enumname =~ m/Jmp/){ + $line .= sprintf(" OpCode.EndsUncondJmpBlkFlag |\n", $size); + } + $line .= sprintf(" (%d << OpCode.StackChangeShift)\n", $popstate); + $line .= sprintf(" );\n\n"); - $line .= sprintf(" $popstate"); - $line .= sprintf(");\n\n"); + if ($size == 1) + { if ($oneByte{$s2}) { printf("Error opcode 0x%x already defined!\n", $s2); @@ -368,103 +339,115 @@ while (<OPCODE>) print " New = $line"; $ret = -1; } - $line .= sprintf("new OpCode(%s, StackBehaviour.%s, StackBehaviour.%s, OperandType.%s, OpCodeType.%s, %u, (byte)0x%x, (byte)0x%x, FlowControl.%s, " , $stringname, $pop, $push, $operand, $type, $size, $s1, $s2, $ctrl); - - if ($ctrl eq "Return" || $ctrl eq "Branch" || $ctrl eq "Throw" || $stringname eq "\"jmp\"" || $stringname eq "\"jmpi\"") - { - $line .= sprintf("true, "); - - } - else - { - $line .= sprintf("false, "); - } - - $popstate = 0; - if($pop eq "Pop0" || $pop eq "Varpop") - { - $popstate = 0; - } - elsif($pop eq "Pop1" || $pop eq "Popi" || $pop eq "Popref") - { - $popstate = $popstate -1; - } - elsif ($pop eq "Pop1_pop1" || $pop eq "Popi_pop1" || $pop eq "Popi_popi" || $pop eq "Popi_popi8" || $pop eq "Popi_popr4" || $pop eq "Popi_popr8" || $pop eq "Popref_pop1" || $pop eq "Popref_popi") - { - $popstate = $popstate -2; - } - elsif ($pop eq "Popi_popi_popi" || $pop eq "Popref_popi_popi" || $pop eq "Popref_popi_popi8" || $pop eq "Popref_popi_popr4" || $pop eq "Popref_popi_popr8" || $pop eq "Popref_popi_popref") - { - $popstate = $popstate -3; - } - - if ($push eq "Push1" || $push eq "Pushi" ||$push eq "Pushi8" ||$push eq "Pushr4" ||$push eq "Pushr8" ||$push eq "Pushref") - { - $popstate = $popstate + 1; - } - elsif($push eq "Push1_push1") - { - $popstate = $popstate + 2; - } - - $line .= sprintf(" $popstate"); - $line .= sprintf(");\n\n"); $twoByte{$s2 + 256 * $s1} = $line; - } else { $line .= "\n"; push(@deprecated, $line); + printf("deprecated code!\n"); } $count++; - } + } } -#Write out the Flow Control class +# Generate the Flow Control enum $ctrlflowcount = 0; foreach $key (sort {$a cmp $b} keys (%controlFlow)) { - print FCOUTPUT "\t$key"; - print FCOUTPUT "\t= $ctrlflowcount,\n"; + print FCOUTPUT " $key"; + print FCOUTPUT " = $ctrlflowcount,\n"; $ctrlflowcount++; + if ($key =~ m/Next/){ + print FCOUTPUT $obsoleteAttr; + print FCOUTPUT " Phi"; + print FCOUTPUT " = $ctrlflowcount,\n"; + $ctrlflowcount++; + } } +#end the flowcontrol enum +print FCOUTPUT " }\n}\n"; -#end the flowcontrol class -print FCOUTPUT "}\n}"; - -#Write out the StackBehaviour class +# Generate the StackBehaviour enum $ctrlflowcount = 0; foreach $key (sort {$a cmp $b} keys (%stackbehav)) { - print SOUTPUT "\t$key"; - print SOUTPUT "\t= $ctrlflowcount,\n"; - $ctrlflowcount++; + if ($key !~ m/Popref_popi_pop1/){ + print SOUTPUT " $key"; + print SOUTPUT " = $ctrlflowcount,\n"; + $ctrlflowcount++; + } } -#end the StackBehaviour class -print SOUTPUT "}\n}"; +print SOUTPUT " Popref_popi_pop1 = $ctrlflowcount,\n"; +#end the StackBehaviour enum +print SOUTPUT " }\n}\n"; +# Generate OpCodeType enum $ctrlflowcount = 0; foreach $key (sort {$a cmp $b} keys (%opcodetype)) { - print OCOUTPUT "\t$key"; - print OCOUTPUT "\t= $ctrlflowcount,\n"; + if ($ctrlflowcount == 0){ + print OCOUTPUT $obsoleteAttr; + print OCOUTPUT " Annotation = 0,\n"; + $ctrlflowcount++; + } + print OCOUTPUT " $key"; + print OCOUTPUT " = $ctrlflowcount,\n"; $ctrlflowcount++; } -#end the OpCodeTYpe class -print OCOUTPUT "}\n}"; +# end the OpCodeType enum +print OCOUTPUT " }\n}\n"; +# Generate OperandType enum $ctrlflowcount = 0; foreach $key (sort {$a cmp $b} keys (%operandtype)) { - print OPOUTPUT "\t$key"; - print OPOUTPUT "\t= $ctrlflowcount,\n"; + print OPOUTPUT " $key"; + print OPOUTPUT " = $ctrlflowcount,\n"; $ctrlflowcount++; + if ($key =~ m/InlineNone/){ + print OPOUTPUT $obsoleteAttr; + print OPOUTPUT " InlinePhi = 6,\n"; + $ctrlflowcount++; + } + if ($key =~ m/^InlineR$/){ + $ctrlflowcount++; + } } -#end the OperandType class -print OPOUTPUT "}\n}"; +#end the OperandType enum +print OPOUTPUT " }\n}\n"; + +# Generate OpCodeValues internal enum +print OUTPUT " ///<summary>\n"; +print OUTPUT " /// Internal enum OpCodeValues for opcode values.\n"; +print OUTPUT " ///</summary>\n"; +print OUTPUT " ///<remarks>\n"; +print OUTPUT " /// Note that the value names are used to construct publicly visible\n"; +print OUTPUT " /// ilasm-compatible opcode names, so their exact form is important!\n"; +print OUTPUT " ///</remarks>\n"; +print OUTPUT " internal enum OpCodeValues\n"; +print OUTPUT " {\n"; + +foreach $opcodeValue (sort {$a <=> $b} keys(%opcodeEnum)) { + print OUTPUT $opcodeEnum{$opcodeValue}; +} + +# End generating OpCodeValues internal enum +print OUTPUT " }\n\n"; + +# Generate public OpCodes class +print OUTPUT " /// <summary>\n"; +print OUTPUT " /// <para>\n"; +print OUTPUT " /// The IL instruction opcodes supported by the runtime.\n"; +print OUTPUT " /// The Specification of IL Instruction describes each Opcode.\n"; +print OUTPUT " /// </para>\n"; +print OUTPUT " /// </summary>\n"; +print OUTPUT " /// <seealso topic='IL Instruction Set Specification'/>\n"; +print OUTPUT " public class OpCodes\n"; +print OUTPUT " {\n\n";; +print OUTPUT " private OpCodes()\n {\n }\n\n"; my $opcode; my $lastOp = -1; @@ -481,21 +464,20 @@ foreach $opcode (sort {$a <=> $b} keys(%twoByte)) { $lastOp = $opcode; } +print OUTPUT "\n";; +print OUTPUT " public static bool TakesSingleByteArgument(OpCode inst)\n"; +print OUTPUT " {\n"; +print OUTPUT " switch (inst.OperandType)\n"; +print OUTPUT " {\n"; +print OUTPUT " case OperandType.ShortInlineBrTarget:\n"; +print OUTPUT " case OperandType.ShortInlineI:\n"; +print OUTPUT " case OperandType.ShortInlineVar:\n"; +print OUTPUT " return true;\n"; +print OUTPUT " };\n"; +print OUTPUT " return false;\n"; +print OUTPUT " }\n"; + +# End Generate public OpCodes class and close namespace +print OUTPUT " }\n}\n"; - - - -print OUTPUT "\n\n\tpublic static bool TakesSingleByteArgument(OpCode inst)\n\t{\n"; -print OUTPUT"\t\tswitch(inst.m_operand)\n\t\t{\n"; -print OUTPUT "\t\t\tcase OperandType.ShortInlineBrTarget :\n"; -print OUTPUT "\t\t\tcase OperandType.ShortInlineI :\n"; -print OUTPUT "\t\t\tcase OperandType.ShortInlineVar :\n"; -print OUTPUT "\t\t\treturn true;\n"; -print OUTPUT "\t\t};\n"; -print OUTPUT "\t\treturn false;\n"; -print OUTPUT "\t}\n"; -print OUTPUT "}\n}"; exit($ret); - - - |