/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

public class Main  {
  public static void main(String[] args) throws Exception {
    if (testOddLow1(5L)) {
      throw new Error();
    }

    if (testNonFollowingHigh(5)) {
      throw new Error();
    }

    if (testOddLow2()) {
      throw new Error();
    }
  }

  public static boolean testOddLow1(long a /* ECX-EDX */) {
    // class instance is in EBP
    long b = myLongField1; // ESI-EDI
    int f = myField1; // EBX
    int e = myField2; // EAX
    int g = myField3; // ESI (by spilling ESI-EDI, see below)
    int h = myField4; // EDI
    myLongField2 = a; // Make sure ESI-EDI gets spilled and not ECX-EDX
    myField2 = f; // use of EBX
    myField1 = e; // use of EAX
    myField3 = h; // use of ESI
    myField4 = g; // use if EDI

    // At this point `b` has been spilled and needs to have a pair. The ordering
    // in the register allocator triggers the allocation of `res` before `b`.
    // `res` being used after the `doCall`, we want a callee saved register.
    //
    // EBP is taken by the class instance and EDI is taken by `g` (both used in the `myField4`
    // assignment below). So we end up allocating ESI for `res`.
    //
    // When we try to allocate a pair for `b` we're in the following situation:
    // EAX is free
    // ECX is taken
    // EDX is taken
    // EBX is free
    // ESP is blocked
    // EBP could be spilled
    // ESI is taken
    // EDI could be spilled
    //
    // So there is no consecutive registers available to please the register allocator.
    // The compiler used to trip then because of a bogus implementation of trying to split
    // an unaligned register pair (here ECX and EDX). The implementation would not find
    // a register and the register allocator would then complain about not having
    // enough registers for the operation.
    boolean res = a == b;
    $noinline$doCall();
    myField4 = g;
    return res;
  }

  public static boolean testNonFollowingHigh(int i) {
    // class instance is in EBP
    long b = myLongField1; // ESI-EDI
    long a = (long)i; // EAX-EDX
    int f = myField1; // EBX
    int e = myField2; // ECX
    int g = myField3; // ESI (by spilling ESI-EDI, see below)
    int h = myField4; // EDI
    myLongField2 = a; // Make sure ESI-EDI gets spilled and not ECX-EDX
    myField2 = f; // use of EBX
    myField1 = e; // use of ECX
    myField3 = h; // use of EDI
    myField4 = g; // use of ESI

    // At this point `b` has been spilled and needs to have a pair. The ordering
    // in the register allocator triggers the allocation of `res` before `b`.
    // `res` being used after the `doCall`, we want a callee saved register.
    //
    // EBP is taken by the class instance and ESI is taken by `g` (both used in the `myField4`
    // assignment below). So we end up allocating EDI for `res`.
    //
    // When we try to allocate a pair for `b` we're in the following situation:
    // EAX is taken
    // ECX is free
    // EDX is taken
    // EBX is free
    // ESP is blocked
    // EBP could be spilled
    // ESI is taken
    // EDI could be spilled
    //
    // So there is no consecutive registers available to please the register allocator.
    // The compiler used to be in a bad state because of a bogus implementation of trying
    // to split an unaligned register pair (here EAX and EDX).
    boolean res = a == b;
    $noinline$doCall();
    myField4 = g;
    return res;
  }

  public static boolean testOddLow2() {
    // class instance is in EBP
    long b = myLongField1; // ECX-EDX (hint due to call below).
    long a = myLongField2; // ESI-EDI
    int f = myField1; // EBX
    int e = myField2; // EAX
    int g = myField3; // ECX
    int h = myField4; // EDX
    int i = myField5; // ESI - callee saved due to assignment after call to $noinline$doCall.
    myField2 = f; // use of EBX
    myField1 = e; // use of EAX
    myField3 = h; // use of EDX
    myField4 = i; // use of ESI
    myField5 = g; // use of ECX

    // At this point `a` and `b` have been spilled and need to have a pairs. The ordering
    // in the register allocator triggers the allocation of `res` before `a` and `b`.
    // `res` being used after the `doCall`, we want a callee saved register.
    //
    // EBP is taken by the class instance and ESI is taken by `i` (both used in the `myField4`
    // assignment below). So we end up allocating EDI for `res`.
    //
    // We first try to allocator a pair for `b`. We're in the following situation:
    // EAX is free
    // ECX is free
    // EDX is free
    // EBX is free
    // ESP is blocked
    // EBP could be spilled
    // ESI could be spilled
    // EDI is taken
    //
    // Because `b` is used as a first argument to a call, we take its hint and allocate
    // ECX-EDX to it.
    //
    // We then try to allocate a pair for `a`. We're in the following situation:
    // EAX is free
    // ECX could be spilled
    // EDX could be spilled
    // EBX is free
    // ESP is blocked
    // EBP could be spilled
    // ESI could be spilled
    // EDI is taken
    //
    // So no consecutive two free registers are available. When trying to find a slot, we pick
    // the first unaligned or non-pair interval. In this case, this is the unaligned ECX-EDX.
    // The compiler used to then trip because it forgot to remove the high interval containing
    // the pair from the active list.

    boolean res = a == b;
    $noinline$doCall(b);
    myField4 = i; // use of ESI
    return res;
  }

  public static void $noinline$doCall() {
  }

  public static void $noinline$doCall(long e) {
  }

  public static int myField1;
  public static int myField2;
  public static int myField3;
  public static int myField4;
  public static int myField5;
  public static long myLongField1;
  public static long myLongField2;
}
