NOP = "add $0, $0, $0"


@macro("reg u16") # noqa: F821
def delay(reg, cycles):
    """ place enough nop instructions to delay execution for `cycles`. """
    cycles = cycles.value
    static_cost = 4             # add (1) + addi (1) + final as.z (2)
    loop_cost = 4               # as.z (1) + jmp (3)
    if cycles < (static_cost + loop_cost):
        return "\n\t".join([NOP] * cycles)
    loops = 1 + ((cycles - static_cost) // loop_cost)
    extra = (cycles - static_cost) % loop_cost
    leftover = "\n\t".join([NOP] * extra)
    return """
        add  {reg}, $0, $0
        addi {reg}, {loops}
        as.z {reg}, {reg}, -1
        jmp -1
        {leftover}
    """.format(reg=reg, loops=loops, leftover=leftover)
