1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.android.dx.dex.code; 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.RegisterSpecList; 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.Constant; 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstInteger; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstKnownNull; 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstLiteral64; 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstLiteralBits; 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.AnnotatedOutput; 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.Hex; 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Base class for all instruction format handlers. Instruction format 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * handlers know how to translate {@link DalvInsn} instances into 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * streams of code words, as well as human-oriented listing strings 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * representing such translations. 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic abstract class InsnFormat { 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the string form, suitable for inclusion in a listing 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * dump, of the given instruction. The instruction must be of this 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instance's format for proper operation. 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param insn {@code non-null;} the instruction 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param noteIndices whether to include an explicit notation of 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * constant pool indices 4399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the string form 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final String listingString(DalvInsn insn, boolean noteIndices) { 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String op = insn.getOpcode().getName(); 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String arg = insnArgString(insn); 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String comment = insnCommentString(insn, noteIndices); 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringBuilder sb = new StringBuilder(100); 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(op); 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (arg.length() != 0) { 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(' '); 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(arg); 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (comment.length() != 0) { 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(" // "); 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(comment); 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sb.toString(); 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the string form of the arguments to the given instruction. 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The instruction must be of this instance's format. If the instruction 6999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * has no arguments, then the result should be {@code ""}, not 7099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code null}. 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p>Subclasses must override this method.</p> 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 7499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param insn {@code non-null;} the instruction 7599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the string form 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public abstract String insnArgString(DalvInsn insn); 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the associated comment for the given instruction, if any. 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The instruction must be of this instance's format. If the instruction 8299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * has no comment, then the result should be {@code ""}, not 8399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code null}. 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p>Subclasses must override this method.</p> 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param insn {@code non-null;} the instruction 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param noteIndices whether to include an explicit notation of 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * constant pool indices 9099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the string form 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public abstract String insnCommentString(DalvInsn insn, 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean noteIndices); 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the code size of instructions that use this format. The 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * size is a number of 16-bit code units, not bytes. This should 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * throw an exception if this format is of variable size. 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code >= 0;} the instruction length in 16-bit code units 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public abstract int codeSize(); 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns whether or not the given instruction's arguments will 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * fit in this instance's format. This includes such things as 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * counting register arguments, checking register ranges, and 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * making sure that additional arguments are of appropriate types 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and are in-range. If this format has a branch target but the 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instruction's branch offset is unknown, this method will simply 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * not check the offset. 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p>Subclasses must override this method.</p> 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 11599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param insn {@code non-null;} the instruction to check 11699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code true} iff the instruction's arguments are 11799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * appropriate for this instance, or {@code false} if not 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public abstract boolean isCompatible(DalvInsn insn); 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns whether or not the given instruction's branch offset will 12399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * fit in this instance's format. This always returns {@code false} 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * for formats that don't include a branch offset. 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p>The default implementation of this method always returns 12799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code false}. Subclasses must override this method if they 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * include branch offsets.</p> 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 13099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param insn {@code non-null;} the instruction to check 13199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code true} iff the instruction's branch offset is 13299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * appropriate for this instance, or {@code false} if not 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean branchFits(TargetInsn insn) { 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the next instruction format to try to match an instruction 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * with, presuming that this instance isn't compatible, if any. 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p>Subclasses must override this method.</p> 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 14499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code null-ok;} the next format to try, or {@code null} if 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * there are no suitable alternatives 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public abstract InsnFormat nextUp(); 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Writes the code units for the given instruction to the given 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * output destination. The instruction must be of this instance's format. 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p>Subclasses must override this method.</p> 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 15599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param out {@code non-null;} the output destination to write to 15699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param insn {@code non-null;} the instruction to write 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public abstract void writeTo(AnnotatedOutput out, DalvInsn insn); 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper method to return a register list string. 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 16399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param list {@code non-null;} the list of registers 16499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the string form 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected static String regListString(RegisterSpecList list) { 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sz = list.size(); 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringBuffer sb = new StringBuffer(sz * 5 + 2); 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append('{'); 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < sz; i++) { 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (i != 0) { 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(", "); 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(list.get(i).regString()); 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append('}'); 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sb.toString(); 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper method to return a literal bits argument string. 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param value the value 18899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the string form 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected static String literalBitsString(CstLiteralBits value) { 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringBuffer sb = new StringBuffer(100); 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append('#'); 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (value instanceof CstKnownNull) { 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append("null"); 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(value.typeName()); 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(' '); 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(value.toHuman()); 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sb.toString(); 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper method to return a literal bits comment string. 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param value the value 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param width the width of the constant, in bits (used for displaying 21199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * the uninterpreted bits; one of: {@code 4 8 16 32 64} 21299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the comment 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected static String literalBitsComment(CstLiteralBits value, 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int width) { 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringBuffer sb = new StringBuffer(20); 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append("#"); 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long bits; 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (value instanceof CstLiteral64) { 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bits = ((CstLiteral64) value).getLongBits(); 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bits = value.getIntBits(); 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (width) { 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 4: sb.append(Hex.uNibble((int) bits)); break; 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 8: sb.append(Hex.u1((int) bits)); break; 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 16: sb.append(Hex.u2((int) bits)); break; 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 32: sb.append(Hex.u4((int) bits)); break; 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 64: sb.append(Hex.u8(bits)); break; 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: { 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new RuntimeException("shouldn't happen"); 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sb.toString(); 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper method to return a branch address string. 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 24599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param insn {@code non-null;} the instruction in question 24699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the string form of the instruction's branch target 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected static String branchString(DalvInsn insn) { 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TargetInsn ti = (TargetInsn) insn; 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int address = ti.getTargetAddress(); 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (address == (char) address) ? Hex.u2(address) : Hex.u4(address); 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper method to return the comment for a branch. 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 25899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param insn {@code non-null;} the instruction in question 25999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the comment 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected static String branchComment(DalvInsn insn) { 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TargetInsn ti = (TargetInsn) insn; 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int offset = ti.getTargetOffset(); 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (offset == (short) offset) ? Hex.s2(offset) : Hex.s4(offset); 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper method to return a constant string. 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 27199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param insn {@code non-null;} a constant-bearing instruction 27299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the string form of the contained constant 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected static String cstString(DalvInsn insn) { 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CstInsn ci = (CstInsn) insn; 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Constant cst = ci.getConstant(); 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return cst.toHuman(); 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper method to return an instruction comment for a constant. 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 28499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param insn {@code non-null;} a constant-bearing instruction 28599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} comment string representing the constant 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected static String cstComment(DalvInsn insn) { 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CstInsn ci = (CstInsn) insn; 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (! ci.hasIndex()) { 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ""; 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringBuilder sb = new StringBuilder(20); 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int index = ci.getIndex(); 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(ci.getConstant().typeName()); 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append('@'); 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (index < 65536) { 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(Hex.u2(index)); 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(Hex.u4(index)); 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sb.toString(); 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper method to determine if a signed int value fits in a nibble. 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param value the value in question 31399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code true} iff it's in the range -8..+7 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected static boolean signedFitsInNibble(int value) { 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (value >= -8) && (value <= 7); 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper method to determine if an unsigned int value fits in a nibble. 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param value the value in question 32399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code true} iff it's in the range 0..0xf 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected static boolean unsignedFitsInNibble(int value) { 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return value == (value & 0xf); 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper method to determine if a signed int value fits in a byte. 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param value the value in question 33399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code true} iff it's in the range -0x80..+0x7f 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected static boolean signedFitsInByte(int value) { 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (byte) value == value; 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper method to determine if an unsigned int value fits in a byte. 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param value the value in question 34399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code true} iff it's in the range 0..0xff 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected static boolean unsignedFitsInByte(int value) { 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return value == (value & 0xff); 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper method to determine if a signed int value fits in a short. 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param value the value in question 35399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code true} iff it's in the range -0x8000..+0x7fff 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected static boolean signedFitsInShort(int value) { 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (short) value == value; 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper method to determine if an unsigned int value fits in a short. 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param value the value in question 36399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code true} iff it's in the range 0..0xffff 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected static boolean unsignedFitsInShort(int value) { 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return value == (value & 0xffff); 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper method to determine if a signed int value fits in three bytes. 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param value the value in question 37399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code true} iff it's in the range -0x800000..+0x7fffff 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected static boolean signedFitsIn3Bytes(int value) { 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return value == ((value << 8) >> 8); 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper method to extract the callout-argument index from an 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * appropriate instruction. 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 38399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param insn {@code non-null;} the instruction 38499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code >= 0;} the callout argument index 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected static int argIndex(DalvInsn insn) { 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int arg = ((CstInteger) ((CstInsn) insn).getConstant()).getValue(); 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (arg < 0) { 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("bogus insn"); 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return arg; 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper method to combine an opcode and a second byte of data into 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the appropriate form for emitting into a code buffer. 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 40099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param insn {@code non-null;} the instruction containing the opcode 40199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param arg {@code 0..255;} arbitrary other byte value 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return combined value 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected static short opcodeUnit(DalvInsn insn, int arg) { 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((arg & 0xff) != arg) { 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("arg out of range 0..255"); 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int opcode = insn.getOpcode().getOpcode(); 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((opcode & 0xff) != opcode) { 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("opcode out of range 0..255"); 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (short) (opcode | (arg << 8)); 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper method to combine two bytes into a code unit. 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 42199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param low {@code 0..255;} low byte 42299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param high {@code 0..255;} high byte 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return combined value 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected static short codeUnit(int low, int high) { 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((low & 0xff) != low) { 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("low out of range 0..255"); 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((high & 0xff) != high) { 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("high out of range 0..255"); 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (short) (low | (high << 8)); 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper method to combine four nibbles into a code unit. 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 44099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param n0 {@code 0..15;} low nibble 44199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param n1 {@code 0..15;} medium-low nibble 44299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param n2 {@code 0..15;} medium-high nibble 44399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param n3 {@code 0..15;} high nibble 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return combined value 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected static short codeUnit(int n0, int n1, int n2, int n3) { 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((n0 & 0xf) != n0) { 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("n0 out of range 0..15"); 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((n1 & 0xf) != n1) { 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("n1 out of range 0..15"); 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((n2 & 0xf) != n2) { 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("n2 out of range 0..15"); 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((n3 & 0xf) != n3) { 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("n3 out of range 0..15"); 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (short) (n0 | (n1 << 4) | (n2 << 8) | (n3 << 12)); 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper method to combine two nibbles into a byte. 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 46999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param low {@code 0..15;} low nibble 47099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param high {@code 0..15;} high nibble 47199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code 0..255;} combined value 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected static int makeByte(int low, int high) { 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((low & 0xf) != low) { 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("low out of range 0..15"); 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((high & 0xf) != high) { 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("high out of range 0..15"); 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return low | (high << 4); 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Writes one code unit to the given output destination. 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 48899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param out {@code non-null;} where to write to 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param c0 code unit to write 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected static void write(AnnotatedOutput out, short c0) { 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeShort(c0); 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Writes two code units to the given output destination. 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 49899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param out {@code non-null;} where to write to 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param c0 code unit to write 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param c1 code unit to write 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected static void write(AnnotatedOutput out, short c0, short c1) { 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeShort(c0); 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeShort(c1); 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Writes three code units to the given output destination. 509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 51099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param out {@code non-null;} where to write to 511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param c0 code unit to write 512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param c1 code unit to write 513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param c2 code unit to write 514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected static void write(AnnotatedOutput out, short c0, short c1, 516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project short c2) { 517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeShort(c0); 518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeShort(c1); 519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeShort(c2); 520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Writes four code units to the given output destination. 524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 52599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param out {@code non-null;} where to write to 526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param c0 code unit to write 527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param c1 code unit to write 528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param c2 code unit to write 529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param c3 code unit to write 530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected static void write(AnnotatedOutput out, short c0, short c1, 532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project short c2, short c3) { 533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeShort(c0); 534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeShort(c1); 535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeShort(c2); 536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeShort(c3); 537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Writes five code units to the given output destination. 541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 54299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param out {@code non-null;} where to write to 543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param c0 code unit to write 544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param c1 code unit to write 545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param c2 code unit to write 546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param c3 code unit to write 547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param c4 code unit to write 548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected static void write(AnnotatedOutput out, short c0, short c1, 550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project short c2, short c3, short c4) { 551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeShort(c0); 552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeShort(c1); 553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeShort(c2); 554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeShort(c3); 555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeShort(c4); 556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Writes six code units to the given output destination. 560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 56199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param out {@code non-null;} where to write to 562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param c0 code unit to write 563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param c1 code unit to write 564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param c2 code unit to write 565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param c3 code unit to write 566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param c4 code unit to write 567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param c5 code unit to write 568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected static void write(AnnotatedOutput out, short c0, short c1, 570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project short c2, short c3, short c4, short c5) { 571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeShort(c0); 572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeShort(c1); 573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeShort(c2); 574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeShort(c3); 575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeShort(c4); 576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.writeShort(c5); 577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 579