Exemplo n.º 1
0
Assembler::Address1 Assembler::imm_slow(int imm_32) {
#if NOT_CURRENTLY_USED
  /* Uncomment this to see commonly used values */
  static int done = 0;
  if (!done) {
    done = 1;
    Address1 res;
    for (int i=-256; i<256; i++) {
      tty->print("  /* %8x */ ", i);
      if (is_rotated_imm_slow(i, res)) {
        tty->print_cr("0x%x,", (int)res);
      } else {
        tty->print_cr("-1,");
      }
    }
  }
#endif

  Address1 result;
  if (is_rotated_imm(imm_32, result)) {
    return result;
  }
  JVM_FATAL(cannot_represent_imm_32_as_rotated_imm_8);
  return zero;
}
Exemplo n.º 2
0
void SourceAssembler::add_using_gp(Register reg, const char *name, 
                                   Condition cond) {
  int offset = find_gp_offset(name);
  if (is_rotated_imm(offset)) {
    eol_comment(name);
    add(reg, gp, imm(offset), cond);
  } else {
    char buff[128];
    jvm_sprintf(buff, "slow add_gp_imm %s %d", name, offset);
    eol_comment(buff);
    offset -= 1024;
    GUARANTEE(is_rotated_imm(1024), "sanity");
    GUARANTEE(is_rotated_imm(offset), "sanity");
    add(reg, gp, imm(1024), cond);
    add(reg, reg, imm(offset), cond);
  }
}                  
Exemplo n.º 3
0
bool Macros::is_twoword_immediate(int imm32,
                                  Address1& result1, Address1& result2) {
  GUARANTEE( !is_rotated_imm(imm32), "Shouldn't call this");
  if ((unsigned)imm32 < 0x10000) {
    // This takes care of 99% of all cases in which we return "true".
    // The following may not give the canonical form [the form with the
    // smallest possible value for "rotate"] for the immediates, but we don't
    // really care.
    result1 = imm_rotate(imm32 & 0xFF, 0);
    result2 = imm_rotate(imm32 >> 8,  24);
    return true;
  }
Exemplo n.º 4
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();
}