13c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein/* 23c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * Copyright (C) 2011 The Android Open Source Project 33c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * 43c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * Licensed under the Apache License, Version 2.0 (the "License"); 53c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * you may not use this file except in compliance with the License. 63c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * You may obtain a copy of the License at 73c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * 83c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * http://www.apache.org/licenses/LICENSE-2.0 93c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * 103c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * Unless required by applicable law or agreed to in writing, software 113c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * distributed under the License is distributed on an "AS IS" BASIS, 123c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * See the License for the specific language governing permissions and 143c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * limitations under the License. 153c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein */ 163c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 17537939ca06a47668f719ee06159303bcd3175c69Dan Bornsteinpackage com.android.dx.io.instructions; 183c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 19fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dex.DexException; 20537939ca06a47668f719ee06159303bcd3175c69Dan Bornsteinimport com.android.dx.io.IndexType; 21537939ca06a47668f719ee06159303bcd3175c69Dan Bornsteinimport com.android.dx.io.OpcodeInfo; 22537939ca06a47668f719ee06159303bcd3175c69Dan Bornsteinimport com.android.dx.io.Opcodes; 23740fce415cf1a982e9b035604f432eed378fbd05Dan Bornsteinimport com.android.dx.util.Hex; 2419cefdcde26ea31d06cef031032b2ef78013d976Dan Bornsteinimport java.io.EOFException; 2519cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein 263c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein/** 273c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * Representation of an instruction format, which knows how to decode into 283c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * and encode from instances of {@link DecodedInstruction}. 293c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein */ 303c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornsteinpublic enum InstructionCodec { 313c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_00X() { 323c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 3319cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 34740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new ZeroRegisterDecodedInstruction( 35740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein this, opcodeUnit, 0, null, 36d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 0, 0L); 373c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 383c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 393c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 403c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein out.write(insn.getOpcodeUnit()); 413c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 423c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 433c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 443c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_10X() { 453c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 4619cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 473c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int opcode = byte0(opcodeUnit); 483c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int literal = byte1(opcodeUnit); // should be zero 49740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new ZeroRegisterDecodedInstruction( 50740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein this, opcode, 0, null, 51d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 0, literal); 523c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 533c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 543c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 553c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein out.write(insn.getOpcodeUnit()); 563c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 573c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 583c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 593c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_12X() { 603c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 6119cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 623c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int opcode = byte0(opcodeUnit); 633c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int a = nibble2(opcodeUnit); 643c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int b = nibble3(opcodeUnit); 65740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new TwoRegisterDecodedInstruction( 66740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein this, opcode, 0, null, 67d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 0, 0L, 68740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein a, b); 693c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 703c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 713c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 723c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein out.write( 733c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein codeUnit(insn.getOpcodeUnit(), 743c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein makeByte(insn.getA(), insn.getB()))); 753c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 763c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 773c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 783c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_11N() { 793c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 8019cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 813c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int opcode = byte0(opcodeUnit); 823c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int a = nibble2(opcodeUnit); 833c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int literal = (nibble3(opcodeUnit) << 28) >> 28; // sign-extend 84740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new OneRegisterDecodedInstruction( 85740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein this, opcode, 0, null, 86d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 0, literal, 87740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein a); 883c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 893c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 903c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 913c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein out.write( 923c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein codeUnit(insn.getOpcodeUnit(), 933c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein makeByte(insn.getA(), insn.getLiteralNibble()))); 943c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 953c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 963c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 973c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_11X() { 983c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 9919cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 1003c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int opcode = byte0(opcodeUnit); 1013c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int a = byte1(opcodeUnit); 102740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new OneRegisterDecodedInstruction( 103740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein this, opcode, 0, null, 104d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 0, 0L, 105740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein a); 1063c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 1073c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 1083c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 1093c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein out.write(codeUnit(insn.getOpcode(), insn.getA())); 1103c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 1113c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 1123c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 1133c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_10T() { 1143c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 11519cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 116d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein int baseAddress = in.cursor() - 1; 1173c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int opcode = byte0(opcodeUnit); 11832dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein int target = (byte) byte1(opcodeUnit); // sign-extend 119740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new ZeroRegisterDecodedInstruction( 120740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein this, opcode, 0, null, 121d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein baseAddress + target, 0L); 1223c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 1233c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 1243c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 125d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein int relativeTarget = insn.getTargetByte(out.cursor()); 126d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein out.write(codeUnit(insn.getOpcode(), relativeTarget)); 1273c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 1283c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 1293c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 1303c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_20T() { 1313c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 13219cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 133d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein int baseAddress = in.cursor() - 1; 1343c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int opcode = byte0(opcodeUnit); 1353c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int literal = byte1(opcodeUnit); // should be zero 1363c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int target = (short) in.read(); // sign-extend 137740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new ZeroRegisterDecodedInstruction( 138740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein this, opcode, 0, null, 139d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein baseAddress + target, literal); 1403c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 1413c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 1423c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 143d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein short relativeTarget = insn.getTargetUnit(out.cursor()); 144d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein out.write(insn.getOpcodeUnit(), relativeTarget); 1453c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 1463c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 1473c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 1483c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_20BC() { 1493c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 15019cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 1513c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein // Note: We use the literal field to hold the decoded AA value. 1523c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int opcode = byte0(opcodeUnit); 1533c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int literal = byte1(opcodeUnit); 1543c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int index = in.read(); 155740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new ZeroRegisterDecodedInstruction( 156740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein this, opcode, index, IndexType.VARIES, 157d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 0, literal); 1583c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 1593c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 1603c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 1613c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein out.write( 1623c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein codeUnit(insn.getOpcode(), insn.getLiteralByte()), 1633c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein insn.getIndexUnit()); 1643c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 1653c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 1663c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 1673c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_22X() { 1683c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 16919cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 1703c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int opcode = byte0(opcodeUnit); 1713c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int a = byte1(opcodeUnit); 1723c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int b = in.read(); 173740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new TwoRegisterDecodedInstruction( 174740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein this, opcode, 0, null, 175d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 0, 0L, 176740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein a, b); 1773c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 1783c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 1793c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 1803c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein out.write( 1813c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein codeUnit(insn.getOpcode(), insn.getA()), 1823c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein insn.getBUnit()); 1833c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 1843c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 1853c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 1863c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_21T() { 1873c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 18819cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 189d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein int baseAddress = in.cursor() - 1; 1903c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int opcode = byte0(opcodeUnit); 1913c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int a = byte1(opcodeUnit); 1923c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int target = (short) in.read(); // sign-extend 193740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new OneRegisterDecodedInstruction( 194740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein this, opcode, 0, null, 195d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein baseAddress + target, 0L, 196740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein a); 1973c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 1983c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 1993c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 200d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein short relativeTarget = insn.getTargetUnit(out.cursor()); 201d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein out.write(codeUnit(insn.getOpcode(), insn.getA()), relativeTarget); 2023c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 2033c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 2043c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 2053c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_21S() { 2063c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 20719cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 2083c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int opcode = byte0(opcodeUnit); 2093c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int a = byte1(opcodeUnit); 2103c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int literal = (short) in.read(); // sign-extend 211740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new OneRegisterDecodedInstruction( 212740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein this, opcode, 0, null, 213d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 0, literal, 214740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein a); 2153c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 2163c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 2173c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 2183c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein out.write( 2193c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein codeUnit(insn.getOpcode(), insn.getA()), 2203c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein insn.getLiteralUnit()); 2213c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 2223c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 2233c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 2243c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_21H() { 2253c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 22619cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 2273c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int opcode = byte0(opcodeUnit); 2283c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int a = byte1(opcodeUnit); 2290ebdfc22385095c75fbced79edc1d1e75b504213Jesse Wilson long literal = (short) in.read(); // sign-extend 2303c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 2313c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein /* 2323c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * Format 21h decodes differently depending on the opcode, 2333c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * because the "signed hat" might represent either a 32- 2343c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * or 64- bit value. 2353c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein */ 2367ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein literal <<= (opcode == Opcodes.CONST_HIGH16) ? 16 : 48; 2373c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 238740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new OneRegisterDecodedInstruction( 239740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein this, opcode, 0, null, 240d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 0, literal, 241740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein a); 2423c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 2433c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 2443c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 2453c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein // See above. 2463c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int opcode = insn.getOpcode(); 2477ba91291bb6ce64691398a8751656207e8e3e98dDan Bornstein int shift = (opcode == Opcodes.CONST_HIGH16) ? 16 : 48; 2483c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein short literal = (short) (insn.getLiteral() >> shift); 2493c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 2503c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein out.write(codeUnit(opcode, insn.getA()), literal); 2513c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 2523c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 2533c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 2543c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_21C() { 2553c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 25619cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 2573c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int opcode = byte0(opcodeUnit); 2583c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int a = byte1(opcodeUnit); 2593c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int index = in.read(); 2603c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein IndexType indexType = OpcodeInfo.getIndexType(opcode); 261740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new OneRegisterDecodedInstruction( 262740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein this, opcode, index, indexType, 263d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 0, 0L, 264740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein a); 2653c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 2663c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 2673c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 2683c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein out.write( 2693c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein codeUnit(insn.getOpcode(), insn.getA()), 2701bbb3378b108329c7ab75713fe9507b7ffc7f885Jesse Wilson insn.getIndexUnit()); 2713c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 2723c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 2733c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 2743c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_23X() { 2753c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 27619cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 2773c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int opcode = byte0(opcodeUnit); 2783c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int a = byte1(opcodeUnit); 2793c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int bc = in.read(); 2803c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int b = byte0(bc); 2813c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int c = byte1(bc); 282740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new ThreeRegisterDecodedInstruction( 283740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein this, opcode, 0, null, 284d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 0, 0L, 285740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein a, b, c); 2863c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 2873c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 2883c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 2893c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein out.write( 2903c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein codeUnit(insn.getOpcode(), insn.getA()), 2913c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein codeUnit(insn.getB(), insn.getC())); 2923c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 2933c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 2943c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 2953c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_22B() { 2963c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 29719cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 2983c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int opcode = byte0(opcodeUnit); 2993c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int a = byte1(opcodeUnit); 3003c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int bc = in.read(); 3013c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int b = byte0(bc); 3023c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int literal = (byte) byte1(bc); // sign-extend 303740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new TwoRegisterDecodedInstruction( 304740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein this, opcode, 0, null, 305d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 0, literal, 306740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein a, b); 3073c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 3083c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 3093c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 3103c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein out.write( 3113c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein codeUnit(insn.getOpcode(), insn.getA()), 3123c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein codeUnit(insn.getB(), 3133c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein insn.getLiteralByte())); 3143c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 3153c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 3163c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 3173c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_22T() { 3183c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 31919cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 320d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein int baseAddress = in.cursor() - 1; 3213c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int opcode = byte0(opcodeUnit); 3223c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int a = nibble2(opcodeUnit); 3233c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int b = nibble3(opcodeUnit); 3243c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int target = (short) in.read(); // sign-extend 325740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new TwoRegisterDecodedInstruction( 326740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein this, opcode, 0, null, 327d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein baseAddress + target, 0L, 328740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein a, b); 3293c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 3303c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 3313c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 332d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein short relativeTarget = insn.getTargetUnit(out.cursor()); 3333c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein out.write( 3343c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein codeUnit(insn.getOpcode(), 3353c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein makeByte(insn.getA(), insn.getB())), 336d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein relativeTarget); 3373c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 3383c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 3393c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 3403c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_22S() { 3413c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 34219cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 3433c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int opcode = byte0(opcodeUnit); 3443c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int a = nibble2(opcodeUnit); 3453c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int b = nibble3(opcodeUnit); 3463c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int literal = (short) in.read(); // sign-extend 347740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new TwoRegisterDecodedInstruction( 348740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein this, opcode, 0, null, 349d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 0, literal, 350740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein a, b); 3513c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 3523c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 3533c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 3543c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein out.write( 3553c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein codeUnit(insn.getOpcode(), 3563c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein makeByte(insn.getA(), insn.getB())), 3573c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein insn.getLiteralUnit()); 3583c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 3593c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 3603c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 3613c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_22C() { 3623c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 36319cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 3643c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int opcode = byte0(opcodeUnit); 3653c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int a = nibble2(opcodeUnit); 3663c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int b = nibble3(opcodeUnit); 3673c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int index = in.read(); 3683c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein IndexType indexType = OpcodeInfo.getIndexType(opcode); 369740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new TwoRegisterDecodedInstruction( 370740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein this, opcode, index, indexType, 371d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 0, 0L, 372740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein a, b); 3733c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 3743c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 3753c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 3763c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein out.write( 3773c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein codeUnit(insn.getOpcode(), 3783c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein makeByte(insn.getA(), insn.getB())), 3793c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein insn.getIndexUnit()); 3803c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 3813c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 3823c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 3833c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_22CS() { 3843c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 38519cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 3863c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int opcode = byte0(opcodeUnit); 3873c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int a = nibble2(opcodeUnit); 3883c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int b = nibble3(opcodeUnit); 3893c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int index = in.read(); 390740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new TwoRegisterDecodedInstruction( 391740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein this, opcode, index, IndexType.FIELD_OFFSET, 392d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 0, 0L, 393740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein a, b); 3943c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 3953c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 3963c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 3973c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein out.write( 3983c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein codeUnit(insn.getOpcode(), 3993c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein makeByte(insn.getA(), insn.getB())), 4003c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein insn.getIndexUnit()); 4013c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 4023c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 4033c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 4043c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_30T() { 4053c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 40619cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 407d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein int baseAddress = in.cursor() - 1; 4083c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int opcode = byte0(opcodeUnit); 4093c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int literal = byte1(opcodeUnit); // should be zero 4103c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int target = in.readInt(); 411740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new ZeroRegisterDecodedInstruction( 412740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein this, opcode, 0, null, 413d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein baseAddress + target, literal); 4143c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 4153c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 4163c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 417d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein int relativeTarget = insn.getTarget(out.cursor()); 418d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein out.write(insn.getOpcodeUnit(), 419d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein unit0(relativeTarget), unit1(relativeTarget)); 4203c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 4213c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 4223c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 4233c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_32X() { 4243c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 42519cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 4263c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int opcode = byte0(opcodeUnit); 4273c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int literal = byte1(opcodeUnit); // should be zero 4283c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int a = in.read(); 4293c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int b = in.read(); 430740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new TwoRegisterDecodedInstruction( 431740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein this, opcode, 0, null, 432d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 0, literal, 433740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein a, b); 4343c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 4353c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 4363c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 4373c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein out.write(insn.getOpcodeUnit(), insn.getAUnit(), insn.getBUnit()); 4383c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 4393c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 4403c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 4413c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_31I() { 4423c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 44319cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 4443c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int opcode = byte0(opcodeUnit); 4453c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int a = byte1(opcodeUnit); 4463c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int literal = in.readInt(); 447740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new OneRegisterDecodedInstruction( 448740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein this, opcode, 0, null, 449d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 0, literal, 450740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein a); 4513c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 4523c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 4533c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 4543c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int literal = insn.getLiteralInt(); 4553c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein out.write( 4563c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein codeUnit(insn.getOpcode(), insn.getA()), 4573c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein unit0(literal), 4583c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein unit1(literal)); 4593c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 4603c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 4613c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 4623c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_31T() { 4633c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 46419cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 465d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein int baseAddress = in.cursor() - 1; 4663c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int opcode = byte0(opcodeUnit); 4673c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int a = byte1(opcodeUnit); 468d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein int target = baseAddress + in.readInt(); 469d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 470d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein /* 471d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein * Switch instructions need to "forward" their addresses to their 472d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein * payload target instructions. 473d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein */ 474d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein switch (opcode) { 475d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein case Opcodes.PACKED_SWITCH: 476d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein case Opcodes.SPARSE_SWITCH: { 477d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein in.setBaseAddress(target, baseAddress); 478d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein break; 479d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein } 480d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein } 481d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 482740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new OneRegisterDecodedInstruction( 483740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein this, opcode, 0, null, 484d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein target, 0L, 485740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein a); 4863c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 4873c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 4883c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 489d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein int relativeTarget = insn.getTarget(out.cursor()); 4903c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein out.write( 4913c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein codeUnit(insn.getOpcode(), insn.getA()), 492d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein unit0(relativeTarget), unit1(relativeTarget)); 4933c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 4943c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 4953c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 4963c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_31C() { 4973c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 49819cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 4993c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int opcode = byte0(opcodeUnit); 5003c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int a = byte1(opcodeUnit); 5013c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int index = in.readInt(); 5023c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein IndexType indexType = OpcodeInfo.getIndexType(opcode); 503740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new OneRegisterDecodedInstruction( 504740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein this, opcode, index, indexType, 505d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 0, 0L, 506740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein a); 5073c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 5083c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 5093c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 5103c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int index = insn.getIndex(); 5113c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein out.write( 5123c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein codeUnit(insn.getOpcode(), insn.getA()), 5133c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein unit0(index), 5143c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein unit1(index)); 5153c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 5163c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 5173c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 5183c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_35C() { 5193c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 52019cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 5213c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein return decodeRegisterList(this, opcodeUnit, in); 5223c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 5233c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 5243c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 5253c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein encodeRegisterList(insn, out); 5263c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 5273c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 5283c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 5293c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_35MS() { 5303c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 53119cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 5323c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein return decodeRegisterList(this, opcodeUnit, in); 5333c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 5343c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 5353c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 5363c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein encodeRegisterList(insn, out); 5373c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 5383c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 5393c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 5403c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_35MI() { 5413c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 54219cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 5433c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein return decodeRegisterList(this, opcodeUnit, in); 5443c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 5453c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 5463c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 5473c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein encodeRegisterList(insn, out); 5483c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 5493c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 5503c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 5513c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_3RC() { 5523c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 55319cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 5543c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein return decodeRegisterRange(this, opcodeUnit, in); 5553c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 5563c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 5573c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 5583c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein encodeRegisterRange(insn, out); 5593c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 5603c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 5613c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 5623c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_3RMS() { 5633c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 56419cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 5653c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein return decodeRegisterRange(this, opcodeUnit, in); 5663c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 5673c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 5683c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 5693c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein encodeRegisterRange(insn, out); 5703c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 5713c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 5723c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 5733c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_3RMI() { 5743c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 57519cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 5763c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein return decodeRegisterRange(this, opcodeUnit, in); 5773c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 5783c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 5793c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 5803c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein encodeRegisterRange(insn, out); 5813c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 5823c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 5833c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 5843c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein FORMAT_51L() { 5853c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 58619cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein CodeInput in) throws EOFException { 5873c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int opcode = byte0(opcodeUnit); 5883c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int a = byte1(opcodeUnit); 5893c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein long literal = in.readLong(); 590740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new OneRegisterDecodedInstruction( 591740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein this, opcode, 0, null, 592d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 0, literal, 593740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein a); 5943c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 5953c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 5963c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 5971bbb3378b108329c7ab75713fe9507b7ffc7f885Jesse Wilson long literal = insn.getLiteral(); 5983c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein out.write( 5993c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein codeUnit(insn.getOpcode(), insn.getA()), 6003c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein unit0(literal), 6013c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein unit1(literal), 6023c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein unit2(literal), 6033c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein unit3(literal)); 6043c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 6053c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }, 6063c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 60732dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein FORMAT_PACKED_SWITCH_PAYLOAD() { 60832dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 60932dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein CodeInput in) throws EOFException { 6100ebdfc22385095c75fbced79edc1d1e75b504213Jesse Wilson int baseAddress = in.baseAddressForCursor() - 1; // already read opcode 61132dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein int size = in.read(); 612d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein int firstKey = in.readInt(); 613d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein int[] targets = new int[size]; 61432dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein 615d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein for (int i = 0; i < size; i++) { 616d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein targets[i] = baseAddress + in.readInt(); 61732dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein } 61832dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein 619d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein return new PackedSwitchPayloadDecodedInstruction( 620d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein this, opcodeUnit, firstKey, targets); 62132dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein } 62232dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein 62332dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 624d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein PackedSwitchPayloadDecodedInstruction payload = 625d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein (PackedSwitchPayloadDecodedInstruction) insn; 626d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein int[] targets = payload.getTargets(); 627d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein int baseAddress = out.baseAddressForCursor(); 628d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 629d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein out.write(payload.getOpcodeUnit()); 630d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein out.write(asUnsignedUnit(targets.length)); 631d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein out.writeInt(payload.getFirstKey()); 632d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 633d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein for (int target : targets) { 634d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein out.writeInt(target - baseAddress); 635d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein } 63632dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein } 63732dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein }, 63832dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein 63932dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein FORMAT_SPARSE_SWITCH_PAYLOAD() { 64032dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 64132dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein CodeInput in) throws EOFException { 6420ebdfc22385095c75fbced79edc1d1e75b504213Jesse Wilson int baseAddress = in.baseAddressForCursor() - 1; // already read opcode 64332dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein int size = in.read(); 644d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein int[] keys = new int[size]; 645d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein int[] targets = new int[size]; 64632dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein 647d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein for (int i = 0; i < size; i++) { 648d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein keys[i] = in.readInt(); 649d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein } 65032dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein 651d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein for (int i = 0; i < size; i++) { 652d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein targets[i] = baseAddress + in.readInt(); 65332dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein } 65432dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein 655d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein return new SparseSwitchPayloadDecodedInstruction( 656d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein this, opcodeUnit, keys, targets); 65732dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein } 65832dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein 65932dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 660d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein SparseSwitchPayloadDecodedInstruction payload = 661d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein (SparseSwitchPayloadDecodedInstruction) insn; 662d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein int[] keys = payload.getKeys(); 663d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein int[] targets = payload.getTargets(); 664d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein int baseAddress = out.baseAddressForCursor(); 665d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 666d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein out.write(payload.getOpcodeUnit()); 667d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein out.write(asUnsignedUnit(targets.length)); 668d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 669d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein for (int key : keys) { 670d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein out.writeInt(key); 671d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein } 672d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 673d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein for (int target : targets) { 674d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein out.writeInt(target - baseAddress); 675d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein } 67632dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein } 67732dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein }, 67832dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein 67932dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein FORMAT_FILL_ARRAY_DATA_PAYLOAD() { 68032dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein @Override public DecodedInstruction decode(int opcodeUnit, 68132dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein CodeInput in) throws EOFException { 68232dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein int elementWidth = in.read(); 68332dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein int size = in.readInt(); 68432dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein 685d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein switch (elementWidth) { 686d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein case 1: { 687d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein byte[] array = new byte[size]; 688d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein boolean even = true; 689d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein for (int i = 0, value = 0; i < size; i++, even = !even) { 690d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein if (even) { 691d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein value = in.read(); 692d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein } 693d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein array[i] = (byte) (value & 0xff); 694d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein value >>= 8; 695d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein } 696d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein return new FillArrayDataPayloadDecodedInstruction( 697d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein this, opcodeUnit, array); 698d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein } 699d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein case 2: { 700d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein short[] array = new short[size]; 701d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein for (int i = 0; i < size; i++) { 702d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein array[i] = (short) in.read(); 703d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein } 704d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein return new FillArrayDataPayloadDecodedInstruction( 705d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein this, opcodeUnit, array); 706d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein } 707d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein case 4: { 708d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein int[] array = new int[size]; 709d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein for (int i = 0; i < size; i++) { 710d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein array[i] = in.readInt(); 711d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein } 712d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein return new FillArrayDataPayloadDecodedInstruction( 713d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein this, opcodeUnit, array); 714d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein } 715d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein case 8: { 716d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein long[] array = new long[size]; 717d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein for (int i = 0; i < size; i++) { 718d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein array[i] = in.readLong(); 719d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein } 720d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein return new FillArrayDataPayloadDecodedInstruction( 721d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein this, opcodeUnit, array); 722d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein } 72332dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein } 72432dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein 725d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein throw new DexException("bogus element_width: " 726d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein + Hex.u2(elementWidth)); 72732dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein } 72832dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein 72932dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein @Override public void encode(DecodedInstruction insn, CodeOutput out) { 730d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein FillArrayDataPayloadDecodedInstruction payload = 731d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein (FillArrayDataPayloadDecodedInstruction) insn; 732d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein short elementWidth = payload.getElementWidthUnit(); 733d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein Object data = payload.getData(); 734d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 735d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein out.write(payload.getOpcodeUnit()); 736d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein out.write(elementWidth); 737d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein out.writeInt(payload.getSize()); 738d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 739d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein switch (elementWidth) { 740d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein case 1: out.write((byte[]) data); break; 741d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein case 2: out.write((short[]) data); break; 742d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein case 4: out.write((int[]) data); break; 743d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein case 8: out.write((long[]) data); break; 744d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein default: { 745d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein throw new DexException("bogus element_width: " 746d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein + Hex.u2(elementWidth)); 747d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein } 748d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein } 74932dd826ad1742993cf0627448cd083a5021d71bbDan Bornstein } 7503c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein }; 7513c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 7523c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein /** 7533c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * Decodes an instruction specified by the given opcode unit, reading 7543c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * any required additional code units from the given input source. 7553c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein */ 75619cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein public abstract DecodedInstruction decode(int opcodeUnit, CodeInput in) 75719cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein throws EOFException; 7583c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 7593c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein /** 7603c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * Encodes the given instruction. 7613c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein */ 7623c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein public abstract void encode(DecodedInstruction insn, CodeOutput out); 7633c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 7643c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein /** 7653c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * Helper method that decodes any of the register-list formats. 7663c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein */ 7673c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein private static DecodedInstruction decodeRegisterList( 76819cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein InstructionCodec format, int opcodeUnit, CodeInput in) 76919cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein throws EOFException { 7703c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int opcode = byte0(opcodeUnit); 7713c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int e = nibble2(opcodeUnit); 7723c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int registerCount = nibble3(opcodeUnit); 7733c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int index = in.read(); 7743c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int abcd = in.read(); 7753c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int a = nibble0(abcd); 7763c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int b = nibble1(abcd); 7773c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int c = nibble2(abcd); 7783c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int d = nibble3(abcd); 7793c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein IndexType indexType = OpcodeInfo.getIndexType(opcode); 780740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein 781740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein // TODO: Having to switch like this is less than ideal. 782740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein switch (registerCount) { 783740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein case 0: 784740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new ZeroRegisterDecodedInstruction( 785740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein format, opcode, index, indexType, 786d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 0, 0L); 787740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein case 1: 788740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new OneRegisterDecodedInstruction( 789740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein format, opcode, index, indexType, 790d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 0, 0L, 791740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein a); 792740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein case 2: 793740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new TwoRegisterDecodedInstruction( 794740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein format, opcode, index, indexType, 795d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 0, 0L, 796740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein a, b); 797740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein case 3: 798740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new ThreeRegisterDecodedInstruction( 799740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein format, opcode, index, indexType, 800d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 0, 0L, 801740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein a, b, c); 802740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein case 4: 803740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new FourRegisterDecodedInstruction( 804740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein format, opcode, index, indexType, 805d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 0, 0L, 806740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein a, b, c, d); 807740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein case 5: 808740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new FiveRegisterDecodedInstruction( 809740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein format, opcode, index, indexType, 810d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 0, 0L, 811740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein a, b, c, d, e); 812740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein } 813740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein 814740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein throw new DexException("bogus registerCount: " 815740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein + Hex.uNibble(registerCount)); 8163c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 8173c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 8183c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein /** 8193c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * Helper method that encodes any of the register-list formats. 8203c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein */ 8213c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein private static void encodeRegisterList(DecodedInstruction insn, 8223c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein CodeOutput out) { 8233c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein out.write(codeUnit(insn.getOpcode(), 8243c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein makeByte(insn.getE(), insn.getRegisterCount())), 8253c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein insn.getIndexUnit(), 8263c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein codeUnit(insn.getA(), insn.getB(), insn.getC(), insn.getD())); 8273c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 8283c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 8293c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein /** 8303c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * Helper method that decodes any of the three-unit register-range formats. 8313c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein */ 8323c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein private static DecodedInstruction decodeRegisterRange( 83319cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein InstructionCodec format, int opcodeUnit, CodeInput in) 83419cefdcde26ea31d06cef031032b2ef78013d976Dan Bornstein throws EOFException { 8353c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int opcode = byte0(opcodeUnit); 8363c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int registerCount = byte1(opcodeUnit); 8373c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int index = in.read(); 8383c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int a = in.read(); 8393c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein IndexType indexType = OpcodeInfo.getIndexType(opcode); 840740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein return new RegisterRangeDecodedInstruction( 841740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein format, opcode, index, indexType, 842d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 0, 0L, 843740fce415cf1a982e9b035604f432eed378fbd05Dan Bornstein a, registerCount); 8443c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 8453c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 8463c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein /** 8473c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein * Helper method that encodes any of the three-unit register-range formats. 8483c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein */ 8493c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein private static void encodeRegisterRange(DecodedInstruction insn, 8503c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein CodeOutput out) { 8513c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein out.write(codeUnit(insn.getOpcode(), insn.getRegisterCount()), 8523c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein insn.getIndexUnit(), 8533c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein insn.getAUnit()); 8543c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 8553c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 8563c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein private static short codeUnit(int lowByte, int highByte) { 8573c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein if ((lowByte & ~0xff) != 0) { 8583c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein throw new IllegalArgumentException("bogus lowByte"); 8593c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 8603c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 8613c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein if ((highByte & ~0xff) != 0) { 8623c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein throw new IllegalArgumentException("bogus highByte"); 8633c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 8643c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 8653c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein return (short) (lowByte | (highByte << 8)); 8663c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 8673c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 8683c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein private static short codeUnit(int nibble0, int nibble1, int nibble2, 8693c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein int nibble3) { 8703c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein if ((nibble0 & ~0xf) != 0) { 8713c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein throw new IllegalArgumentException("bogus nibble0"); 8723c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 8733c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 8743c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein if ((nibble1 & ~0xf) != 0) { 8753c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein throw new IllegalArgumentException("bogus nibble1"); 8763c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 8773c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 8783c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein if ((nibble2 & ~0xf) != 0) { 8793c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein throw new IllegalArgumentException("bogus nibble2"); 8803c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 8813c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 8823c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein if ((nibble3 & ~0xf) != 0) { 8833c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein throw new IllegalArgumentException("bogus nibble3"); 8843c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 8853c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 8863c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein return (short) (nibble0 | (nibble1 << 4) 8873c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein | (nibble2 << 8) | (nibble3 << 12)); 8883c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 8893c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 8903c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein private static int makeByte(int lowNibble, int highNibble) { 8913c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein if ((lowNibble & ~0xf) != 0) { 8923c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein throw new IllegalArgumentException("bogus lowNibble"); 8933c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 8943c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 8953c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein if ((highNibble & ~0xf) != 0) { 8963c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein throw new IllegalArgumentException("bogus highNibble"); 8973c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 8983c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 8993c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein return lowNibble | (highNibble << 4); 9003c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 9013c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 902d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein private static short asUnsignedUnit(int value) { 903d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein if ((value & ~0xffff) != 0) { 904d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein throw new IllegalArgumentException("bogus unsigned code unit"); 905d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein } 906d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 907d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein return (short) value; 908d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein } 909d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein 9103c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein private static short unit0(int value) { 9113c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein return (short) value; 9123c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 9133c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 9143c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein private static short unit1(int value) { 9153c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein return (short) (value >> 16); 9163c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 9173c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 9183c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein private static short unit0(long value) { 9193c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein return (short) value; 9203c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 9213c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 9223c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein private static short unit1(long value) { 9233c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein return (short) (value >> 16); 9243c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 9253c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 9263c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein private static short unit2(long value) { 9273c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein return (short) (value >> 32); 9283c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 9293c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 9303c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein private static short unit3(long value) { 9313c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein return (short) (value >> 48); 9323c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 9333c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 9343c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein private static int byte0(int value) { 9353c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein return value & 0xff; 9363c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 9373c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 9383c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein private static int byte1(int value) { 9393c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein return (value >> 8) & 0xff; 9403c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 9413c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 9423c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein private static int byte2(int value) { 9433c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein return (value >> 16) & 0xff; 9443c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 9453c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 9463c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein private static int byte3(int value) { 9473c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein return value >>> 24; 9483c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 9493c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 9503c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein private static int nibble0(int value) { 9513c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein return value & 0xf; 9523c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 9533c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 9543c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein private static int nibble1(int value) { 9553c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein return (value >> 4) & 0xf; 9563c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 9573c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 9583c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein private static int nibble2(int value) { 9593c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein return (value >> 8) & 0xf; 9603c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 9613c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein 9623c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein private static int nibble3(int value) { 9633c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein return (value >> 12) & 0xf; 9643c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein } 9653c5df37a2df7368eb274eb097e9cfa2ccc7fffb6Dan Bornstein} 966