+ // If this is a bytecode format that did not include the unreachable
+ // instruction, bump up the opcode number to adjust it.
+ if (hasNoUnreachableInst)
+ if (Opcode >= 6 && Opcode < 62)
+ ++Opcode;
+
+ // If this is bytecode version 6, that only had signed Rem and Div
+ // instructions, then we must compensate for those two instructions only.
+ // So that the switch statement below works, we're trying to turn this into
+ // a version 5 opcode. To do that we must adjust the opcode to 10 (Div) if its
+ // any of the UDiv, SDiv or FDiv instructions; or, adjust the opcode to
+ // 11 (Rem) if its any of the URem, SRem, or FRem instructions; or, simply
+ // decrement the instruction code if its beyond FRem.
+ if (!hasSignlessDivRem) {
+ // If its one of the signed Div/Rem opcodes, its fine the way it is
+ if (Opcode >= 10 && Opcode <= 12) // UDiv through FDiv
+ Opcode = 10; // Div
+ else if (Opcode >=13 && Opcode <= 15) // URem through FRem
+ Opcode = 11; // Rem
+ else if (Opcode >= 16 && Opcode <= 35) // And through Shr
+ // Adjust for new instruction codes
+ Opcode -= 4;
+ else if (Opcode >= 36 && Opcode <= 42) // Everything after Select
+ // In vers 6 bytecode we eliminated the placeholders for the obsolete
+ // VAARG and VANEXT instructions. Consequently those two slots were
+ // filled starting with Select (36) which was 34. So now we only need
+ // to subtract two. This circumvents hitting opcodes 32 and 33
+ Opcode -= 2;
+ else { // Opcode < 10 or > 42
+ // No upgrade necessary.
+ return 0;
+ }
+ }
+