private void align64bits(Dop[] opcodes) {
    while (true) {
      int notAligned64bitRegAccess = 0;
      int aligned64bitRegAccess = 0;
      int notAligned64bitParamAccess = 0;
      int aligned64bitParamAccess = 0;
      int lastParameter = unreservedRegCount + reservedCount + reservedParameterCount;
      int firstParameter = lastParameter - paramSize;

      // Collects the number of time that 64-bit registers are accessed aligned or not.
      for (DalvInsn insn : insns) {
        RegisterSpecList regs = insn.getRegisters();
        for (int usedRegIdx = 0; usedRegIdx < regs.size(); usedRegIdx++) {
          RegisterSpec reg = regs.get(usedRegIdx);
          if (reg.isCategory2()) {
            boolean isParameter = reg.getReg() >= firstParameter;
            if (reg.isEvenRegister()) {
              if (isParameter) {
                aligned64bitParamAccess++;
              } else {
                aligned64bitRegAccess++;
              }
            } else {
              if (isParameter) {
                notAligned64bitParamAccess++;
              } else {
                notAligned64bitRegAccess++;
              }
            }
          }
        }
      }

      if (notAligned64bitParamAccess > aligned64bitParamAccess
          && notAligned64bitRegAccess > aligned64bitRegAccess) {
        addReservedRegisters(1);
      } else if (notAligned64bitParamAccess > aligned64bitParamAccess) {
        addReservedParameters(1);
      } else if (notAligned64bitRegAccess > aligned64bitRegAccess) {
        addReservedRegisters(1);

        // Need to shift parameters if they exist and if number of unaligned is greater than
        // aligned. We test the opposite because we previously shift all registers by one,
        // so the number of aligned become the number of unaligned.
        if (paramSize != 0 && aligned64bitParamAccess > notAligned64bitParamAccess) {
          addReservedParameters(1);
        }
      } else {
        break;
      }

      if (!reserveRegisters(opcodes)) {
        break;
      }
    }
  }
Helper for {@link #assignAddressesAndFixBranches}, which checks the branch target size
requirement of each branch instruction to make sure it fits. For instructions that don't fit,
this rewrites them to use a {@code goto} of some sort. In the case of a conditional branch that
doesn't fit, the sense of the test is reversed in order to branch around a {@code goto} to the
original target.

@return whether any branches had to be fixed
android/android_framework/dex-maker/src/main/java/com/android/dx/dex/code/OutputFinisher.java