Ejemplo n.º 1
0
// Print this EntryActivation and all other EntryActivation's that follow it.
void EntryActivation::print_list_on(Stream* st, int indent, int index) {
#if USE_DEBUG_PRINTING
  int last_indent = st->indentation();
  st->set_indentation(indent);
  st->indent();

  st->print("[%d] ", index);
  Method m = method();
  m.print_value_on(st);
  st->cr();

  for (int i = 0; i < length(); i++) {
    st->indent();
    st->print("    ");

    switch(tag_at(i)) { 
    case float_tag:
      st->print("(float)  %f", jvm_f2d(float_at(i)));
      break;
    case double_tag:
      st->print("(double)  %d", double_at(i));
      i++;
      break;
    case long_tag:
      st->print("(long)   ");
      st->print(OsMisc_jlong_format_specifier(), long_at(i));
      i++;
      break;
    case obj_tag:
      {
        st->print("(obj)  ");
        Oop obj = obj_at(i);
        obj.print_value_on(st);
      }
      break;
    case int_tag:
      st->print("(int)    %d", int_at(i));
      break;
    default:
      SHOULD_NOT_REACH_HERE();
    }
    st->cr();
  }

  EntryActivation mynext = next();
  if (mynext.not_null()) {
    mynext.print_list_on(st, indent, index+1);
  }
  st->set_indentation(last_indent);
#endif
}
Ejemplo n.º 2
0
RawLocation::Actions 
RawLocation::do_conform_to(int my_index, RawLocation* other, int other_index, 
                           RawLocation::Actions allowed_actions) {
  // make sure object registers and locations have object values 
  if (other->stack_type() == T_OBJECT && stack_type() != T_OBJECT) {
    // Conformance code makes it so that this is no longer necessary.
    SHOULD_NOT_REACH_HERE();

#if NOT_CURRENTLY_USED
    // if we clear an cached object location there's no need to clear
    // any registers, since the register cache (due to type conflicts) is 
    // guaranteed never to be used again
    if (other.is_flushed() || other.is_cached()) {
      code_generator()->clear_object_location(index());
    } else {
      GUARANTEE(other.is_changed(), "only case left");
      Value other_value(other.type());
      other.read_value(other_value);
      Oop::Raw null_obj;      
      code_generator()->move(other_value, &null_obj);
    }
    return;
#endif
  }
  // compute the merge action
  const Actions required_actions = merge_actions(other);

  const Actions actions = required_actions & allowed_actions;

  // handle loads/stores from/to locations
  if (actions & LOC_LOAD)  {
    other->update_cache(other_index);
  }
  if (actions & LOC_STORE) {
    write_changes(my_index);
  }
  
  // handle register stores
  if (actions & REG_STORE && other->in_register()) {
    // declare & read values for both source and destination
    const Value this_value (this,  my_index   );
    const Value other_value(other, other_index);

    // do the register store 
    if (!other->is_register_identical_to(my_index, this, other_index)) {
      code_generator()->move(other_value, this_value);
    }
  }

  return required_actions & ~allowed_actions;
}
Ejemplo n.º 3
0
/*
 * We can't run the VM in the main thread (because it has to handle events).
 * So we run the VM in this thread.
 */
static DWORD WINAPI vm_thread_routine(LPVOID lpvParam) {
  // Print arguments that we are using
  JVMSPI_PrintRaw("Running VM");
  JVMSPI_PrintRaw("\n");

  for (int i = 1; i < _argc; i++) {
    JVMSPI_PrintRaw(" ");
    JVMSPI_PrintRaw(_argv[i]);
    JVMSPI_PrintRaw("\n");
  }

  // Call this before any other Jvm_ functions.
  JVM_Initialize();

  int argc = _argc;
  char ** argv = _argv;
  // Ignore arg[0] -- the name of the program.
  argc --;
  argv ++;

  while (true) {
    int n = JVM_ParseOneArg(argc, argv);
    if (n < 0) {
      JVMSPI_DisplayUsage(NULL);
      return -1;
    } else if (n == 0) {
      break;
    }
    argc -= n;
    argv += n;
  }

  if (LogConsole) {
    write_console("Console output logged at \n");
    write_console(logfilename);
    write_console("\n");
    for (int index=0; index<_argc; index++) {
      log_console(_argv[index]);
      log_console(" ");
    }
    log_console("\n");
  }
  if (!WriteConsole) {
    write_console("On-screen console output disabled.\n");
  }

  int code = JVM_Start(NULL, NULL, argc, argv);
  JVMSPI_Exit(code);
  SHOULD_NOT_REACH_HERE();
  return 0;
}
Ejemplo n.º 4
0
void SourceAssembler::beg_segment(Segment *segment, SegmentType segment_type) {
  GUARANTEE(_segment == NULL, "no nested segments");
  _segment = segment;
  int segment_number = 1;

  GUARANTEE(segment_type != no_segment, "must specify segment");
  if (_segment_type != segment_type) {
    if (!GenerateSDTCode && !GenerateGNUCode && !GenerateMicrosoftCode) {
      // Generating code for ADS or RVCT. Need to add PRESERVE8
      // if we're building for RVCT 2.0 or later
      stream()->print_cr("\tIF {ARMASM_VERSION} >= 200000");
      stream()->print_cr("\tPRESERVE8");
      stream()->print_cr("\tENDIF");
    }
    _segment_type = segment_type;   // Since this controls the stream() below
    switch (segment_type) {
      case code_segment:
        if (GenerateSDTCode) {
          stream()->print_cr("\tAREA |.text%d|, CODE", segment_number++);
	} else {
          stream()->print_cr(GenerateGNUCode? ".text":"\tAREA |.text|, CODE");
	}
        break;

      case data_segment:
        if (GenerateSDTCode) {
          stream()->print_cr("\tAREA |.data%d|, DATA", segment_number++);
	} else if (GenerateGNUCode) {
          stream()->print_cr(".data");
        } else {
          stream()->print_cr("\tAREA |.data|, DATA");
	}
        break;

      case bss_segment:
        if (GenerateSDTCode) {
          stream()->print_cr("\tAREA |.data%d|, DATA", segment_number++);
	} else {
          stream()->print_cr(GenerateGNUCode ? ".bss":"\tAREA |.data|, DATA");
	}
        break;

      case gp_segment:
        break;

      default:
        SHOULD_NOT_REACH_HERE();
    }
  }
}
Ejemplo n.º 5
0
void TypeArrayClass::print_type_on(Stream* st) {
#if USE_DEBUG_PRINTING
 switch(type()) {
   case T_BOOLEAN:   st->print("Bool");   break;
   case T_CHAR:      st->print("Char");   break;
   case T_FLOAT:     st->print("Float");  break;
   case T_DOUBLE:    st->print("Double"); break;
   case T_BYTE:      st->print("Byte");   break;
   case T_SHORT:     st->print("Short");  break;
   case T_INT:       st->print("Int");    break;
   case T_LONG:      st->print("Long");   break;
   default: SHOULD_NOT_REACH_HERE();
 }
#endif
}
Ejemplo n.º 6
0
void MemoryAddress::fill_in_address_register() {
  // In all cases exception for variable arrays indices, we are looking at
  // at fixed offset into the object.
  jint fixed_offset;
  if (has_fixed_offset(fixed_offset)) {
    code_generator()->mov(address_register(), fixed_offset + base_offset());
    code_generator()->add(address_register(), fixed_register(),
                          address_register());
    set_address_register_includes_base_offset();
  } else {
    // This is a virtual method, and in this case, we better be calling
    // an overriding definition.
    SHOULD_NOT_REACH_HERE();
  }
}
Ejemplo n.º 7
0
void Value::set_immediate_from_static_field(InstanceClass* ic, int offset) {
  TypeArray::Raw f = ic->fields();
  Oop::Raw object;

  for (int index = 0; index < f().length(); index += 5) {
    Field static_field(ic, index);

    if (static_field.offset() == offset) {
      // Note: there may be a non-static field with the same 'offset'
      // as the static field we're trying to find.
      if (static_field.is_final() && static_field.is_static()) {
        switch (static_field.type()) {
          case T_BOOLEAN : // fall-through - stored as 32-bit
          case T_CHAR    : // fall-through - stored as 32-bit
          case T_BYTE    : // fall-through - stored as 32-bit
          case T_SHORT   : // fall-through - stored as 32-bit
          case T_INT     : set_int(ic->int_field(offset));       break;

          case T_ARRAY   : // fall-through
          case T_OBJECT  :
            // Note: if setting immediate for object fields is enabled for cross
            // generator, this reference will be written to the TEXT block as a
            // part of relocation information for the compiled method. The
            // problem is that the referenced object may be put to the HEAP
            // block and it would be impossible to write its reference
            // in the TEXT block. At this point we don't know the block type of
            // the referenced object, so for now we disable setting immediate
            // for cross generator.
            if (!USE_AOT_COMPILATION || !GenerateROMImage) {
              object = ic->obj_field(offset); 
              set_obj(&object);
            }
            break;
#if ENABLE_FLOAT
          case T_FLOAT   : set_float(ic->float_field(offset));   break;
          case T_DOUBLE  : set_double(ic->double_field(offset)); break;
#endif
          case T_LONG    : set_long(ic->long_field(offset));     break;
          default        : SHOULD_NOT_REACH_HERE();              break;
        }
      }
      return;
    }
  }

  // This field is not final and was removed from the fields array
  // during romization
}
Ejemplo n.º 8
0
void Thread::start_lightweight_thread() {
  Thread* thread = Thread::current();
  // idea here is that some threads can't be terminated
  // by throwing an uncatchable exceptions if they're in 'just started'
  // state (i.e. never executed), as this exception will be silently ignored
  // by shared_entry(), thus we have to check thread status before
  // actual execution of pending entries, and null them out, 
  // if thread is terminating
  if (thread->is_terminating()) {
    Oop::Raw null;
    thread->set_pending_entries(&null);
  } else {
    invoke_pending_entries(thread);
  }

  if (!Universe::is_stopping() && !TestCompiler) {
    if (CURRENT_HAS_PENDING_EXCEPTION) {
      call_on_primordial_stack(lightweight_thread_uncaught_exception);
    }
    call_on_primordial_stack(finish);
    invoke_pending_entries(thread);
    // Just in case the append_pending_entry() failed inside
    // Thread::finish()
    force_terminated(thread);
#if ENABLE_ISOLATES
#if !ARM && !HITACHI_SH
    {
      call_on_primordial_stack(thread_task_cleanup);
      invoke_pending_entries(thread);
    }
#endif
#endif
  }
  // The following returns to another Java thread, unless this is
  // the only remaining Java thread.
  call_on_primordial_stack(lightweight_thread_exit);

  // We can only return here if we are the last thread.
  // Running on the Java stack at this point, no handles please
  GUARANTEE(Scheduler::get_next_runnable_thread()->is_null(),
            "Must be last thread");

  // Back to C land
  current_thread_to_primordial();

  SHOULD_NOT_REACH_HERE();
}
Ejemplo n.º 9
0
void EventLogger::dump(Stream *s) {
  jlong freq = Os::elapsed_frequency();
  bool use_usec = (freq > 100 * 1000);

  if (use_usec) {
    s->print("      msec");
  } else {
    s->print("  msec");
  }
  s->print_cr("   hrtick event");
  s->print_cr("=======================================");

  jlong last_hrticks = 0;
  for (LogEntryBlock *blk = _head; blk; blk = blk->_next) {
    for (int i=0; i<blk->_used_count; i++) {
      LogEntry *entry = &blk->_entries[i];
      const char *name = "??";
      switch (entry->_type) {
        EVENT_LOGGER_TYPES_DO(CASE_OF_EVENT_LOGGER_TYPE);
      default:
        SHOULD_NOT_REACH_HERE();
        break;
      }
      jlong time = last_hrticks + entry->_hrtick_delta;
      jlong usec = time * 1000 * 1000 / freq;
      jlong msec = usec / 1000;
      usec = usec % 1000;
      last_hrticks = time;

      s->print("%6d", (jint)msec);
      if (use_usec) {
        s->print(".");
        if (usec < 100) {
          s->print("0");
        }
        if (usec < 10) {
          s->print("0");
        }
        s->print("%d", usec);
      }
      s->print_cr(" %8d %s", (jint)time, name);
    }
    s->print_cr("=======================================");
  }
}
  void check_static(int index JVM_TRAPS) {
    ConstantPool::Raw cp = method()->constants();      
      if (cp().tag_at(index).is_resolved_static_method()) {
        Method m = cp().resolved_static_method_at(index);       
        _owner->add_method(&m JVM_NO_CHECK_AT_BOTTOM);
      } else {
        // This could be an element we failed to resolve 
        // when ROMizing an application.
        if (!PostponeErrorsUntilRuntime) {
          SHOULD_NOT_REACH_HERE();
        } else {
          GUARANTEE(cp().tag_at(index).is_method(), "Sanity");
          // The class must be marked as unverified or non-optimizable, 
          // since it contains an unresolved entry at this point.
#ifdef AZZERT
          InstanceClass klass = method()->holder();
          GUARANTEE(!klass.is_verified() || !klass.is_optimizable(), 
                    "Sanity");
#endif
        }
      }
  }
Ejemplo n.º 11
0
  void check_static(int index) {
    AllocationDisabler no_allocation_should_happen;
    ConstantPool::Raw cp = method()->constants();      
    if (cp().tag_at(index).is_resolved_static_method()) {
      Method::Raw callee = cp().resolved_static_method_at(index);
      _owner->try_inline(method(), &callee, bci());
    } else {
      // This could be an element we failed to resolve 
      // when ROMizing an application.
      if (!PostponeErrorsUntilRuntime) {
        SHOULD_NOT_REACH_HERE();
      } else {
        GUARANTEE(cp().tag_at(index).is_method(), "Sanity");
        // The class must be marked as unverified or non-optimizable, 
        // since it contains an unresolved entry at this point.
#ifdef AZZERT
        InstanceClass::Raw klass = method()->holder();
        GUARANTEE(!klass().is_verified() || !klass().is_optimizable(), "Sanity");
#endif
      }
    }
  }
Ejemplo n.º 12
0
void CompiledMethodDesc::set_cache_index ( const int i ) {
  const size_t non_index_mask = ~CompiledMethodDesc::INDEX_MASK;
  const size_t bits_and_size = _flags_and_size & non_index_mask;
  _flags_and_size = bits_and_size | 
                    (size_t(i)<<CompiledMethodDesc::NUMBER_OF_NON_INDEX_BITS);

  // Patch the "strb gp, [gp, #xxxx]" instruction. It does not appear
  // at a fixed location because of code scheduling.
  juint* index_loc = (juint*) (this+1);

#ifdef AZZERT
  juint* index_end = index_loc + 10; // we might have debug code at the
                                     // beginning of the compiled method prolog
#else
  juint* index_end = index_loc + 3;
#endif

  const juint opcode = 
    (juint)Assembler::always << 28 | 1 << 26 | 1 << 22 | Assembler::gp << 12;
  const juint addressing = 3 << 23 | Assembler::gp << 16;
  const juint pattern = opcode | addressing;
  const juint mask = 0xfffff000;

  for (; index_loc < index_end; index_loc++) {
    juint instr = *index_loc & mask;
    if (instr == pattern) {
      *index_loc = instr |
         (i + (address(_method_execution_sensor) - address(&gp_base_label)));
      return;
    }
  }
  SHOULD_NOT_REACH_HERE();

  // set_cach_index is called before major GC
  // The worst that may happen in the rare case when icache is not updated
  // is just a minor deviation in statistics.
  // OsMisc_flush_icache( (address) index_loc, sizeof *index_loc );
}
Ejemplo n.º 13
0
SourceAssembler::Condition SourceAssembler::negate_cc(Condition condition) {
  switch (condition) {
  case equal         : return not_equal;
  case not_equal     : return equal;
  case less          : return greater_equal;
  case less_equal    : return greater;
  case greater       : return less_equal;
  case greater_equal : return less;
  case below         : return above_equal;
  case below_equal   : return above;
  case above         : return below_equal;
  case above_equal   : return below;
  case overflow      : return no_overflow;
  case no_overflow   : return overflow;
  case negative      : return positive;
  case positive      : return negative;
  case parity        : return no_parity;
  case no_parity     : return parity;
  }

  SHOULD_NOT_REACH_HERE();
  return zero;
}
Ejemplo n.º 14
0
void Value::assign_register() {
  if (in_register()) return;

  switch(stack_type()) {
    case T_OBJECT : // fall through
    case T_ARRAY  : // fall through
    case T_INT    : set_register(RegisterAllocator::allocate());
                    break;
    case T_LONG   : set_registers(RegisterAllocator::allocate(), RegisterAllocator::allocate());
                    break;
#if ENABLE_ARM_VFP
    case T_FLOAT  : set_register(RegisterAllocator::allocate_float_register());
                    break;
    case T_DOUBLE : set_vfp_double_register(RegisterAllocator::allocate_double_register());
                    break;
#else  // !ENABLE_ARM_VFP
    case T_FLOAT  : // fall through
    case T_DOUBLE : set_register(RegisterAllocator::allocate_float_register());
                    break;
#endif  // ENABLE_ARM_VFP
    default       : SHOULD_NOT_REACH_HERE();
                    break;
  }
}
Ejemplo n.º 15
0
void SourceAssembler::Label::bind(Stream* s, bool is_global) {
  switch(_state) {
    case undefined:           global(s);                break;
    case anonymous_unused:   /* Fall through */
    case anonymous_used:       _state = anonymous_bound; break;
    case anonymous_bound:     SHOULD_NOT_REACH_HERE();  break;
    default:                                            break; 
  }
  // start a new line if we are not at the beginning
  if (s->position() > 0) {
    s->cr();
  }

  GUARANTEE(s->position() == 0, "wrong label position");
  print_on(s);
  if (GenerateGNUCode) {
    s->print(":");
  } else {
    if (is_global && !GenerateSDTCode) {
      s->print(" PROC");
    }
  }
  s->cr();
}
Ejemplo n.º 16
0
SHORTARRAY createCharArray(const char *utf8stringArg,
                           int utf8length,
                           int *unicodelengthP, 
                           bool_t isPermanent) {
  GUARANTEE(_in_kvm_native_method, "sanity");
  GUARANTEE(!isPermanent, "Permanent char arrays not supported");
  (void)isPermanent;

  LiteralStream ls((char*)utf8stringArg, 0, utf8length);
  int num_chars = ls.length();
  if (num_chars >= 0) {
    SETUP_ERROR_CHECKER_ARG;
    TypeArray::Raw array = Universe::new_char_array(num_chars JVM_CHECK_0);
    for (int i=0; i<num_chars; i++) {
      array().char_at_put(i, ls.read());
    }
    *unicodelengthP = num_chars;
    return (SHORTARRAY)(array().obj());
  } else {
    // Bad UTF8 string in utf8stringArg
    SHOULD_NOT_REACH_HERE();
    return NULL;
  }
}
Ejemplo n.º 17
0
 FarClassDesc(): _instance_size(0) { SHOULD_NOT_REACH_HERE(); }
Ejemplo n.º 18
0
// generate a map of all the field types in this object
int CompiledMethod::generate_fieldmap(TypeArray* field_map) {
  SHOULD_NOT_REACH_HERE();
  return 0;
} 
Ejemplo n.º 19
0
char *ConstantTag::name_for(jubyte tag, bool use_prefix) {
  const char *result = "???";
  switch (tag) {
    // Defined by JLS (JvmConst.hpp)
    JVM_TAG_CASE(Utf8);
    JVM_TAG_CASE(Unicode);
    JVM_TAG_CASE(Integer);
    JVM_TAG_CASE(Float);
    JVM_TAG_CASE(Long);      
    JVM_TAG_CASE(Double);
    JVM_TAG_CASE(Class);
    JVM_TAG_CASE(String);
    JVM_TAG_CASE(Fieldref);
    JVM_TAG_CASE(Methodref);
    JVM_TAG_CASE(InterfaceMethodref);
    JVM_TAG_CASE(NameAndType);

    // Defined by the VM (ConstantTag.hpp)
    JVM_TAG_CASE(Invalid);

    JVM_TAG_CASE(UnresolvedClass);
    JVM_TAG_CASE(ClassIndex);
    JVM_TAG_CASE(UnresolvedString);
    JVM_TAG_CASE(StringIndex);

    JVM_TAG_CASE(ResolvedBooleanFieldref);
    JVM_TAG_CASE(ResolvedCharFieldref);
    JVM_TAG_CASE(ResolvedFloatFieldref);
    JVM_TAG_CASE(ResolvedDoubleFieldref);
    JVM_TAG_CASE(ResolvedByteFieldref);
    JVM_TAG_CASE(ResolvedShortFieldref);
    JVM_TAG_CASE(ResolvedIntFieldref);
    JVM_TAG_CASE(ResolvedLongFieldref);
    JVM_TAG_CASE(ResolvedObjectFieldref);
    JVM_TAG_CASE(ResolvedArrayFieldref);

    JVM_TAG_CASE(ResolvedStaticBooleanFieldref);
    JVM_TAG_CASE(ResolvedStaticCharFieldref);
    JVM_TAG_CASE(ResolvedStaticFloatFieldref);
    JVM_TAG_CASE(ResolvedStaticDoubleFieldref);
    JVM_TAG_CASE(ResolvedStaticByteFieldref);
    JVM_TAG_CASE(ResolvedStaticShortFieldref);
    JVM_TAG_CASE(ResolvedStaticIntFieldref);
    JVM_TAG_CASE(ResolvedStaticLongFieldref);
    JVM_TAG_CASE(ResolvedStaticObjectFieldref);
    JVM_TAG_CASE(ResolvedStaticArrayFieldref);

    JVM_TAG_CASE(ResolvedStaticMethod);

    JVM_TAG_CASE(ResolvedBooleanVirtualMethod);
    JVM_TAG_CASE(ResolvedCharVirtualMethod);
    JVM_TAG_CASE(ResolvedFloatVirtualMethod);
    JVM_TAG_CASE(ResolvedDoubleVirtualMethod);
    JVM_TAG_CASE(ResolvedByteVirtualMethod);
    JVM_TAG_CASE(ResolvedShortVirtualMethod);
    JVM_TAG_CASE(ResolvedIntVirtualMethod);
    JVM_TAG_CASE(ResolvedLongVirtualMethod);
    JVM_TAG_CASE(ResolvedObjectVirtualMethod);
    JVM_TAG_CASE(ResolvedArrayVirtualMethod);
    JVM_TAG_CASE(ResolvedVoidVirtualMethod);

    JVM_TAG_CASE(ResolvedBooleanInterfaceMethod);
    JVM_TAG_CASE(ResolvedCharInterfaceMethod);
    JVM_TAG_CASE(ResolvedFloatInterfaceMethod);
    JVM_TAG_CASE(ResolvedDoubleInterfaceMethod);
    JVM_TAG_CASE(ResolvedByteInterfaceMethod);
    JVM_TAG_CASE(ResolvedShortInterfaceMethod);
    JVM_TAG_CASE(ResolvedIntInterfaceMethod);
    JVM_TAG_CASE(ResolvedLongInterfaceMethod);
    JVM_TAG_CASE(ResolvedObjectInterfaceMethod);
    JVM_TAG_CASE(ResolvedArrayInterfaceMethod);
    JVM_TAG_CASE(ResolvedVoidInterfaceMethod);

    JVM_TAG_CASE(ResolvedUncommonInterfaceMethod);
    JVM_TAG_CASE(ResolvedFinalUncommonInterfaceMethod);

  default:
    SHOULD_NOT_REACH_HERE();
  }
  return (char*)result;
}
Ejemplo n.º 20
0
 void* operator new(size_t /*size*/) {
   SHOULD_NOT_REACH_HERE();
   return (void *)0;
 }
Ejemplo n.º 21
0
 void operator delete(void* /*p*/) {
   SHOULD_NOT_REACH_HERE();
 }
Ejemplo n.º 22
0
void Macros::arith_imm(Opcode opcode, Register rd, Register rn, int imm32,
                       const LiteralAccessor* la, CCMode s, Condition cond) {
  GUARANTEE(rd <= r15 && rn <= r15, "Invalid register used");
  
  Address1 result;
  if (is_rotated_imm(imm32, result)) {
    // Simplest case.  We can handle the immediate directly
    arith(opcode, rd, rn, result, s, cond);
    return;
  }
  int alt_opcode_type = OpcodeInfo::table[opcode].alt_opcode_type;
  int alt_imm32 = alt_opcode_type == alt_NEG ? -imm32 : ~imm32;
  Opcode alt_opcode = (Opcode)OpcodeInfo::table[opcode].alt_opcode;

  if (alt_opcode_type != alt_NONE && is_rotated_imm(alt_imm32, result)) {
    // We can handle the negated/complemented immediate
    arith(alt_opcode, rd, rn, result, s, cond);
    return;
  }

  // Is the imm32, or some rotated or shifted form of it already available
  if (la != NULL && la->has_literal(imm32, result)) {
    arith(opcode, rd, rn, result, s, cond);
    return;
  }
  if (alt_opcode_type != alt_NONE && 
      la != NULL && la->has_literal(alt_imm32, result)) {
    arith(alt_opcode, rd, rn, result, s, cond);
    return;
  }

  // Let's see if we can split either imm32 or alt_imm32 into two pieces,
  // each of which can be represented as an immediate.
  if ((rd != pc) && (s == no_CC || opcode <= _eor || opcode >= _orr)) {

    // Don't even try if we're setting the pc, or if this is an "arithmetic"
    // rather than a logical operation.  (For arithmetic operations, the C
    // and V bit have meanings that cannot be reproduced by splitting)
    if (OpcodeInfo::table[opcode].twoword_allowed) {
      if (arith2_imm(opcode, rd, rn, imm32, s, cond)) {
        return;
      }
    }
    if (alt_opcode_type != alt_NONE
           && OpcodeInfo::table[alt_opcode].twoword_allowed){
      // Can we break up alt_imm32 into two pieces, each an immediate?
      if (arith2_imm(alt_opcode, rd, rn, alt_imm32, s, cond)) {
        return;
      }
    }
  }

  if (opcode == _eor && imm32 == -1) {
    // This is the only chance we have of optimizing ~X
    mvn(rd, reg(rn), s, cond);
    return;
  }

  if (opcode == _mov) {
    ldr_big_integer(rd, imm32, cond);
    return;
  }

  // We include the (opcode != _mov) below, even though it isn't necessary,
  // since on the XScale we may want to get of the preceding clause.
  if (opcode != _mov) {
    Register tmp = (la != NULL) ? la->get_literal(imm32) : Assembler::no_reg;
    if (tmp != no_reg) {
      GUARANTEE(rn != tmp, "register must be different");
      arith(opcode, rd, rn, reg(tmp), s, cond);
      la->free_literal();
      return;
    }
  }

  // We are desperate.  We are clearly in some test suite situation that
  // is purposely generating a large immediate when that shouldn't
  // normally happen.  Let's just deal with it
  if ((rd != pc) && (s == no_CC || opcode <= _eor || opcode >= _orr)) {
    if (OpcodeInfo::table[opcode].twoword_allowed) {
      arith4_imm(opcode, rd, rn, imm32, s, cond);
      return;
    }
    if (alt_opcode_type != alt_NONE &&
      OpcodeInfo::table[alt_opcode].twoword_allowed){
      arith4_imm(alt_opcode, rd, rn, alt_imm32, s, cond);
      return;
    }
  }

  SHOULD_NOT_REACH_HERE();
}
Ejemplo n.º 23
0
void BytecodeClosure::illegal_code(JVM_SINGLE_ARG_TRAPS) { 
    JVM_IGNORE_TRAPS;
    SHOULD_NOT_REACH_HERE();
}