twisti@2047: /* stefank@2314: * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. twisti@2047: * Copyright 2008, 2009, 2010 Red Hat, Inc. twisti@2047: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. twisti@2047: * twisti@2047: * This code is free software; you can redistribute it and/or modify it twisti@2047: * under the terms of the GNU General Public License version 2 only, as twisti@2047: * published by the Free Software Foundation. twisti@2047: * twisti@2047: * This code is distributed in the hope that it will be useful, but WITHOUT twisti@2047: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or twisti@2047: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License twisti@2047: * version 2 for more details (a copy is included in the LICENSE file that twisti@2047: * accompanied this code). twisti@2047: * twisti@2047: * You should have received a copy of the GNU General Public License version twisti@2047: * 2 along with this work; if not, write to the Free Software Foundation, twisti@2047: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. twisti@2047: * twisti@2047: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA twisti@2047: * or visit www.oracle.com if you need additional information or have any twisti@2047: * questions. twisti@2047: * twisti@2047: */ twisti@2047: stefank@2314: #include "precompiled.hpp" stefank@2314: #include "interpreter/bytecodes.hpp" stefank@2314: #include "shark/llvmHeaders.hpp" stefank@2314: #include "shark/llvmValue.hpp" stefank@2314: #include "shark/sharkBlock.hpp" stefank@2314: #include "shark/sharkBuilder.hpp" stefank@2314: #include "shark/sharkConstant.hpp" stefank@2314: #include "shark/sharkState.hpp" stefank@2314: #include "shark/sharkValue.hpp" stefank@2314: #include "shark/shark_globals.hpp" stefank@2314: #include "utilities/debug.hpp" twisti@2047: twisti@2047: using namespace llvm; twisti@2047: twisti@2047: void SharkBlock::parse_bytecode(int start, int limit) { twisti@2047: SharkValue *a, *b, *c, *d; twisti@2047: int i; twisti@2047: twisti@2047: // Ensure the current state is initialized before we emit any code, twisti@2047: // so that any setup code for the state is at the start of the block twisti@2047: current_state(); twisti@2047: twisti@2047: // Parse the bytecodes twisti@2047: iter()->reset_to_bci(start); twisti@2047: while (iter()->next_bci() < limit) { twisti@2047: NOT_PRODUCT(a = b = c = d = NULL); twisti@2047: iter()->next(); twisti@2047: twisti@2047: if (SharkTraceBytecodes) twisti@2047: tty->print_cr("%4d: %s", bci(), Bytecodes::name(bc())); twisti@2047: twisti@2047: if (has_trap() && trap_bci() == bci()) { twisti@2047: do_trap(trap_request()); twisti@2047: return; twisti@2047: } twisti@2047: twisti@2047: if (UseLoopSafepoints) { twisti@2047: // XXX if a lcmp is followed by an if_?? then C2 maybe-inserts twisti@2047: // the safepoint before the lcmp rather than before the if. twisti@2047: // Maybe we should do this too. See parse2.cpp for details. twisti@2047: switch (bc()) { twisti@2047: case Bytecodes::_goto: twisti@2047: case Bytecodes::_ifnull: twisti@2047: case Bytecodes::_ifnonnull: twisti@2047: case Bytecodes::_if_acmpeq: twisti@2047: case Bytecodes::_if_acmpne: twisti@2047: case Bytecodes::_ifeq: twisti@2047: case Bytecodes::_ifne: twisti@2047: case Bytecodes::_iflt: twisti@2047: case Bytecodes::_ifle: twisti@2047: case Bytecodes::_ifgt: twisti@2047: case Bytecodes::_ifge: twisti@2047: case Bytecodes::_if_icmpeq: twisti@2047: case Bytecodes::_if_icmpne: twisti@2047: case Bytecodes::_if_icmplt: twisti@2047: case Bytecodes::_if_icmple: twisti@2047: case Bytecodes::_if_icmpgt: twisti@2047: case Bytecodes::_if_icmpge: twisti@2047: if (iter()->get_dest() <= bci()) twisti@2047: maybe_add_backedge_safepoint(); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_goto_w: twisti@2047: if (iter()->get_far_dest() <= bci()) twisti@2047: maybe_add_backedge_safepoint(); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_tableswitch: twisti@2047: case Bytecodes::_lookupswitch: twisti@2047: if (switch_default_dest() <= bci()) { twisti@2047: maybe_add_backedge_safepoint(); twisti@2047: break; twisti@2047: } twisti@2047: int len = switch_table_length(); twisti@2047: for (int i = 0; i < len; i++) { twisti@2047: if (switch_dest(i) <= bci()) { twisti@2047: maybe_add_backedge_safepoint(); twisti@2047: break; twisti@2047: } twisti@2047: } twisti@2047: break; twisti@2047: } twisti@2047: } twisti@2047: twisti@2047: switch (bc()) { twisti@2047: case Bytecodes::_nop: twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_aconst_null: twisti@2047: push(SharkValue::null()); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_iconst_m1: twisti@2047: push(SharkValue::jint_constant(-1)); twisti@2047: break; twisti@2047: case Bytecodes::_iconst_0: twisti@2047: push(SharkValue::jint_constant(0)); twisti@2047: break; twisti@2047: case Bytecodes::_iconst_1: twisti@2047: push(SharkValue::jint_constant(1)); twisti@2047: break; twisti@2047: case Bytecodes::_iconst_2: twisti@2047: push(SharkValue::jint_constant(2)); twisti@2047: break; twisti@2047: case Bytecodes::_iconst_3: twisti@2047: push(SharkValue::jint_constant(3)); twisti@2047: break; twisti@2047: case Bytecodes::_iconst_4: twisti@2047: push(SharkValue::jint_constant(4)); twisti@2047: break; twisti@2047: case Bytecodes::_iconst_5: twisti@2047: push(SharkValue::jint_constant(5)); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_lconst_0: twisti@2047: push(SharkValue::jlong_constant(0)); twisti@2047: break; twisti@2047: case Bytecodes::_lconst_1: twisti@2047: push(SharkValue::jlong_constant(1)); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_fconst_0: twisti@2047: push(SharkValue::jfloat_constant(0)); twisti@2047: break; twisti@2047: case Bytecodes::_fconst_1: twisti@2047: push(SharkValue::jfloat_constant(1)); twisti@2047: break; twisti@2047: case Bytecodes::_fconst_2: twisti@2047: push(SharkValue::jfloat_constant(2)); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_dconst_0: twisti@2047: push(SharkValue::jdouble_constant(0)); twisti@2047: break; twisti@2047: case Bytecodes::_dconst_1: twisti@2047: push(SharkValue::jdouble_constant(1)); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_bipush: twisti@2047: push(SharkValue::jint_constant(iter()->get_constant_u1())); twisti@2047: break; twisti@2047: case Bytecodes::_sipush: twisti@2047: push(SharkValue::jint_constant(iter()->get_constant_u2())); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_ldc: twisti@2047: case Bytecodes::_ldc_w: twisti@4314: case Bytecodes::_ldc2_w: { twisti@4314: SharkConstant* constant = SharkConstant::for_ldc(iter()); twisti@4314: assert(constant->is_loaded(), "trap should handle unloaded classes"); twisti@4314: push(constant->value(builder())); twisti@2047: break; twisti@4314: } twisti@2047: case Bytecodes::_iload_0: twisti@2047: case Bytecodes::_lload_0: twisti@2047: case Bytecodes::_fload_0: twisti@2047: case Bytecodes::_dload_0: twisti@2047: case Bytecodes::_aload_0: twisti@2047: push(local(0)); twisti@2047: break; twisti@2047: case Bytecodes::_iload_1: twisti@2047: case Bytecodes::_lload_1: twisti@2047: case Bytecodes::_fload_1: twisti@2047: case Bytecodes::_dload_1: twisti@2047: case Bytecodes::_aload_1: twisti@2047: push(local(1)); twisti@2047: break; twisti@2047: case Bytecodes::_iload_2: twisti@2047: case Bytecodes::_lload_2: twisti@2047: case Bytecodes::_fload_2: twisti@2047: case Bytecodes::_dload_2: twisti@2047: case Bytecodes::_aload_2: twisti@2047: push(local(2)); twisti@2047: break; twisti@2047: case Bytecodes::_iload_3: twisti@2047: case Bytecodes::_lload_3: twisti@2047: case Bytecodes::_fload_3: twisti@2047: case Bytecodes::_dload_3: twisti@2047: case Bytecodes::_aload_3: twisti@2047: push(local(3)); twisti@2047: break; twisti@2047: case Bytecodes::_iload: twisti@2047: case Bytecodes::_lload: twisti@2047: case Bytecodes::_fload: twisti@2047: case Bytecodes::_dload: twisti@2047: case Bytecodes::_aload: twisti@2047: push(local(iter()->get_index())); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_baload: twisti@2047: do_aload(T_BYTE); twisti@2047: break; twisti@2047: case Bytecodes::_caload: twisti@2047: do_aload(T_CHAR); twisti@2047: break; twisti@2047: case Bytecodes::_saload: twisti@2047: do_aload(T_SHORT); twisti@2047: break; twisti@2047: case Bytecodes::_iaload: twisti@2047: do_aload(T_INT); twisti@2047: break; twisti@2047: case Bytecodes::_laload: twisti@2047: do_aload(T_LONG); twisti@2047: break; twisti@2047: case Bytecodes::_faload: twisti@2047: do_aload(T_FLOAT); twisti@2047: break; twisti@2047: case Bytecodes::_daload: twisti@2047: do_aload(T_DOUBLE); twisti@2047: break; twisti@2047: case Bytecodes::_aaload: twisti@2047: do_aload(T_OBJECT); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_istore_0: twisti@2047: case Bytecodes::_lstore_0: twisti@2047: case Bytecodes::_fstore_0: twisti@2047: case Bytecodes::_dstore_0: twisti@2047: case Bytecodes::_astore_0: twisti@2047: set_local(0, pop()); twisti@2047: break; twisti@2047: case Bytecodes::_istore_1: twisti@2047: case Bytecodes::_lstore_1: twisti@2047: case Bytecodes::_fstore_1: twisti@2047: case Bytecodes::_dstore_1: twisti@2047: case Bytecodes::_astore_1: twisti@2047: set_local(1, pop()); twisti@2047: break; twisti@2047: case Bytecodes::_istore_2: twisti@2047: case Bytecodes::_lstore_2: twisti@2047: case Bytecodes::_fstore_2: twisti@2047: case Bytecodes::_dstore_2: twisti@2047: case Bytecodes::_astore_2: twisti@2047: set_local(2, pop()); twisti@2047: break; twisti@2047: case Bytecodes::_istore_3: twisti@2047: case Bytecodes::_lstore_3: twisti@2047: case Bytecodes::_fstore_3: twisti@2047: case Bytecodes::_dstore_3: twisti@2047: case Bytecodes::_astore_3: twisti@2047: set_local(3, pop()); twisti@2047: break; twisti@2047: case Bytecodes::_istore: twisti@2047: case Bytecodes::_lstore: twisti@2047: case Bytecodes::_fstore: twisti@2047: case Bytecodes::_dstore: twisti@2047: case Bytecodes::_astore: twisti@2047: set_local(iter()->get_index(), pop()); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_bastore: twisti@2047: do_astore(T_BYTE); twisti@2047: break; twisti@2047: case Bytecodes::_castore: twisti@2047: do_astore(T_CHAR); twisti@2047: break; twisti@2047: case Bytecodes::_sastore: twisti@2047: do_astore(T_SHORT); twisti@2047: break; twisti@2047: case Bytecodes::_iastore: twisti@2047: do_astore(T_INT); twisti@2047: break; twisti@2047: case Bytecodes::_lastore: twisti@2047: do_astore(T_LONG); twisti@2047: break; twisti@2047: case Bytecodes::_fastore: twisti@2047: do_astore(T_FLOAT); twisti@2047: break; twisti@2047: case Bytecodes::_dastore: twisti@2047: do_astore(T_DOUBLE); twisti@2047: break; twisti@2047: case Bytecodes::_aastore: twisti@2047: do_astore(T_OBJECT); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_pop: twisti@2047: xpop(); twisti@2047: break; twisti@2047: case Bytecodes::_pop2: twisti@2047: xpop(); twisti@2047: xpop(); twisti@2047: break; twisti@2047: case Bytecodes::_swap: twisti@2047: a = xpop(); twisti@2047: b = xpop(); twisti@2047: xpush(a); twisti@2047: xpush(b); twisti@2047: break; twisti@2047: case Bytecodes::_dup: twisti@2047: a = xpop(); twisti@2047: xpush(a); twisti@2047: xpush(a); twisti@2047: break; twisti@2047: case Bytecodes::_dup_x1: twisti@2047: a = xpop(); twisti@2047: b = xpop(); twisti@2047: xpush(a); twisti@2047: xpush(b); twisti@2047: xpush(a); twisti@2047: break; twisti@2047: case Bytecodes::_dup_x2: twisti@2047: a = xpop(); twisti@2047: b = xpop(); twisti@2047: c = xpop(); twisti@2047: xpush(a); twisti@2047: xpush(c); twisti@2047: xpush(b); twisti@2047: xpush(a); twisti@2047: break; twisti@2047: case Bytecodes::_dup2: twisti@2047: a = xpop(); twisti@2047: b = xpop(); twisti@2047: xpush(b); twisti@2047: xpush(a); twisti@2047: xpush(b); twisti@2047: xpush(a); twisti@2047: break; twisti@2047: case Bytecodes::_dup2_x1: twisti@2047: a = xpop(); twisti@2047: b = xpop(); twisti@2047: c = xpop(); twisti@2047: xpush(b); twisti@2047: xpush(a); twisti@2047: xpush(c); twisti@2047: xpush(b); twisti@2047: xpush(a); twisti@2047: break; twisti@2047: case Bytecodes::_dup2_x2: twisti@2047: a = xpop(); twisti@2047: b = xpop(); twisti@2047: c = xpop(); twisti@2047: d = xpop(); twisti@2047: xpush(b); twisti@2047: xpush(a); twisti@2047: xpush(d); twisti@2047: xpush(c); twisti@2047: xpush(b); twisti@2047: xpush(a); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_arraylength: twisti@2047: do_arraylength(); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_getfield: twisti@2047: do_getfield(); twisti@2047: break; twisti@2047: case Bytecodes::_getstatic: twisti@2047: do_getstatic(); twisti@2047: break; twisti@2047: case Bytecodes::_putfield: twisti@2047: do_putfield(); twisti@2047: break; twisti@2047: case Bytecodes::_putstatic: twisti@2047: do_putstatic(); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_iadd: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jint( twisti@2047: builder()->CreateAdd(a->jint_value(), b->jint_value()), false)); twisti@2047: break; twisti@2047: case Bytecodes::_isub: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jint( twisti@2047: builder()->CreateSub(a->jint_value(), b->jint_value()), false)); twisti@2047: break; twisti@2047: case Bytecodes::_imul: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jint( twisti@2047: builder()->CreateMul(a->jint_value(), b->jint_value()), false)); twisti@2047: break; twisti@2047: case Bytecodes::_idiv: twisti@2047: do_idiv(); twisti@2047: break; twisti@2047: case Bytecodes::_irem: twisti@2047: do_irem(); twisti@2047: break; twisti@2047: case Bytecodes::_ineg: twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jint( twisti@2047: builder()->CreateNeg(a->jint_value()), a->zero_checked())); twisti@2047: break; twisti@2047: case Bytecodes::_ishl: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jint( twisti@2047: builder()->CreateShl( twisti@2047: a->jint_value(), twisti@2047: builder()->CreateAnd( twisti@2047: b->jint_value(), LLVMValue::jint_constant(0x1f))), false)); twisti@2047: break; twisti@2047: case Bytecodes::_ishr: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jint( twisti@2047: builder()->CreateAShr( twisti@2047: a->jint_value(), twisti@2047: builder()->CreateAnd( twisti@2047: b->jint_value(), LLVMValue::jint_constant(0x1f))), false)); twisti@2047: break; twisti@2047: case Bytecodes::_iushr: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jint( twisti@2047: builder()->CreateLShr( twisti@2047: a->jint_value(), twisti@2047: builder()->CreateAnd( twisti@2047: b->jint_value(), LLVMValue::jint_constant(0x1f))), false)); twisti@2047: break; twisti@2047: case Bytecodes::_iand: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jint( twisti@2047: builder()->CreateAnd(a->jint_value(), b->jint_value()), false)); twisti@2047: break; twisti@2047: case Bytecodes::_ior: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jint( twisti@2047: builder()->CreateOr(a->jint_value(), b->jint_value()), twisti@2047: a->zero_checked() && b->zero_checked())); twisti@2047: break; twisti@2047: case Bytecodes::_ixor: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jint( twisti@2047: builder()->CreateXor(a->jint_value(), b->jint_value()), false)); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_ladd: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jlong( twisti@2047: builder()->CreateAdd(a->jlong_value(), b->jlong_value()), false)); twisti@2047: break; twisti@2047: case Bytecodes::_lsub: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jlong( twisti@2047: builder()->CreateSub(a->jlong_value(), b->jlong_value()), false)); twisti@2047: break; twisti@2047: case Bytecodes::_lmul: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jlong( twisti@2047: builder()->CreateMul(a->jlong_value(), b->jlong_value()), false)); twisti@2047: break; twisti@2047: case Bytecodes::_ldiv: twisti@2047: do_ldiv(); twisti@2047: break; twisti@2047: case Bytecodes::_lrem: twisti@2047: do_lrem(); twisti@2047: break; twisti@2047: case Bytecodes::_lneg: twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jlong( twisti@2047: builder()->CreateNeg(a->jlong_value()), a->zero_checked())); twisti@2047: break; twisti@2047: case Bytecodes::_lshl: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jlong( twisti@2047: builder()->CreateShl( twisti@2047: a->jlong_value(), twisti@2047: builder()->CreateIntCast( twisti@2047: builder()->CreateAnd( twisti@2047: b->jint_value(), LLVMValue::jint_constant(0x3f)), twisti@2047: SharkType::jlong_type(), true)), false)); twisti@2047: break; twisti@2047: case Bytecodes::_lshr: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jlong( twisti@2047: builder()->CreateAShr( twisti@2047: a->jlong_value(), twisti@2047: builder()->CreateIntCast( twisti@2047: builder()->CreateAnd( twisti@2047: b->jint_value(), LLVMValue::jint_constant(0x3f)), twisti@2047: SharkType::jlong_type(), true)), false)); twisti@2047: break; twisti@2047: case Bytecodes::_lushr: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jlong( twisti@2047: builder()->CreateLShr( twisti@2047: a->jlong_value(), twisti@2047: builder()->CreateIntCast( twisti@2047: builder()->CreateAnd( twisti@2047: b->jint_value(), LLVMValue::jint_constant(0x3f)), twisti@2047: SharkType::jlong_type(), true)), false)); twisti@2047: break; twisti@2047: case Bytecodes::_land: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jlong( twisti@2047: builder()->CreateAnd(a->jlong_value(), b->jlong_value()), false)); twisti@2047: break; twisti@2047: case Bytecodes::_lor: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jlong( twisti@2047: builder()->CreateOr(a->jlong_value(), b->jlong_value()), twisti@2047: a->zero_checked() && b->zero_checked())); twisti@2047: break; twisti@2047: case Bytecodes::_lxor: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jlong( twisti@2047: builder()->CreateXor(a->jlong_value(), b->jlong_value()), false)); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_fadd: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jfloat( twisti@2047: builder()->CreateFAdd(a->jfloat_value(), b->jfloat_value()))); twisti@2047: break; twisti@2047: case Bytecodes::_fsub: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jfloat( twisti@2047: builder()->CreateFSub(a->jfloat_value(), b->jfloat_value()))); twisti@2047: break; twisti@2047: case Bytecodes::_fmul: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jfloat( twisti@2047: builder()->CreateFMul(a->jfloat_value(), b->jfloat_value()))); twisti@2047: break; twisti@2047: case Bytecodes::_fdiv: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jfloat( twisti@2047: builder()->CreateFDiv(a->jfloat_value(), b->jfloat_value()))); twisti@2047: break; twisti@2047: case Bytecodes::_frem: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jfloat( twisti@2047: builder()->CreateFRem(a->jfloat_value(), b->jfloat_value()))); twisti@2047: break; twisti@2047: case Bytecodes::_fneg: twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jfloat( twisti@2047: builder()->CreateFNeg(a->jfloat_value()))); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_dadd: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jdouble( twisti@2047: builder()->CreateFAdd(a->jdouble_value(), b->jdouble_value()))); twisti@2047: break; twisti@2047: case Bytecodes::_dsub: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jdouble( twisti@2047: builder()->CreateFSub(a->jdouble_value(), b->jdouble_value()))); twisti@2047: break; twisti@2047: case Bytecodes::_dmul: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jdouble( twisti@2047: builder()->CreateFMul(a->jdouble_value(), b->jdouble_value()))); twisti@2047: break; twisti@2047: case Bytecodes::_ddiv: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jdouble( twisti@2047: builder()->CreateFDiv(a->jdouble_value(), b->jdouble_value()))); twisti@2047: break; twisti@2047: case Bytecodes::_drem: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jdouble( twisti@2047: builder()->CreateFRem(a->jdouble_value(), b->jdouble_value()))); twisti@2047: break; twisti@2047: case Bytecodes::_dneg: twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jdouble( twisti@2047: builder()->CreateFNeg(a->jdouble_value()))); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_iinc: twisti@2047: i = iter()->get_index(); twisti@2047: set_local( twisti@2047: i, twisti@2047: SharkValue::create_jint( twisti@2047: builder()->CreateAdd( twisti@2047: LLVMValue::jint_constant(iter()->get_iinc_con()), twisti@2047: local(i)->jint_value()), false)); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_lcmp: twisti@2047: do_lcmp(); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_fcmpl: twisti@2047: do_fcmp(false, false); twisti@2047: break; twisti@2047: case Bytecodes::_fcmpg: twisti@2047: do_fcmp(false, true); twisti@2047: break; twisti@2047: case Bytecodes::_dcmpl: twisti@2047: do_fcmp(true, false); twisti@2047: break; twisti@2047: case Bytecodes::_dcmpg: twisti@2047: do_fcmp(true, true); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_i2l: twisti@2047: a = pop(); twisti@2047: push(SharkValue::create_jlong( twisti@2047: builder()->CreateIntCast( twisti@2047: a->jint_value(), SharkType::jlong_type(), true), a->zero_checked())); twisti@2047: break; twisti@2047: case Bytecodes::_i2f: twisti@2047: push(SharkValue::create_jfloat( twisti@2047: builder()->CreateSIToFP( twisti@2047: pop()->jint_value(), SharkType::jfloat_type()))); twisti@2047: break; twisti@2047: case Bytecodes::_i2d: twisti@2047: push(SharkValue::create_jdouble( twisti@2047: builder()->CreateSIToFP( twisti@2047: pop()->jint_value(), SharkType::jdouble_type()))); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_l2i: twisti@2047: push(SharkValue::create_jint( twisti@2047: builder()->CreateIntCast( twisti@2047: pop()->jlong_value(), SharkType::jint_type(), true), false)); twisti@2047: break; twisti@2047: case Bytecodes::_l2f: twisti@2047: push(SharkValue::create_jfloat( twisti@2047: builder()->CreateSIToFP( twisti@2047: pop()->jlong_value(), SharkType::jfloat_type()))); twisti@2047: break; twisti@2047: case Bytecodes::_l2d: twisti@2047: push(SharkValue::create_jdouble( twisti@2047: builder()->CreateSIToFP( twisti@2047: pop()->jlong_value(), SharkType::jdouble_type()))); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_f2i: twisti@2047: push(SharkValue::create_jint( twisti@2047: builder()->CreateCall( twisti@2047: builder()->f2i(), pop()->jfloat_value()), false)); twisti@2047: break; twisti@2047: case Bytecodes::_f2l: twisti@2047: push(SharkValue::create_jlong( twisti@2047: builder()->CreateCall( twisti@2047: builder()->f2l(), pop()->jfloat_value()), false)); twisti@2047: break; twisti@2047: case Bytecodes::_f2d: twisti@2047: push(SharkValue::create_jdouble( twisti@2047: builder()->CreateFPExt( twisti@2047: pop()->jfloat_value(), SharkType::jdouble_type()))); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_d2i: twisti@2047: push(SharkValue::create_jint( twisti@2047: builder()->CreateCall( twisti@2047: builder()->d2i(), pop()->jdouble_value()), false)); twisti@2047: break; twisti@2047: case Bytecodes::_d2l: twisti@2047: push(SharkValue::create_jlong( twisti@2047: builder()->CreateCall( twisti@2047: builder()->d2l(), pop()->jdouble_value()), false)); twisti@2047: break; twisti@2047: case Bytecodes::_d2f: twisti@2047: push(SharkValue::create_jfloat( twisti@2047: builder()->CreateFPTrunc( twisti@2047: pop()->jdouble_value(), SharkType::jfloat_type()))); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_i2b: twisti@2047: push(SharkValue::create_jint( twisti@2047: builder()->CreateAShr( twisti@2047: builder()->CreateShl( twisti@2047: pop()->jint_value(), twisti@2047: LLVMValue::jint_constant(24)), twisti@2047: LLVMValue::jint_constant(24)), false)); twisti@2047: break; twisti@2047: case Bytecodes::_i2c: twisti@2047: push(SharkValue::create_jint( twisti@2047: builder()->CreateAnd( twisti@2047: pop()->jint_value(), twisti@2047: LLVMValue::jint_constant(0xffff)), false)); twisti@2047: break; twisti@2047: case Bytecodes::_i2s: twisti@2047: push(SharkValue::create_jint( twisti@2047: builder()->CreateAShr( twisti@2047: builder()->CreateShl( twisti@2047: pop()->jint_value(), twisti@2047: LLVMValue::jint_constant(16)), twisti@2047: LLVMValue::jint_constant(16)), false)); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_return: twisti@2047: do_return(T_VOID); twisti@2047: break; twisti@2047: case Bytecodes::_ireturn: twisti@2047: do_return(T_INT); twisti@2047: break; twisti@2047: case Bytecodes::_lreturn: twisti@2047: do_return(T_LONG); twisti@2047: break; twisti@2047: case Bytecodes::_freturn: twisti@2047: do_return(T_FLOAT); twisti@2047: break; twisti@2047: case Bytecodes::_dreturn: twisti@2047: do_return(T_DOUBLE); twisti@2047: break; twisti@2047: case Bytecodes::_areturn: twisti@2047: do_return(T_OBJECT); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_athrow: twisti@2047: do_athrow(); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_goto: twisti@2047: case Bytecodes::_goto_w: twisti@2047: do_goto(); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_jsr: twisti@2047: case Bytecodes::_jsr_w: twisti@2047: do_jsr(); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_ret: twisti@2047: do_ret(); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_ifnull: twisti@2047: do_if(ICmpInst::ICMP_EQ, SharkValue::null(), pop()); twisti@2047: break; twisti@2047: case Bytecodes::_ifnonnull: twisti@2047: do_if(ICmpInst::ICMP_NE, SharkValue::null(), pop()); twisti@2047: break; twisti@2047: case Bytecodes::_if_acmpeq: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: do_if(ICmpInst::ICMP_EQ, b, a); twisti@2047: break; twisti@2047: case Bytecodes::_if_acmpne: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: do_if(ICmpInst::ICMP_NE, b, a); twisti@2047: break; twisti@2047: case Bytecodes::_ifeq: twisti@2047: do_if(ICmpInst::ICMP_EQ, SharkValue::jint_constant(0), pop()); twisti@2047: break; twisti@2047: case Bytecodes::_ifne: twisti@2047: do_if(ICmpInst::ICMP_NE, SharkValue::jint_constant(0), pop()); twisti@2047: break; twisti@2047: case Bytecodes::_iflt: twisti@2047: do_if(ICmpInst::ICMP_SLT, SharkValue::jint_constant(0), pop()); twisti@2047: break; twisti@2047: case Bytecodes::_ifle: twisti@2047: do_if(ICmpInst::ICMP_SLE, SharkValue::jint_constant(0), pop()); twisti@2047: break; twisti@2047: case Bytecodes::_ifgt: twisti@2047: do_if(ICmpInst::ICMP_SGT, SharkValue::jint_constant(0), pop()); twisti@2047: break; twisti@2047: case Bytecodes::_ifge: twisti@2047: do_if(ICmpInst::ICMP_SGE, SharkValue::jint_constant(0), pop()); twisti@2047: break; twisti@2047: case Bytecodes::_if_icmpeq: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: do_if(ICmpInst::ICMP_EQ, b, a); twisti@2047: break; twisti@2047: case Bytecodes::_if_icmpne: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: do_if(ICmpInst::ICMP_NE, b, a); twisti@2047: break; twisti@2047: case Bytecodes::_if_icmplt: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: do_if(ICmpInst::ICMP_SLT, b, a); twisti@2047: break; twisti@2047: case Bytecodes::_if_icmple: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: do_if(ICmpInst::ICMP_SLE, b, a); twisti@2047: break; twisti@2047: case Bytecodes::_if_icmpgt: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: do_if(ICmpInst::ICMP_SGT, b, a); twisti@2047: break; twisti@2047: case Bytecodes::_if_icmpge: twisti@2047: b = pop(); twisti@2047: a = pop(); twisti@2047: do_if(ICmpInst::ICMP_SGE, b, a); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_tableswitch: twisti@2047: case Bytecodes::_lookupswitch: twisti@2047: do_switch(); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_invokestatic: twisti@2047: case Bytecodes::_invokespecial: twisti@2047: case Bytecodes::_invokevirtual: twisti@2047: case Bytecodes::_invokeinterface: twisti@2047: do_call(); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_instanceof: twisti@2047: // This is a very common construct: twisti@2047: // twisti@2047: // if (object instanceof Klass) { twisti@2047: // something = (Klass) object; twisti@2047: // ... twisti@2047: // } twisti@2047: // twisti@2047: // which gets compiled to something like this: twisti@2047: // twisti@2047: // 28: aload 9 twisti@2047: // 30: instanceof twisti@2047: // 33: ifeq 52 twisti@2047: // 36: aload 9 twisti@2047: // 38: checkcast twisti@2047: // twisti@2047: // Handling both bytecodes at once allows us twisti@2047: // to eliminate the checkcast. twisti@2047: if (iter()->next_bci() < limit && twisti@2047: (iter()->next_bc() == Bytecodes::_ifeq || twisti@2047: iter()->next_bc() == Bytecodes::_ifne) && twisti@2047: (!UseLoopSafepoints || twisti@2047: iter()->next_get_dest() > iter()->next_bci())) { twisti@2047: if (maybe_do_instanceof_if()) { twisti@2047: iter()->next(); twisti@2047: if (SharkTraceBytecodes) twisti@2047: tty->print_cr("%4d: %s", bci(), Bytecodes::name(bc())); twisti@2047: break; twisti@2047: } twisti@2047: } twisti@2047: // fall through twisti@2047: case Bytecodes::_checkcast: twisti@2047: do_instance_check(); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_new: twisti@2047: do_new(); twisti@2047: break; twisti@2047: case Bytecodes::_newarray: twisti@2047: do_newarray(); twisti@2047: break; twisti@2047: case Bytecodes::_anewarray: twisti@2047: do_anewarray(); twisti@2047: break; twisti@2047: case Bytecodes::_multianewarray: twisti@2047: do_multianewarray(); twisti@2047: break; twisti@2047: twisti@2047: case Bytecodes::_monitorenter: twisti@2047: do_monitorenter(); twisti@2047: break; twisti@2047: case Bytecodes::_monitorexit: twisti@2047: do_monitorexit(); twisti@2047: break; twisti@2047: twisti@2047: default: twisti@2047: ShouldNotReachHere(); twisti@2047: } twisti@2047: } twisti@2047: } twisti@2047: twisti@2047: SharkState* SharkBlock::initial_current_state() { twisti@2047: return entry_state()->copy(); twisti@2047: } twisti@2047: twisti@2047: int SharkBlock::switch_default_dest() { twisti@2047: return iter()->get_dest_table(0); twisti@2047: } twisti@2047: twisti@2047: int SharkBlock::switch_table_length() { twisti@2047: switch(bc()) { twisti@2047: case Bytecodes::_tableswitch: twisti@2047: return iter()->get_int_table(2) - iter()->get_int_table(1) + 1; twisti@2047: twisti@2047: case Bytecodes::_lookupswitch: twisti@2047: return iter()->get_int_table(1); twisti@2047: twisti@2047: default: twisti@2047: ShouldNotReachHere(); twisti@2047: } twisti@2047: } twisti@2047: twisti@2047: int SharkBlock::switch_key(int i) { twisti@2047: switch(bc()) { twisti@2047: case Bytecodes::_tableswitch: twisti@2047: return iter()->get_int_table(1) + i; twisti@2047: twisti@2047: case Bytecodes::_lookupswitch: twisti@2047: return iter()->get_int_table(2 + 2 * i); twisti@2047: twisti@2047: default: twisti@2047: ShouldNotReachHere(); twisti@2047: } twisti@2047: } twisti@2047: twisti@2047: int SharkBlock::switch_dest(int i) { twisti@2047: switch(bc()) { twisti@2047: case Bytecodes::_tableswitch: twisti@2047: return iter()->get_dest_table(i + 3); twisti@2047: twisti@2047: case Bytecodes::_lookupswitch: twisti@2047: return iter()->get_dest_table(2 + 2 * i + 1); twisti@2047: twisti@2047: default: twisti@2047: ShouldNotReachHere(); twisti@2047: } twisti@2047: } twisti@2047: twisti@2047: void SharkBlock::do_div_or_rem(bool is_long, bool is_rem) { twisti@2047: SharkValue *sb = pop(); twisti@2047: SharkValue *sa = pop(); twisti@2047: twisti@2047: check_divide_by_zero(sb); twisti@2047: twisti@2047: Value *a, *b, *p, *q; twisti@2047: if (is_long) { twisti@2047: a = sa->jlong_value(); twisti@2047: b = sb->jlong_value(); twisti@2047: p = LLVMValue::jlong_constant(0x8000000000000000LL); twisti@2047: q = LLVMValue::jlong_constant(-1); twisti@2047: } twisti@2047: else { twisti@2047: a = sa->jint_value(); twisti@2047: b = sb->jint_value(); twisti@2047: p = LLVMValue::jint_constant(0x80000000); twisti@2047: q = LLVMValue::jint_constant(-1); twisti@2047: } twisti@2047: twisti@2047: BasicBlock *ip = builder()->GetBlockInsertionPoint(); twisti@2047: BasicBlock *special_case = builder()->CreateBlock(ip, "special_case"); twisti@2047: BasicBlock *general_case = builder()->CreateBlock(ip, "general_case"); twisti@2047: BasicBlock *done = builder()->CreateBlock(ip, "done"); twisti@2047: twisti@2047: builder()->CreateCondBr( twisti@2047: builder()->CreateAnd( twisti@2047: builder()->CreateICmpEQ(a, p), twisti@2047: builder()->CreateICmpEQ(b, q)), twisti@2047: special_case, general_case); twisti@2047: twisti@2047: builder()->SetInsertPoint(special_case); twisti@2047: Value *special_result; twisti@2047: if (is_rem) { twisti@2047: if (is_long) twisti@2047: special_result = LLVMValue::jlong_constant(0); twisti@2047: else twisti@2047: special_result = LLVMValue::jint_constant(0); twisti@2047: } twisti@2047: else { twisti@2047: special_result = a; twisti@2047: } twisti@2047: builder()->CreateBr(done); twisti@2047: twisti@2047: builder()->SetInsertPoint(general_case); twisti@2047: Value *general_result; twisti@2047: if (is_rem) twisti@2047: general_result = builder()->CreateSRem(a, b); twisti@2047: else twisti@2047: general_result = builder()->CreateSDiv(a, b); twisti@2047: builder()->CreateBr(done); twisti@2047: twisti@2047: builder()->SetInsertPoint(done); twisti@2047: PHINode *result; twisti@2047: if (is_long) twisti@4314: result = builder()->CreatePHI(SharkType::jlong_type(), 0, "result"); twisti@2047: else twisti@4314: result = builder()->CreatePHI(SharkType::jint_type(), 0, "result"); twisti@2047: result->addIncoming(special_result, special_case); twisti@2047: result->addIncoming(general_result, general_case); twisti@2047: twisti@2047: if (is_long) twisti@2047: push(SharkValue::create_jlong(result, false)); twisti@2047: else twisti@2047: push(SharkValue::create_jint(result, false)); twisti@2047: } twisti@2047: twisti@2047: void SharkBlock::do_field_access(bool is_get, bool is_field) { twisti@2047: bool will_link; twisti@2047: ciField *field = iter()->get_field(will_link); twisti@2047: assert(will_link, "typeflow responsibility"); twisti@2047: assert(is_field != field->is_static(), "mismatch"); twisti@2047: twisti@2047: // Pop the value off the stack where necessary twisti@2047: SharkValue *value = NULL; twisti@2047: if (!is_get) twisti@2047: value = pop(); twisti@2047: twisti@2047: // Find the object we're accessing, if necessary twisti@2047: Value *object = NULL; twisti@2047: if (is_field) { twisti@2047: SharkValue *value = pop(); twisti@2047: check_null(value); twisti@2047: object = value->generic_value(); twisti@2047: } twisti@4444: if (is_get && field->is_constant() && field->is_static()) { twisti@2047: SharkConstant *constant = SharkConstant::for_field(iter()); twisti@2047: if (constant->is_loaded()) twisti@2047: value = constant->value(builder()); twisti@2047: } twisti@2047: if (!is_get || value == NULL) { twisti@4314: if (!is_field) { twisti@4314: object = builder()->CreateInlineOop(field->holder()->java_mirror()); twisti@4314: } twisti@2047: BasicType basic_type = field->type()->basic_type(); twisti@4314: Type *stack_type = SharkType::to_stackType(basic_type); twisti@4314: Type *field_type = SharkType::to_arrayType(basic_type); twisti@4441: Type *type = field_type; twisti@4441: if (field->is_volatile()) { twisti@4441: if (field_type == SharkType::jfloat_type()) { twisti@4441: type = SharkType::jint_type(); twisti@4441: } else if (field_type == SharkType::jdouble_type()) { twisti@4441: type = SharkType::jlong_type(); twisti@4441: } twisti@4441: } twisti@2047: Value *addr = builder()->CreateAddressOfStructEntry( twisti@2047: object, in_ByteSize(field->offset_in_bytes()), twisti@4441: PointerType::getUnqual(type), twisti@2047: "addr"); twisti@2047: twisti@2047: // Do the access twisti@2047: if (is_get) { twisti@4314: Value* field_value; twisti@4314: if (field->is_volatile()) { twisti@4314: field_value = builder()->CreateAtomicLoad(addr); twisti@4441: field_value = builder()->CreateBitCast(field_value, field_type); twisti@4314: } else { twisti@4314: field_value = builder()->CreateLoad(addr); twisti@4314: } twisti@2047: if (field_type != stack_type) { twisti@2047: field_value = builder()->CreateIntCast( twisti@2047: field_value, stack_type, basic_type != T_CHAR); twisti@2047: } twisti@2047: twisti@2047: value = SharkValue::create_generic(field->type(), field_value, false); twisti@2047: } twisti@2047: else { twisti@2047: Value *field_value = value->generic_value(); twisti@2047: twisti@2047: if (field_type != stack_type) { twisti@2047: field_value = builder()->CreateIntCast( twisti@2047: field_value, field_type, basic_type != T_CHAR); twisti@2047: } twisti@2047: twisti@4314: if (field->is_volatile()) { twisti@4441: field_value = builder()->CreateBitCast(field_value, type); twisti@4314: builder()->CreateAtomicStore(field_value, addr); twisti@4314: } else { twisti@4314: builder()->CreateStore(field_value, addr); twisti@4314: } twisti@2047: twisti@4314: if (!field->type()->is_primitive_type()) { twisti@2047: builder()->CreateUpdateBarrierSet(oopDesc::bs(), addr); twisti@4314: } twisti@2047: } twisti@2047: } twisti@2047: twisti@2047: // Push the value onto the stack where necessary twisti@2047: if (is_get) twisti@2047: push(value); twisti@2047: } twisti@2047: twisti@2047: void SharkBlock::do_lcmp() { twisti@2047: Value *b = pop()->jlong_value(); twisti@2047: Value *a = pop()->jlong_value(); twisti@2047: twisti@2047: BasicBlock *ip = builder()->GetBlockInsertionPoint(); twisti@2047: BasicBlock *ne = builder()->CreateBlock(ip, "lcmp_ne"); twisti@2047: BasicBlock *lt = builder()->CreateBlock(ip, "lcmp_lt"); twisti@2047: BasicBlock *gt = builder()->CreateBlock(ip, "lcmp_gt"); twisti@2047: BasicBlock *done = builder()->CreateBlock(ip, "done"); twisti@2047: twisti@2047: BasicBlock *eq = builder()->GetInsertBlock(); twisti@2047: builder()->CreateCondBr(builder()->CreateICmpEQ(a, b), done, ne); twisti@2047: twisti@2047: builder()->SetInsertPoint(ne); twisti@2047: builder()->CreateCondBr(builder()->CreateICmpSLT(a, b), lt, gt); twisti@2047: twisti@2047: builder()->SetInsertPoint(lt); twisti@2047: builder()->CreateBr(done); twisti@2047: twisti@2047: builder()->SetInsertPoint(gt); twisti@2047: builder()->CreateBr(done); twisti@2047: twisti@2047: builder()->SetInsertPoint(done); twisti@4314: PHINode *result = builder()->CreatePHI(SharkType::jint_type(), 0, "result"); twisti@2047: result->addIncoming(LLVMValue::jint_constant(-1), lt); twisti@2047: result->addIncoming(LLVMValue::jint_constant(0), eq); twisti@2047: result->addIncoming(LLVMValue::jint_constant(1), gt); twisti@2047: twisti@2047: push(SharkValue::create_jint(result, false)); twisti@2047: } twisti@2047: twisti@2047: void SharkBlock::do_fcmp(bool is_double, bool unordered_is_greater) { twisti@2047: Value *a, *b; twisti@2047: if (is_double) { twisti@2047: b = pop()->jdouble_value(); twisti@2047: a = pop()->jdouble_value(); twisti@2047: } twisti@2047: else { twisti@2047: b = pop()->jfloat_value(); twisti@2047: a = pop()->jfloat_value(); twisti@2047: } twisti@2047: twisti@2047: BasicBlock *ip = builder()->GetBlockInsertionPoint(); twisti@2047: BasicBlock *ordered = builder()->CreateBlock(ip, "ordered"); twisti@2047: BasicBlock *ge = builder()->CreateBlock(ip, "fcmp_ge"); twisti@2047: BasicBlock *lt = builder()->CreateBlock(ip, "fcmp_lt"); twisti@2047: BasicBlock *eq = builder()->CreateBlock(ip, "fcmp_eq"); twisti@2047: BasicBlock *gt = builder()->CreateBlock(ip, "fcmp_gt"); twisti@2047: BasicBlock *done = builder()->CreateBlock(ip, "done"); twisti@2047: twisti@2047: builder()->CreateCondBr( twisti@2047: builder()->CreateFCmpUNO(a, b), twisti@2047: unordered_is_greater ? gt : lt, ordered); twisti@2047: twisti@2047: builder()->SetInsertPoint(ordered); twisti@2047: builder()->CreateCondBr(builder()->CreateFCmpULT(a, b), lt, ge); twisti@2047: twisti@2047: builder()->SetInsertPoint(ge); twisti@2047: builder()->CreateCondBr(builder()->CreateFCmpUGT(a, b), gt, eq); twisti@2047: twisti@2047: builder()->SetInsertPoint(lt); twisti@2047: builder()->CreateBr(done); twisti@2047: twisti@2047: builder()->SetInsertPoint(gt); twisti@2047: builder()->CreateBr(done); twisti@2047: twisti@2047: builder()->SetInsertPoint(eq); twisti@2047: builder()->CreateBr(done); twisti@2047: twisti@2047: builder()->SetInsertPoint(done); twisti@4314: PHINode *result = builder()->CreatePHI(SharkType::jint_type(), 0, "result"); twisti@2047: result->addIncoming(LLVMValue::jint_constant(-1), lt); twisti@2047: result->addIncoming(LLVMValue::jint_constant(0), eq); twisti@2047: result->addIncoming(LLVMValue::jint_constant(1), gt); twisti@2047: twisti@2047: push(SharkValue::create_jint(result, false)); twisti@2047: } twisti@2047: twisti@2047: void SharkBlock::emit_IR() { twisti@2047: ShouldNotCallThis(); twisti@2047: } twisti@2047: twisti@2047: SharkState* SharkBlock::entry_state() { twisti@2047: ShouldNotCallThis(); twisti@2047: } twisti@2047: twisti@2047: void SharkBlock::do_zero_check(SharkValue* value) { twisti@2047: ShouldNotCallThis(); twisti@2047: } twisti@2047: twisti@2047: void SharkBlock::maybe_add_backedge_safepoint() { twisti@2047: ShouldNotCallThis(); twisti@2047: } twisti@2047: twisti@2047: bool SharkBlock::has_trap() { twisti@2047: return false; twisti@2047: } twisti@2047: twisti@2047: int SharkBlock::trap_request() { twisti@2047: ShouldNotCallThis(); twisti@2047: } twisti@2047: twisti@2047: int SharkBlock::trap_bci() { twisti@2047: ShouldNotCallThis(); twisti@2047: } twisti@2047: twisti@2047: void SharkBlock::do_trap(int trap_request) { twisti@2047: ShouldNotCallThis(); twisti@2047: } twisti@2047: twisti@2047: void SharkBlock::do_arraylength() { twisti@2047: ShouldNotCallThis(); twisti@2047: } twisti@2047: twisti@2047: void SharkBlock::do_aload(BasicType basic_type) { twisti@2047: ShouldNotCallThis(); twisti@2047: } twisti@2047: twisti@2047: void SharkBlock::do_astore(BasicType basic_type) { twisti@2047: ShouldNotCallThis(); twisti@2047: } twisti@2047: twisti@2047: void SharkBlock::do_return(BasicType type) { twisti@2047: ShouldNotCallThis(); twisti@2047: } twisti@2047: twisti@2047: void SharkBlock::do_athrow() { twisti@2047: ShouldNotCallThis(); twisti@2047: } twisti@2047: twisti@2047: void SharkBlock::do_goto() { twisti@2047: ShouldNotCallThis(); twisti@2047: } twisti@2047: twisti@2047: void SharkBlock::do_jsr() { twisti@2047: ShouldNotCallThis(); twisti@2047: } twisti@2047: twisti@2047: void SharkBlock::do_ret() { twisti@2047: ShouldNotCallThis(); twisti@2047: } twisti@2047: twisti@2047: void SharkBlock::do_if(ICmpInst::Predicate p, SharkValue* b, SharkValue* a) { twisti@2047: ShouldNotCallThis(); twisti@2047: } twisti@2047: twisti@2047: void SharkBlock::do_switch() { twisti@2047: ShouldNotCallThis(); twisti@2047: } twisti@2047: twisti@2047: void SharkBlock::do_call() { twisti@2047: ShouldNotCallThis(); twisti@2047: } twisti@2047: twisti@2047: void SharkBlock::do_instance_check() { twisti@2047: ShouldNotCallThis(); twisti@2047: } twisti@2047: twisti@2047: bool SharkBlock::maybe_do_instanceof_if() { twisti@2047: ShouldNotCallThis(); twisti@2047: } twisti@2047: twisti@2047: void SharkBlock::do_new() { twisti@2047: ShouldNotCallThis(); twisti@2047: } twisti@2047: twisti@2047: void SharkBlock::do_newarray() { twisti@2047: ShouldNotCallThis(); twisti@2047: } twisti@2047: twisti@2047: void SharkBlock::do_anewarray() { twisti@2047: ShouldNotCallThis(); twisti@2047: } twisti@2047: twisti@2047: void SharkBlock::do_multianewarray() { twisti@2047: ShouldNotCallThis(); twisti@2047: } twisti@2047: twisti@2047: void SharkBlock::do_monitorenter() { twisti@2047: ShouldNotCallThis(); twisti@2047: } twisti@2047: twisti@2047: void SharkBlock::do_monitorexit() { twisti@2047: ShouldNotCallThis(); twisti@2047: }