from ..registers import Register, RegisterMap
from ..utils import get_bits


def ARM_Registers():
    """Initializes registers for ARM architecture"""
    registers = [
        Register(8, x0=0xFFFFFFFFFFFFFFFF, w0=0xFFFFFFFF, r0=0xFFFFFFFF),
        Register(8, x1=0xFFFFFFFFFFFFFFFF, w1=0xFFFFFFFF, r1=0xFFFFFFFF),
        Register(8, x2=0xFFFFFFFFFFFFFFFF, w2=0xFFFFFFFF, r2=0xFFFFFFFF),
        Register(8, x3=0xFFFFFFFFFFFFFFFF, w3=0xFFFFFFFF, r3=0xFFFFFFFF),
        Register(8, x4=0xFFFFFFFFFFFFFFFF, w4=0xFFFFFFFF, r4=0xFFFFFFFF),
        Register(8, x5=0xFFFFFFFFFFFFFFFF, w5=0xFFFFFFFF, r5=0xFFFFFFFF),
        Register(8, x6=0xFFFFFFFFFFFFFFFF, w6=0xFFFFFFFF, r6=0xFFFFFFFF),
        Register(8, x7=0xFFFFFFFFFFFFFFFF, w7=0xFFFFFFFF, r7=0xFFFFFFFF),
        Register(8, x8=0xFFFFFFFFFFFFFFFF, w8=0xFFFFFFFF, r8=0xFFFFFFFF),
        Register(8, x9=0xFFFFFFFFFFFFFFFF, w9=0xFFFFFFFF, r9=0xFFFFFFFF),
        Register(8, x10=0xFFFFFFFFFFFFFFFF, w10=0xFFFFFFFF, r10=0xFFFFFFFF),
        Register(8, x11=0xFFFFFFFFFFFFFFFF, w11=0xFFFFFFFF, r11=0xFFFFFFFF),
        Register(8, x12=0xFFFFFFFFFFFFFFFF, w12=0xFFFFFFFF, r12=0xFFFFFFFF),
        Register(8, x13=0xFFFFFFFFFFFFFFFF, w13=0xFFFFFFFF, r13=0xFFFFFFFF),
        Register(8, x14=0xFFFFFFFFFFFFFFFF, w14=0xFFFFFFFF, r14=0xFFFFFFFF),
        Register(8, x15=0xFFFFFFFFFFFFFFFF, w15=0xFFFFFFFF, r15=0xFFFFFFFF),
        Register(8, x16=0xFFFFFFFFFFFFFFFF, w16=0xFFFFFFFF),
        Register(8, x17=0xFFFFFFFFFFFFFFFF, w17=0xFFFFFFFF),
        Register(8, x18=0xFFFFFFFFFFFFFFFF, w18=0xFFFFFFFF),
        Register(8, x19=0xFFFFFFFFFFFFFFFF, w19=0xFFFFFFFF),
        Register(8, x20=0xFFFFFFFFFFFFFFFF, w20=0xFFFFFFFF),
        Register(8, x21=0xFFFFFFFFFFFFFFFF, w21=0xFFFFFFFF),
        Register(8, x22=0xFFFFFFFFFFFFFFFF, w22=0xFFFFFFFF),
        Register(8, x23=0xFFFFFFFFFFFFFFFF, w23=0xFFFFFFFF),
        Register(8, x24=0xFFFFFFFFFFFFFFFF, w24=0xFFFFFFFF),
        Register(8, x25=0xFFFFFFFFFFFFFFFF, w25=0xFFFFFFFF),
        Register(8, x26=0xFFFFFFFFFFFFFFFF, w26=0xFFFFFFFF),
        Register(8, x27=0xFFFFFFFFFFFFFFFF, w27=0xFFFFFFFF),
        Register(8, x28=0xFFFFFFFFFFFFFFFF, w28=0xFFFFFFFF),
        Register(8, x29=0xFFFFFFFFFFFFFFFF, w29=0xFFFFFFFF),
        Register(8, x30=0xFFFFFFFFFFFFFFFF, w30=0xFFFFFFFF),
        Register(8, xzr=0xFFFFFFFFFFFFFFFF, wzr=0xFFFFFFFF),  # Zero register, must always equal zero

        Register(16, q0=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d0=0xFFFFFFFFFFFFFFFF, s0=0xFFFFFFFF, h0=0xFFFF, b0=0xFF),
        Register(16, q1=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d1=0xFFFFFFFFFFFFFFFF, s1=0xFFFFFFFF, h1=0xFFFF, b1=0xFF),
        Register(16, q2=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d2=0xFFFFFFFFFFFFFFFF, s2=0xFFFFFFFF, h2=0xFFFF, b2=0xFF),
        Register(16, q3=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d3=0xFFFFFFFFFFFFFFFF, s3=0xFFFFFFFF, h3=0xFFFF, b3=0xFF),
        Register(16, q4=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d4=0xFFFFFFFFFFFFFFFF, s4=0xFFFFFFFF, h4=0xFFFF, b4=0xFF),
        Register(16, q5=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d5=0xFFFFFFFFFFFFFFFF, s5=0xFFFFFFFF, h5=0xFFFF, b5=0xFF),
        Register(16, q6=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d6=0xFFFFFFFFFFFFFFFF, s6=0xFFFFFFFF, h6=0xFFFF, b6=0xFF),
        Register(16, q7=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d7=0xFFFFFFFFFFFFFFFF, s7=0xFFFFFFFF, h7=0xFFFF, b7=0xFF),
        Register(16, q8=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d8=0xFFFFFFFFFFFFFFFF, s8=0xFFFFFFFF, h8=0xFFFF, b8=0xFF),
        Register(16, q9=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d9=0xFFFFFFFFFFFFFFFF, s9=0xFFFFFFFF, h9=0xFFFF, b9=0xFF),
        Register(16, q10=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d10=0xFFFFFFFFFFFFFFFF, s10=0xFFFFFFFF, h10=0xFFFF, b10=0xFF),
        Register(16, q11=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d11=0xFFFFFFFFFFFFFFFF, s11=0xFFFFFFFF, h11=0xFFFF, b11=0xFF),
        Register(16, q12=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d12=0xFFFFFFFFFFFFFFFF, s12=0xFFFFFFFF, h12=0xFFFF, b12=0xFF),
        Register(16, q13=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d13=0xFFFFFFFFFFFFFFFF, s13=0xFFFFFFFF, h13=0xFFFF, b13=0xFF),
        Register(16, q14=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d14=0xFFFFFFFFFFFFFFFF, s14=0xFFFFFFFF, h14=0xFFFF, b14=0xFF),
        Register(16, q15=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d15=0xFFFFFFFFFFFFFFFF, s15=0xFFFFFFFF, h15=0xFFFF, b15=0xFF),
        Register(16, q16=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d16=0xFFFFFFFFFFFFFFFF, s16=0xFFFFFFFF, h16=0xFFFF, b16=0xFF),
        Register(16, q17=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d17=0xFFFFFFFFFFFFFFFF, s17=0xFFFFFFFF, h17=0xFFFF, b17=0xFF),
        Register(16, q18=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d18=0xFFFFFFFFFFFFFFFF, s18=0xFFFFFFFF, h18=0xFFFF, b18=0xFF),
        Register(16, q19=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d19=0xFFFFFFFFFFFFFFFF, s19=0xFFFFFFFF, h19=0xFFFF, b19=0xFF),
        Register(16, q20=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d20=0xFFFFFFFFFFFFFFFF, s20=0xFFFFFFFF, h20=0xFFFF, b20=0xFF),
        Register(16, q21=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d21=0xFFFFFFFFFFFFFFFF, s21=0xFFFFFFFF, h21=0xFFFF, b21=0xFF),
        Register(16, q22=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d22=0xFFFFFFFFFFFFFFFF, s22=0xFFFFFFFF, h22=0xFFFF, b22=0xFF),
        Register(16, q23=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d23=0xFFFFFFFFFFFFFFFF, s23=0xFFFFFFFF, h23=0xFFFF, b23=0xFF),
        Register(16, q24=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d24=0xFFFFFFFFFFFFFFFF, s24=0xFFFFFFFF, h24=0xFFFF, b24=0xFF),
        Register(16, q25=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d25=0xFFFFFFFFFFFFFFFF, s25=0xFFFFFFFF, h25=0xFFFF, b25=0xFF),
        Register(16, q26=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d26=0xFFFFFFFFFFFFFFFF, s26=0xFFFFFFFF, h26=0xFFFF, b26=0xFF),
        Register(16, q27=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d27=0xFFFFFFFFFFFFFFFF, s27=0xFFFFFFFF, h27=0xFFFF, b27=0xFF),
        Register(16, q28=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d28=0xFFFFFFFFFFFFFFFF, s28=0xFFFFFFFF, h28=0xFFFF, b28=0xFF),
        Register(16, q29=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d29=0xFFFFFFFFFFFFFFFF, s29=0xFFFFFFFF, h29=0xFFFF, b29=0xFF),
        Register(16, q30=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d30=0xFFFFFFFFFFFFFFFF, s30=0xFFFFFFFF, h30=0xFFFF, b30=0xFF),
        Register(16, q31=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, d31=0xFFFFFFFFFFFFFFFF, s31=0xFFFFFFFF, h31=0xFFFF, b31=0xFF),

        # CPSR register
        Register(
            4,
            n=0x80000000,  # negative flag
            z=0x40000000,  # zero flag
            c=0x20000000,  # carry flag
            v=0x10000000,  # overflow flag
            t=0x10,        # thumb mode flag
            f=0x20,        # FIQ disable
            i=0x40,        # IRQ disable
        ),
    ]

    # In 32-bit context, r13 is the same as sp, r14 is the same as lr and r15 is the same as pc.
    # So overwrite these 3 registers with new Register instances containing the extra alias.
    # In 64-bit context, sp and pc are separate registers, so add them now. lr is the same as r30
    # but since it is always referred to as r30 in assembly, no alias is created for it.
    if get_bits() == 64:
        registers.extend([
            Register(8, sp=0xFFFFFFFFFFFFFFFF, wsp=0xFFFFFFFF),
            Register(8, pc=0xFFFFFFFFFFFFFFFF)
        ])
    else:
        registers[13] = Register(8, x13=0xFFFFFFFFFFFFFFFF, w13=0xFFFFFFFF, r13=0xFFFFFFFF, sp=0xFFFFFFFF)
        registers[14] = Register(8, x14=0xFFFFFFFFFFFFFFFF, w14=0xFFFFFFFF, r14=0xFFFFFFFF, lr=0xFFFFFFFF)
        registers[15] = Register(8, x15=0xFFFFFFFFFFFFFFFF, w15=0xFFFFFFFF, r15=0xFFFFFFFF, pc=0xFFFFFFFF)

    return RegisterMap(registers)
