/** * Assigns registers to locals. From the spec: * "the N arguments to a method land in the last N registers of the * method's invocation frame, in order. Wide arguments consume two * registers. Instance methods are passed a this reference as their * first argument." * * In addition to assigning registers to each of the locals, this creates * instructions to move parameters into their initial registers. These * instructions are inserted before the code's first real instruction. */ void initializeLocals() { if (localsInitialized) { throw new AssertionError(); } localsInitialized = true; int reg = 0; for (Local<?> local : locals) { reg += local.initialize(reg); } int firstParamReg = reg; List<Insn> moveParameterInstructions = new ArrayList<Insn>(); for (Local<?> local : parameters) { CstInteger paramConstant = CstInteger.make(reg - firstParamReg); reg += local.initialize(reg); moveParameterInstructions.add(new PlainCstInsn(Rops.opMoveParam(local.type.ropType), sourcePosition, local.spec(), RegisterSpecList.EMPTY, paramConstant)); } labels.get(0).instructions.addAll(0, moveParameterInstructions); }
/** * Makes an instance for the given value. This may (but does not * necessarily) return an already-allocated instance. * * @param value the {@code int} value * @return {@code non-null;} the appropriate instance */ public static CstInteger make(int value) { /* * Note: No need to synchronize, since we don't make any sort * of guarantee about ==, and it's okay to overwrite existing * entries too. */ int idx = (value & 0x7fffffff) % cache.length; CstInteger obj = cache[idx]; if ((obj != null) && (obj.getValue() == value)) { return obj; } obj = new CstInteger(value); cache[idx] = obj; return obj; }
/** * Gets the {@code int} value. * * @return the value */ public int getValue() { return getIntBits(); } }
opcode.getOpcode() == RegOps.SUB) { CstInteger cst = (CstInteger) sourceA.getTypeBearer(); return cst.fitsIn16Bits(); } else { return false; case RegOps.OR: case RegOps.XOR: return cst.fitsIn16Bits(); return cst.fitsIn8Bits(); CstInteger cst2 = CstInteger.make(-cst.getValue()); return cst2.fitsIn16Bits(); default: return false;
/** * Helper method to extract the callout-argument index from an * appropriate instruction. * * @param insn {@code non-null;} the instruction * @return {@code >= 0;} the callout argument index */ protected static int argIndex(DalvInsn insn) { int arg = ((CstInteger) ((CstInsn) insn).getConstant()).getValue(); if (arg < 0) { throw new IllegalArgumentException("bogus insn"); } return arg; }
/** {@inheritDoc} */ public boolean hasConstantOperation(Rop opcode, RegisterSpec sourceA, RegisterSpec sourceB) { if (sourceA.getType() != Type.INT) { return false; } if (! (sourceB.getTypeBearer() instanceof CstInteger)) { return false; } CstInteger cst = (CstInteger) sourceB.getTypeBearer(); // TODO handle rsub switch (opcode.getOpcode()) { // These have 8 and 16 bit cst representations case RegOps.REM: case RegOps.ADD: case RegOps.MUL: case RegOps.DIV: case RegOps.AND: case RegOps.OR: case RegOps.XOR: return cst.fitsIn16Bits(); // These only have 8 bit cst reps case RegOps.SHL: case RegOps.SHR: case RegOps.USHR: return cst.fitsIn8Bits(); default: return false; } }
opcode.getOpcode() == RegOps.SUB) { CstInteger cst = (CstInteger) sourceA.getTypeBearer(); return cst.fitsIn16Bits(); } else { return false; case RegOps.OR: case RegOps.XOR: return cst.fitsIn16Bits(); return cst.fitsIn8Bits(); CstInteger cst2 = CstInteger.make(-cst.getValue()); return cst2.fitsIn16Bits(); default: return false;
/** * Helper method to extract the callout-argument index from an * appropriate instruction. * * @param insn {@code non-null;} the instruction * @return {@code >= 0;} the callout argument index */ protected static int argIndex(DalvInsn insn) { int arg = ((CstInteger) ((CstInsn) insn).getConstant()).getValue(); if (arg < 0) { throw new IllegalArgumentException("bogus insn"); } return arg; }
opcode.getOpcode() == RegOps.SUB) { CstInteger cst = (CstInteger) sourceA.getTypeBearer(); return cst.fitsIn16Bits(); } else { return false; case RegOps.OR: case RegOps.XOR: return cst.fitsIn16Bits(); return cst.fitsIn8Bits(); CstInteger cst2 = CstInteger.make(-cst.getValue()); return cst2.fitsIn16Bits(); default: return false;
/** * Helper method to extract the callout-argument index from an * appropriate instruction. * * @param insn {@code non-null;} the instruction * @return {@code >= 0;} the callout argument index */ protected static int argIndex(DalvInsn insn) { int arg = ((CstInteger) ((CstInsn) insn).getConstant()).getValue(); if (arg < 0) { throw new IllegalArgumentException("bogus insn"); } return arg; }
/** * Makes an instance for the given value. This may (but does not * necessarily) return an already-allocated instance. * * @param value the {@code int} value * @return {@code non-null;} the appropriate instance */ public static CstInteger make(int value) { /* * Note: No need to synchronize, since we don't make any sort * of guarantee about ==, and it's okay to overwrite existing * entries too. */ int idx = (value & 0x7fffffff) % cache.length; CstInteger obj = cache[idx]; if ((obj != null) && (obj.getValue() == value)) { return obj; } obj = new CstInteger(value); cache[idx] = obj; return obj; }
return CstFloat.make(Float.floatToIntBits((Float) value)); } else if (value instanceof Integer) { return CstInteger.make((Integer) value); } else if (value instanceof Long) { return CstLong.make((Long) value);
/** * Gets the {@code int} value. * * @return the value */ public int getValue() { return getIntBits(); } }
opcode.getOpcode() == RegOps.SUB) { CstInteger cst = (CstInteger) sourceA.getTypeBearer(); return cst.fitsIn16Bits(); } else { return false; case RegOps.OR: case RegOps.XOR: return cst.fitsIn16Bits(); return cst.fitsIn8Bits(); CstInteger cst2 = CstInteger.make(-cst.getValue()); return cst2.fitsIn16Bits(); default: return false;
/** * Helper method to extract the callout-argument index from an * appropriate instruction. * * @param insn {@code non-null;} the instruction * @return {@code >= 0;} the callout argument index */ protected static int argIndex(DalvInsn insn) { int arg = ((CstInteger) ((CstInsn) insn).getConstant()).getValue(); if (arg < 0) { throw new IllegalArgumentException("bogus insn"); } return arg; }
/** * Makes an instance for the given value. This may (but does not * necessarily) return an already-allocated instance. * * @param value the {@code int} value * @return {@code non-null;} the appropriate instance */ public static CstInteger make(int value) { /* * Note: No need to synchronize, since we don't make any sort * of guarantee about ==, and it's okay to overwrite existing * entries too. */ int idx = (value & 0x7fffffff) % cache.length; CstInteger obj = cache[idx]; if ((obj != null) && (obj.getValue() == value)) { return obj; } obj = new CstInteger(value); cache[idx] = obj; return obj; }