# Copyright (c) 2021-2022 Huawei Device Co., Ltd.
# 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.

#
# v1 = 0;
# INT32_MAX = 2147483647  
# for (int32 v0 = int32_max - 7, v0 > 0; v0++) { 
#   v1++;
# }
# return v1 - 8;
#
.function i32 run_case1() <static> {    
    movi v0, 2147483640
    movi v1, 0
loop:
    lda v0
    jlez loop_exit
    inci v0, 1
    inci v1, 1
    jmp loop
loop_exit:
    lda v1
    subi 8
    return
}

#
# v1 = 0
# while (a0 < a1):
#     a0++
#     v1++
# return v1
#
.function i32 run_case2(i32 a0, i32 a1) <static> {    
    movi v1, 0
loop:
    lda a0
    jge a1, loop_exit
    inci a0, 1
    inci v1, 1
    jmp loop
loop_exit:
    lda v1
    return
}

.function i32 run_case2a(i32 a0) <static> {  
    movi v0, 0x80000002 
    movi v1, 0
loop:
    lda a0
    jge v0, loop_exit
    inci a0, 1
    inci v1, 1
    jmp loop
loop_exit:
    lda v1
    return
}

#
# v1 = 0
# while (a0 < a1):
#     a0++
#     v1++
# return v1
#
.function i32 run_case3(i64 a0, i64 a1) <static> {    
    movi v1, 0
    movi.64 v2, 1
loop:
    lda.64 a0
    cmp.64 a1
    jgez loop_exit
    lda.64 a0
    add2.64 v2
    sta.64 a0
    inci v1, 1
    jmp loop
loop_exit:
    lda v1
    return
}

.function i32 run_case3a(i64 a0) <static> {    
    movi.64 v0, 0x8000000000000002
    movi v1, 0
    movi.64 v2, 1
loop:
    lda.64 a0
    cmp.64 v0
    jgez loop_exit
    lda.64 a0
    add2.64 v2
    sta.64 a0
    inci v1, 1
    jmp loop
loop_exit:
    lda v1
    return
}

#
# v1 = 0
# while (a0 > a1):
#     a0--
#     v1++
# return v1
#
.function i32 run_case4(i32 a0, i32 a1) <static> {    
    movi v1, 0
loop:
    lda a0
    jle a1, loop_exit
    inci a0, -1
    inci v1, 1
    jmp loop
loop_exit:
    lda v1
    return
}

.function i32 run_case4a(i32 a0) <static> { 
    movi v0, 0x7ffffffd   
    movi v1, 0
loop:
    lda a0
    jle v0, loop_exit
    inci a0, -1
    inci v1, 1
    jmp loop
loop_exit:
    lda v1
    return
}

#
# v1 = 0
# while (a0 > a1):
#     a0--
#     v1++
# return v1
#
.function i32 run_case5(i64 a0, i64 a1) <static> {    
    movi v1, 0
    movi.64 v2, 1
loop:
    lda.64 a0
    cmp.64 a1
    jlez loop_exit
    lda.64 a0
    sub2.64 v2
    sta.64 a0
    inci v1, 1
    jmp loop
loop_exit:
    lda v1
    return
}

.function i32 run_case5a(i64 a0) <static> {  
    movi.64 v0, 0x7ffffffffffffffd  
    movi v1, 0
    movi.64 v2, 1
loop:
    lda.64 a0
    cmp.64 v0
    jlez loop_exit
    lda.64 a0
    sub2.64 v2
    sta.64 a0
    inci v1, 1
    jmp loop
loop_exit:
    lda v1
    return
}

.function i32 main() <static> {
    call.short run_case1
    jnez exit_failure
    
    movi v0, 0x7ffffff7
    movi v1, 0x80000002
    call.short run_case2, v0, v1
    jnez exit_failure
    
    movi v0, 0x80000000
    movi v1, 0x80000002
    call.short run_case2, v0, v1
    subi 2
    jnez exit_failure

    movi v0, 0x7ffffff7
    call.short run_case2a, v0
    jnez exit_failure
    
    movi v0, 0x80000000
    call.short run_case2a, v0
    subi 2
    jnez exit_failure

    movi.64 v0, 0x7ffffffffffffff7
    movi.64 v1, 0x8000000000000002
    call.short run_case3, v0, v1 
    jnez exit_failure    

    movi.64 v0, 0x8000000000000000
    movi.64 v1, 0x8000000000000002
    call.short run_case3, v0, v1
    subi 2 
    jnez exit_failure 

    movi.64 v0, 0x7ffffffffffffff7
    call.short run_case3a, v0 
    jnez exit_failure    

    movi.64 v0, 0x8000000000000000
    call.short run_case3a, v0
    subi 2 
    jnez exit_failure 

    movi v0, 0x8000000a
    movi v1, 0x7ffffffd
    call.short run_case4, v0, v1
    jnez exit_failure

    movi v0, 0x7fffffff
    movi v1, 0x7ffffffd
    call.short run_case4, v0, v1
    subi 2 
    jnez exit_failure 

    movi v0, 0x8000000a
    call.short run_case4a, v0
    jnez exit_failure

    movi v0, 0x7fffffff
    call.short run_case4a, v0
    subi 2 
    jnez exit_failure 

    movi.64 v0, 0x800000000000000a
    movi.64 v1, 0x7ffffffffffffffd
    call.short run_case5, v0, v1
    jnez exit_failure 

    movi.64 v0, 0x7fffffffffffffff
    movi.64 v1, 0x7ffffffffffffffd
    call.short run_case5, v0, v1
    subi 2
    jnez exit_failure 

    movi.64 v0, 0x800000000000000a
    call.short run_case5a, v0
    jnez exit_failure 

    movi.64 v0, 0x7fffffffffffffff
    call.short run_case5a, v0
    subi 2
    jnez exit_failure 

    ldai 0
    return
    
exit_failure:
    ldai 1
    return    
}