import t, c
from stdint import *
import stdio


# ============================================================
# c.LLVMIR / c.LInp / c.LOut 内联 LLVM IR 测试
#
# 测试 c.LLVMIR 内联 LLVM IR 指令的生成和执行
# - c.LInp(expr) 标记输入操作数
# - c.LOut(expr) 标记输出操作数
# ============================================================


# Test 1: 基本加法 add
def test_add() -> t.CInt:
    stdio.printf("--- Test 1: LLVMIR add ---\n")
    a: t.CInt = 10
    b: t.CInt = 20
    r: t.CInt = c.LLVMIR(f"add i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
    stdio.printf("add(10, 20)=%d (expect 30)\n", r)
    if r == 30:
        stdio.printf("LLVMIR add OK\n")
    else:
        stdio.printf("LLVMIR add FAIL\n")
    return 0


# Test 2: 基本减法 sub
def test_sub() -> t.CInt:
    stdio.printf("--- Test 2: LLVMIR sub ---\n")
    a: t.CInt = 50
    b: t.CInt = 20
    r: t.CInt = c.LLVMIR(f"sub i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
    stdio.printf("sub(50, 20)=%d (expect 30)\n", r)
    if r == 30:
        stdio.printf("LLVMIR sub OK\n")
    else:
        stdio.printf("LLVMIR sub FAIL\n")
    return 0


# Test 3: 基本乘法 mul
def test_mul() -> t.CInt:
    stdio.printf("--- Test 3: LLVMIR mul ---\n")
    a: t.CInt = 6
    b: t.CInt = 7
    r: t.CInt = c.LLVMIR(f"mul i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
    stdio.printf("mul(6, 7)=%d (expect 42)\n", r)
    if r == 42:
        stdio.printf("LLVMIR mul OK\n")
    else:
        stdio.printf("LLVMIR mul FAIL\n")
    return 0


# Test 4: 基本除法 sdiv
def test_sdiv() -> t.CInt:
    stdio.printf("--- Test 4: LLVMIR sdiv ---\n")
    a: t.CInt = 100
    b: t.CInt = 4
    r: t.CInt = c.LLVMIR(f"sdiv i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
    stdio.printf("sdiv(100, 4)=%d (expect 25)\n", r)
    if r == 25:
        stdio.printf("LLVMIR sdiv OK\n")
    else:
        stdio.printf("LLVMIR sdiv FAIL\n")
    return 0


# Test 5: 位运算 and
def test_and() -> t.CInt:
    stdio.printf("--- Test 5: LLVMIR and ---\n")
    a: t.CInt = 255
    b: t.CInt = 15
    r: t.CInt = c.LLVMIR(f"and i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
    stdio.printf("and(255, 15)=%d (expect 15)\n", r)
    if r == 15:
        stdio.printf("LLVMIR and OK\n")
    else:
        stdio.printf("LLVMIR and FAIL\n")
    return 0


# Test 6: 位运算 or
def test_or() -> t.CInt:
    stdio.printf("--- Test 6: LLVMIR or ---\n")
    a: t.CInt = 240
    b: t.CInt = 15
    r: t.CInt = c.LLVMIR(f"or i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
    stdio.printf("or(240, 15)=%d (expect 255)\n", r)
    if r == 255:
        stdio.printf("LLVMIR or OK\n")
    else:
        stdio.printf("LLVMIR or FAIL\n")
    return 0


# Test 7: 位运算 xor
def test_xor() -> t.CInt:
    stdio.printf("--- Test 7: LLVMIR xor ---\n")
    a: t.CInt = 255
    b: t.CInt = 15
    r: t.CInt = c.LLVMIR(f"xor i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
    stdio.printf("xor(255, 15)=%d (expect 240)\n", r)
    if r == 240:
        stdio.printf("LLVMIR xor OK\n")
    else:
        stdio.printf("LLVMIR xor FAIL\n")
    return 0


# Test 8: 左移 shl
def test_shl() -> t.CInt:
    stdio.printf("--- Test 8: LLVMIR shl ---\n")
    a: t.CInt = 1
    b: t.CInt = 4
    r: t.CInt = c.LLVMIR(f"shl i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
    stdio.printf("shl(1, 4)=%d (expect 16)\n", r)
    if r == 16:
        stdio.printf("LLVMIR shl OK\n")
    else:
        stdio.printf("LLVMIR shl FAIL\n")
    return 0


# Test 9: LOut 输出赋值
def test_lout() -> t.CInt:
    stdio.printf("--- Test 9: LLVMIR LOut ---\n")
    a: t.CInt = 10
    b: t.CInt = 20
    out_val: t.CInt = 0
    c.LLVMIR(f"{c.LOut(out_val)} = add i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
    stdio.printf("LOut add(10, 20)=%d (expect 30)\n", out_val)
    if out_val == 30:
        stdio.printf("LLVMIR LOut OK\n")
    else:
        stdio.printf("LLVMIR LOut FAIL\n")
    return 0


# Test 10: icmp eq 比较
# 注意: TransPyV 用 sext i1 to i32 扩展布尔结果，true -> -1
def test_icmp_eq() -> t.CInt:
    stdio.printf("--- Test 10: LLVMIR icmp eq ---\n")
    a: t.CInt = 5
    b: t.CInt = 5
    r: t.CInt = c.LLVMIR(f"icmp eq i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
    stdio.printf("icmp eq(5, 5)=%d (expect nonzero)\n", r)
    if r != 0:
        stdio.printf("LLVMIR icmp eq OK\n")
    else:
        stdio.printf("LLVMIR icmp eq FAIL\n")
    return 0


# Test 11: icmp ne 比较
def test_icmp_ne() -> t.CInt:
    stdio.printf("--- Test 11: LLVMIR icmp ne ---\n")
    a: t.CInt = 5
    b: t.CInt = 3
    r: t.CInt = c.LLVMIR(f"icmp ne i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
    stdio.printf("icmp ne(5, 3)=%d (expect nonzero)\n", r)
    if r != 0:
        stdio.printf("LLVMIR icmp ne OK\n")
    else:
        stdio.printf("LLVMIR icmp ne FAIL\n")
    return 0


# Test 12: icmp slt 比较
def test_icmp_slt() -> t.CInt:
    stdio.printf("--- Test 12: LLVMIR icmp slt ---\n")
    a: t.CInt = 3
    b: t.CInt = 5
    r: t.CInt = c.LLVMIR(f"icmp slt i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
    stdio.printf("icmp slt(3, 5)=%d (expect nonzero)\n", r)
    if r != 0:
        stdio.printf("LLVMIR icmp slt OK\n")
    else:
        stdio.printf("LLVMIR icmp slt FAIL\n")
    return 0


# Test 13: srem 取余
def test_srem() -> t.CInt:
    stdio.printf("--- Test 13: LLVMIR srem ---\n")
    a: t.CInt = 17
    b: t.CInt = 5
    r: t.CInt = c.LLVMIR(f"srem i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
    stdio.printf("srem(17, 5)=%d (expect 2)\n", r)
    if r == 2:
        stdio.printf("LLVMIR srem OK\n")
    else:
        stdio.printf("LLVMIR srem FAIL\n")
    return 0


# Test 14: lshr 逻辑右移
def test_lshr() -> t.CInt:
    stdio.printf("--- Test 14: LLVMIR lshr ---\n")
    a: t.CInt = 256
    b: t.CInt = 2
    r: t.CInt = c.LLVMIR(f"lshr i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
    stdio.printf("lshr(256, 2)=%d (expect 64)\n", r)
    if r == 64:
        stdio.printf("LLVMIR lshr OK\n")
    else:
        stdio.printf("LLVMIR lshr FAIL\n")
    return 0


# Test 15: 嵌套在表达式中使用
def test_nested() -> t.CInt:
    stdio.printf("--- Test 15: LLVMIR nested in expression ---\n")
    a: t.CInt = 10
    b: t.CInt = 20
    # c.LLVMIR 结果参与后续运算
    llvmir_result: t.CInt = c.LLVMIR(f"add i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
    final_result: t.CInt = llvmir_result + 10
    stdio.printf("(LLVMIR add(10,20)) + 10 = %d (expect 40)\n", final_result)
    if final_result == 40:
        stdio.printf("LLVMIR nested OK\n")
    else:
        stdio.printf("LLVMIR nested FAIL\n")
    return 0


def llvmir_test() -> t.CInt:
    stdio.printf("=== llvmir_test: c.LLVMIR 内联 LLVM IR 测试 ===\n\n")
    test_add()
    test_sub()
    test_mul()
    test_sdiv()
    test_and()
    test_or()
    test_xor()
    test_shl()
    test_lout()
    test_icmp_eq()
    test_icmp_ne()
    test_icmp_slt()
    test_srem()
    test_lshr()
    test_nested()
    stdio.printf("\n=== llvmir_test 完成 ===\n")
    return 0
