1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 namespace System.Reflection.Metadata 6 { 7 public static partial class ILOpCodeExtensions 8 { 9 /// <summary> 10 /// Returns true of the specified op-code is a branch to a label. 11 /// </summary> IsBranch(this ILOpCode opCode)12 public static bool IsBranch(this ILOpCode opCode) 13 { 14 switch (opCode) 15 { 16 case ILOpCode.Br: 17 case ILOpCode.Br_s: 18 case ILOpCode.Brtrue: 19 case ILOpCode.Brtrue_s: 20 case ILOpCode.Brfalse: 21 case ILOpCode.Brfalse_s: 22 case ILOpCode.Beq: 23 case ILOpCode.Beq_s: 24 case ILOpCode.Bne_un: 25 case ILOpCode.Bne_un_s: 26 case ILOpCode.Bge: 27 case ILOpCode.Bge_s: 28 case ILOpCode.Bge_un: 29 case ILOpCode.Bge_un_s: 30 case ILOpCode.Bgt: 31 case ILOpCode.Bgt_s: 32 case ILOpCode.Bgt_un: 33 case ILOpCode.Bgt_un_s: 34 case ILOpCode.Ble: 35 case ILOpCode.Ble_s: 36 case ILOpCode.Ble_un: 37 case ILOpCode.Ble_un_s: 38 case ILOpCode.Blt: 39 case ILOpCode.Blt_s: 40 case ILOpCode.Blt_un: 41 case ILOpCode.Blt_un_s: 42 case ILOpCode.Leave: 43 case ILOpCode.Leave_s: 44 return true; 45 } 46 47 return false; 48 } 49 50 /// <summary> 51 /// Calculate the size of the specified branch instruction operand. 52 /// </summary> 53 /// <param name="opCode">Branch op-code.</param> 54 /// <returns>1 if <paramref name="opCode"/> is a short branch or 4 if it is a long branch.</returns> 55 /// <exception cref="ArgumentException">Specified <paramref name="opCode"/> is not a branch op-code.</exception> GetBranchOperandSize(this ILOpCode opCode)56 public static int GetBranchOperandSize(this ILOpCode opCode) 57 { 58 switch (opCode) 59 { 60 case ILOpCode.Br_s: 61 case ILOpCode.Brfalse_s: 62 case ILOpCode.Brtrue_s: 63 case ILOpCode.Beq_s: 64 case ILOpCode.Bge_s: 65 case ILOpCode.Bgt_s: 66 case ILOpCode.Ble_s: 67 case ILOpCode.Blt_s: 68 case ILOpCode.Bne_un_s: 69 case ILOpCode.Bge_un_s: 70 case ILOpCode.Bgt_un_s: 71 case ILOpCode.Ble_un_s: 72 case ILOpCode.Blt_un_s: 73 case ILOpCode.Leave_s: 74 return 1; 75 76 case ILOpCode.Br: 77 case ILOpCode.Brfalse: 78 case ILOpCode.Brtrue: 79 case ILOpCode.Beq: 80 case ILOpCode.Bge: 81 case ILOpCode.Bgt: 82 case ILOpCode.Ble: 83 case ILOpCode.Blt: 84 case ILOpCode.Bne_un: 85 case ILOpCode.Bge_un: 86 case ILOpCode.Bgt_un: 87 case ILOpCode.Ble_un: 88 case ILOpCode.Blt_un: 89 case ILOpCode.Leave: 90 return 4; 91 } 92 93 throw new ArgumentException(SR.Format(SR.UnexpectedOpCode, opCode), nameof(opCode)); 94 } 95 96 /// <summary> 97 /// Get a short form of the specified branch op-code. 98 /// </summary> 99 /// <param name="opCode">Branch op-code.</param> 100 /// <returns>Short form of the branch op-code.</returns> 101 /// <exception cref="ArgumentException">Specified <paramref name="opCode"/> is not a branch op-code.</exception> GetShortBranch(this ILOpCode opCode)102 public static ILOpCode GetShortBranch(this ILOpCode opCode) 103 { 104 switch (opCode) 105 { 106 case ILOpCode.Br_s: 107 case ILOpCode.Brfalse_s: 108 case ILOpCode.Brtrue_s: 109 case ILOpCode.Beq_s: 110 case ILOpCode.Bge_s: 111 case ILOpCode.Bgt_s: 112 case ILOpCode.Ble_s: 113 case ILOpCode.Blt_s: 114 case ILOpCode.Bne_un_s: 115 case ILOpCode.Bge_un_s: 116 case ILOpCode.Bgt_un_s: 117 case ILOpCode.Ble_un_s: 118 case ILOpCode.Blt_un_s: 119 case ILOpCode.Leave_s: 120 return opCode; 121 122 case ILOpCode.Br: 123 return ILOpCode.Br_s; 124 125 case ILOpCode.Brfalse: 126 return ILOpCode.Brfalse_s; 127 128 case ILOpCode.Brtrue: 129 return ILOpCode.Brtrue_s; 130 131 case ILOpCode.Beq: 132 return ILOpCode.Beq_s; 133 134 case ILOpCode.Bge: 135 return ILOpCode.Bge_s; 136 137 case ILOpCode.Bgt: 138 return ILOpCode.Bgt_s; 139 140 case ILOpCode.Ble: 141 return ILOpCode.Ble_s; 142 143 case ILOpCode.Blt: 144 return ILOpCode.Blt_s; 145 146 case ILOpCode.Bne_un: 147 return ILOpCode.Bne_un_s; 148 149 case ILOpCode.Bge_un: 150 return ILOpCode.Bge_un_s; 151 152 case ILOpCode.Bgt_un: 153 return ILOpCode.Bgt_un_s; 154 155 case ILOpCode.Ble_un: 156 return ILOpCode.Ble_un_s; 157 158 case ILOpCode.Blt_un: 159 return ILOpCode.Blt_un_s; 160 161 case ILOpCode.Leave: 162 return ILOpCode.Leave_s; 163 } 164 165 throw new ArgumentException(SR.Format(SR.UnexpectedOpCode, opCode), nameof(opCode)); 166 } 167 168 /// <summary> 169 /// Get a long form of the specified branch op-code. 170 /// </summary> 171 /// <param name="opCode">Branch op-code.</param> 172 /// <returns>Long form of the branch op-code.</returns> 173 /// <exception cref="ArgumentException">Specified <paramref name="opCode"/> is not a branch op-code.</exception> GetLongBranch(this ILOpCode opCode)174 public static ILOpCode GetLongBranch(this ILOpCode opCode) 175 { 176 switch (opCode) 177 { 178 case ILOpCode.Br: 179 case ILOpCode.Brfalse: 180 case ILOpCode.Brtrue: 181 case ILOpCode.Beq: 182 case ILOpCode.Bge: 183 case ILOpCode.Bgt: 184 case ILOpCode.Ble: 185 case ILOpCode.Blt: 186 case ILOpCode.Bne_un: 187 case ILOpCode.Bge_un: 188 case ILOpCode.Bgt_un: 189 case ILOpCode.Ble_un: 190 case ILOpCode.Blt_un: 191 case ILOpCode.Leave: 192 return opCode; 193 194 case ILOpCode.Br_s: 195 return ILOpCode.Br; 196 197 case ILOpCode.Brfalse_s: 198 return ILOpCode.Brfalse; 199 200 case ILOpCode.Brtrue_s: 201 return ILOpCode.Brtrue; 202 203 case ILOpCode.Beq_s: 204 return ILOpCode.Beq; 205 206 case ILOpCode.Bge_s: 207 return ILOpCode.Bge; 208 209 case ILOpCode.Bgt_s: 210 return ILOpCode.Bgt; 211 212 case ILOpCode.Ble_s: 213 return ILOpCode.Ble; 214 215 case ILOpCode.Blt_s: 216 return ILOpCode.Blt; 217 218 case ILOpCode.Bne_un_s: 219 return ILOpCode.Bne_un; 220 221 case ILOpCode.Bge_un_s: 222 return ILOpCode.Bge_un; 223 224 case ILOpCode.Bgt_un_s: 225 return ILOpCode.Bgt_un; 226 227 case ILOpCode.Ble_un_s: 228 return ILOpCode.Ble_un; 229 230 case ILOpCode.Blt_un_s: 231 return ILOpCode.Blt_un; 232 233 case ILOpCode.Leave_s: 234 return ILOpCode.Leave; 235 } 236 237 throw new ArgumentException(SR.Format(SR.UnexpectedOpCode, opCode), nameof(opCode)); 238 } 239 } 240 } 241