/*
 * Copyright (C) 2019 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.
 */

// This test checks that FP registers spill offset is correctly recorded in the SlowPath; by causing
// asynchronous deoptimization in debuggable mode we observe the FP values in the interpreter.
public class FloatLoop implements Runnable {
    static final int numberOfThreads = 2;
    volatile static boolean sExitFlag = false;
    volatile static boolean sEntered = false;
    int threadIndex;

    FloatLoop(int index) {
        threadIndex = index;
    }

    public static void main() throws Exception {
        final Thread[] threads = new Thread[numberOfThreads];
        for (int t = 0; t < threads.length; t++) {
            threads[t] = new Thread(new FloatLoop(t));
            threads[t].start();
        }
        for (Thread t : threads) {
            t.join();
        }

        System.out.println("Float loop finishing");
    }

    static final float kFloatConst0 = 256.0f;
    static final float kFloatConst1 = 128.0f;
    static final int kArraySize = 128;
    volatile static float floatField;

    public void expectEqualToEither(float value, float expected0, float expected1) {
        if (value != expected0 && value != expected1) {
            throw new Error("Expected:  " + expected0 + " or "+ expected1 +
                            ", found: " + value);
        }
    }

    // Create an empty int[] to force loading the int[] class before compiling $noinline$busyLoop.
    // This makes sure the compiler can properly type int[] and not bail.
    static int[] emptyArray = new int[0];

    public void $noinline$busyLoop() {
        Main.assertIsManaged();

        // On Arm64:
        // This loop is likely to be vectorized which causes the full 16-byte Q-register to be saved
        // across slow paths.
        int[] array = new int[kArraySize];
        for (int i = 0; i < kArraySize; i++) {
            array[i]++;
        }

        sEntered = true;
        float s0 = kFloatConst0;
        float s1 = kFloatConst1;
        for (int i = 0; !sExitFlag; i++) {
            if (i % 2 == 0) {
                s0 += 2.0;
                s1 += 2.0;
            } else {
                s0 -= 2.0;
                s1 -= 2.0;
            }
            // SuspendCheckSlowPath must record correct stack offset for spilled FP registers.
        }
        Main.assertIsInterpreted();

        expectEqualToEither(s0, kFloatConst0, kFloatConst0 + 2.0f);
        expectEqualToEither(s1, kFloatConst1, kFloatConst1 + 2.0f);

        floatField = s0 + s1;
    }

    public void run() {
        if (threadIndex == 0) {
            while (!sEntered) {
              Thread.yield();
            }
            Main.deoptimizeAll();
            sExitFlag = true;
        } else {
            $noinline$busyLoop();
        }
    }
}
