8 PROGRAM FLOW
  INSTRUCTIONS
 Figure 8-0.
 Table 8-0.
 Listing 8-0.

 The instruction set provides program flow instructions for controlling the
 sequence in which the DSP executes instructions. Generally, the instruc-
 tions in a program execute sequentially, one after another, unless
 otherwise directed by various program structures—branches, loops, sub-
 routines, or interrupts—that intervene and temporarily or permanently
 redirect this linear flow. These program structures enable an application to
 respond to events or conditions as they occur. Program flow control
 instructions include:
    • “DO UNTIL (PC relative)” on page 8-22
    • “Direct JUMP (PC relative)” on page 8-27
    • “CALL (PC relative)” on page 8-30
    • “JUMP (PC relative)” on page 8-34
    • “Long CALL” on page 8-37
    • “Long JUMP” on page 8-40
    • “Indirect CALL” on page 8-42
    • “Indirect JUMP” on page 8-45
    • “Return from Interrupt” on page 8-48
    • “Return from Subroutine” on page 8-52
    • “PUSH or POP Stacks” on page 8-55
    • “PUSH or POP Stacks” on page 8-55



                             ADSP-219x Instruction Set Reference         8-1
Program Flow Instructions




         • “FLUSH CACHE” on page 8-61
         • “Set Interrupt” on page 8-62
         • “Clear Interrupt” on page 8-64
         • “No Operation” on page 8-66
         • “Idle” on page 8-67
         • “Mode Control” on page 8-69
      This chapter describes each of the move instructions and the following
      related topics:
         • “Conditions” on page 8-2
         • “Counter-Based Conditions” on page 8-3
         • “CCODE Register” on page 8-4
         • “MSTAT Mode Control Register” on page 8-4
         • “Branch Options” on page 8-5
         • “Addressing Branch Targets” on page 8-6
         • “Stacks” on page 8-7
         • “Stack Status Flags” on page 8-12
         • “Interrupts” on page 8-13
         • “Application Performance” on page 8-17

Conditions
      Table 2-8 on page 2-15 lists the conditions used in conditional (IF COND)
      instructions and their opcodes. Besides these conditions (which mainly
      relate to the status of the ALU, multiplier, and counter) it is possible to



8-2        ADSP-219x Instruction Set Reference
                                            Counter-Based Conditions




  use the SWCOND condition and the value in the CCODE register to test for
  other DSP status conditions. For more information, see “Condition Code
  (CCODE) Register” on page 2-6. Also, you can test for bit states to gener-
  ate conditions using the TSTBIT instruction. For more information, see
  “Bit Manipulation: TSTBIT, SETBIT, CLRBIT, TGLBIT” on page
  3-18.,

Counter-Based Conditions
  Both IF Condition (conditional) instructions and the DO UNTIL (loop)
  instructions can base execution on the NOT CE condition. Although the DO
  UNTIL instruction uses the CE syntax only, the condition actually tested is
  NOT CE—counter not expired.

  To use a counter condition with either instruction type, you must load the
  CNTR register with an initial counter value (>1) before issuing the instruc-
  tion that uses the counter condition.
  There are some important differences between how conditional and loop
  instructions implement (decrement and test) the counter condition:
     • To implement the NOT CE condition in an IF Condition (condi-
       tional) instruction, the DSP decrements and tests the value loaded
       in the CNTR register before executing the conditional instruction. For
       a conditional instruction based on NOT CE, the DSP tests whether the
       CNTR register contains a value >1.

     • To implement the CE condition in a DO UNTIL (loop) instruction, the
       DSP loads the loop counter stack from the CNTR register at the start
       of the loop, then decrements and tests the counter value in the loop
       counter stack (not the CNTR register) at the end of each pass through
       the loop. For a loop instruction based on CE, the DSP tests whether
       the loop counter stack’s counter value >0. For more information,
       see “Loop Stacks Operation” on page 8-10.




                              ADSP-219x Instruction Set Reference         8-3
Program Flow Instructions




CCODE Register
      Table 2-3 on page 2-7 lists the CCODE register values used to test the
      SWCOND and NOT SWCOND software conditions. Although the source each
      value tests is specific to each DSP in the ADSP-219x family, these values
      (except 0x08 and 0x09) map to the software interrupt bits in the IMASK
      and IRPTL registers.
      To test for any software condition, first load the CCODE register with the
      value of the source you want to test, then test for the true or false state.
      For example, 0x08 represents ALU saturation status, you might code this
      sequence:
         CCODE = 0x08;            /* ALU Saturated (AR_SAT) cond */
         AR = AX0 + AY1;
         IF SWCOND JUMP fix_data; /* Jump to fix_data if AR_SAT */

         fix_data:
           NOP;                         /* code to fix data ALU_SAT */

      Or, to test for a shifter overflowed result:
         CCODE = 0x09;             /* Shifter Overflowed (SV) cond */
         AR = 3; SE = AR;      /* shift code, left shift 3 bits */
         SI = 0xB6A3;          /* value of hi word of input data */
         IF NOT SWCOND SR = ASHIFT SI (HI); /* ashift high word if SV */

      A value written to CCODE isn’t available on the next cycle, so you must
      insert at least one instruction between the write to CCODE and the condi-
      tional instruction that tests the software condition. Otherwise, the
      conditional instruction will test the previous value of CCODE.

MSTAT Mode Control Register
      As shown in Table 2-6 on page 2-11, bits 0 through 7 of the MSTAT register
      control various DSP modes. These modes determine some conditions for
      how status flags are set.




8-4        ADSP-219x Instruction Set Reference
                                                         Branch Options




Branch Options
  All of the DSP’s branch instructions (except DO UNTIL and LJUMP/LCALL),
  support two branch options: immediate and delayed. These options deter-
  mine whether the DSP executes the first two instructions directly
  following the branch instruction before it executes the instruction at the
  branch target address. Because of the instruction pipeline, a number of
  latency cycles (usually four) occur between execution of the branch
  instruction and execution of the branch target instruction.
  By default, the branch instructions perform an immediate branch, which
  means that the next instruction the DSP executes after the branch instruc-
  tion is the instruction at the branch target address, but only after a
  number of NOP cycles. Using the delayed option, you can salvage two of
  the NOP cycles and perform useful work. To do so, you include the (DB)
  option in the branch instruction and code in the two delay slots directly
  following the branch instruction the two instructions that you want exe-
  cuted before the branch target instruction.

  ! You cannot insert      or
                            JUMP  instructions in delay branch slots.
                                        CALL
    You can insert only one two-word instruction, and it must occupy
         the first delay branch slot.
  When the DSP executes an RTI or RTS instruction to return to the main
  program, it returns to execute the first or third instruction after the
  branch instruction, depending on whether the branch is immediate or
  delayed.
  Return from immediate branch:
     IF AV CALL immediate_pump; /* immed branches may be cond */
       NOP;           /* RTS returns program flow here */
       NOP;

     immediate_pump:
       NOP;
       RTS;




                              ADSP-219x Instruction Set Reference      8-5
Program Flow Instructions




      Return from delayed branch:
         CALL delayed_pump (DB); /* delayed branches must be uncond */
           NOP;        /* 1st_delay_instruction */
           NOP;        /* 2nd_delay_instruction */
           NOP;        /* RTS returns program flow here */
           NOP;

         delayed_pump:
           NOP;
           RTS;


Addressing Branch Targets
      When you issue a JUMP or CALL instruction, you specify the address of the
      instruction to branch to in one of three ways:
         • PC relative
           Offset from the current PC. The immediate value you specify in the
           instruction is added to the PC of the branch instruction to form the
           address of the branch target location. For example, the CALL in the
           following code goes to PC-relative address (find_me):
             .EXTERN find_me; /* matches .global in other file */
             CALL find_me (DB);
             NOP;

         • Far absolute
           The full 24-bit address of the branch target location is specified in
           the instruction. You can program this instruction explicitly in an
           LJUMP/ LCALL instruction. The assembler automatically substitutes
           this instruction when the actual address assembled from a PC rela-
           tive address is insufficient.




8-6        ADSP-219x Instruction Set Reference
                                                                       Stacks




     • Indirect
       The address of the branch target location is specified using a DAG
       index register (I0−I7) and the IJPG page register. For example, the
       CALL in the following code goes to an address using the indirect
       address from the I0 register:
         .EXTERN find_me_too; /* matches .global in other file */
         IJPG = 0x0;          /* set memory page for CALL */
         I0 = find_me_too;    /* loads I0 with address */
         NOP;
         NOP;
         CALL (I0) (DB);
         NOP;


Stacks
  Loops and other branch instructions use the DSP’s stacks to implement
  their respective operations.
     • PC stack (33 words × 24 bits)
         Holds the address of the next instruction to execute on return from
         a called subroutine. Only the CALL, RTI, RTS, and PUSH/POP PC
         instructions use this stack.
     • Loop begin stack (8 words × 24 bits)
         Holds the address of the first instruction in a loop. Only the DO UNTL
         and PUSH/POP LOOP instructions use this stack.
     • Loop end stack (8 words × 24 bits)
         Holds the address of the last instruction in a loop. Only the DO UNTL
         and PUSH/POP LOOP instructions use this stack.
     • Loop counter stack (8 words × 16 bits)
         Holds the current value of the loop counter that is loaded from the
         CNTR register. This value—not the value in the CNTR register—is




                              ADSP-219x Instruction Set Reference          8-7
Program Flow Instructions




             tested and decremented at the end of each pass through the loop.
             Only the DO UNTL and PUSH/POP LOOP instructions use this stack.
         • Status stack (16 words × 32 bits)
             Holds the current value of the ASTAT and MSTAT registers. Only RTI
             and PUSH/POP STS instructions use this stack. (When globally
             enabled and unmasked interrupts occur, the DSP automatically
             saves the two status registers to this stack.)

PC and Status Stack Operation
      Applications use these stacks to implement function calls and interrupt
      service routines (ISRs).
      Function Calls. When a CALL instruction executes, it automatically pushes
      onto the PC stack the address of the next instruction to execute upon
      returning from the subroutine. The CALL instruction does not push the
      status registers onto the status stack.
      The RTS instruction, executed at the end of the subroutine, returns pro-
      gram execution to either the first or third instruction following the CALL
      instruction, depending on whether the CALL was immediate or delayed,
      respectively.




8-8        ADSP-219x Instruction Set Reference
                                                                     Stacks




ISRs. When interrupts are globally enabled and an unmasked interrupt
occurs, it cause the DSP to automatically save its current state before
entering the interrupt’s ISR. To do so, the DSP:
   • Pushes onto the PC stack the address of the next instruction to exe-
     cute upon returning from the ISR.
       If the interrupt is higher than the core’s current level of operation,
       the DSP pushes the address of the current instruction onto the PC
       stack and branches immediately to the interrupt’s ISR.
       If the interrupt is lower than the core’s current level of operation,
       the DSP finishes the current operation, pushes the address of the
       next sequential instruction onto the PC stack, and then branches to
       the interrupt’s ISR.
   • Pushes onto the status stack, in order, the ASTAT and MSTAT registers.
The RTI instruction, executed at the end of the ISR, pops the PC stack
returning program execution to the instruction at the retrieved address. It
also pops the status stack, restoring the ASTAT and MSTAT registers to their
previous values. So, if the ISR enables any of the MSTAT mode bits, the RTI
operation automatically disables them.
PUSH/POP PC/STS. You can explicitly push and pop the PC and status
stacks as needed. The DSP automatically performs these operations when
using nested interrupts.
Pushing (PUSH STS) and popping (POP STS) the status stack automatically
saves or restores the ASTAT and MSTAT registers. But, pushing (PUSH PC) and
popping (POP PC) the PC stack requires a few more steps that involve the
STACKA and STACKP registers.

For PUSH/POP PC operations, the 16-bit STACKA register supplies or receives,
respectively, the sixteen LSBs of an instruction’s 24-bit address, and the
8-bit STACKP register supplies or receives the eight MSBs. So, before you




                            ADSP-219x Instruction Set Reference          8-9
Program Flow Instructions




   issue a PUSH PC instruction, you must load the STACKA and STACKP registers
   with the appropriate values:
       STACKA = 0x3521;
       STACKP = 0x02;
       PUSH PC;

   Likewise, after you pop the PC stack, you can check the contents of the
   STACKA and STACKP registers:

       POP PC;
       AX0 = STACKA;
       AY0 = STACKP;


   " Abut a or or
            PUSH
               PUSH
                    POP PC has one cycle of latency for all SSTAT register bits,
                        POP LOOP or STS has one cycle of latency only for the
          STKOVERFLOW bit in the SSTAT register.


Loop Stacks Operation
   Applications use this stack to implement loop operations.
   When a DO UNTIL instruction executes, it automatically pushes data onto
   the three loop stacks:
       • Loop begin stack Receives the loop start address (current PC).
       • Loop end stack      Receives the loop end address.
       • Counter stack       Receives the counter value from the CNTR register
                             for finite loops. If the loop is infinite, the
                             counter stack still receives the counter value; the
                             DSP decrements this value on the stack, but
                             ignores the result.
   Finite Loops (DO <loop> UNTIL CE). The CE terminator specifies a finite
   loop. To accommodate the write effect latency, you must load the CNTR
   register with the number of iterations to execute the loop at least two
   instructions before the DO UNTIL instruction. When the DO UNTIL instruc-



8-10     ADSP-219x Instruction Set Reference
                                                                      Stacks




tion executes, it automatically pushes the CNTR value onto the counter
stack. (The CNTR register retains the original value, until explicitly changed
with a data move or POP LOOP instruction.)
The loop mechanism decrements and tests the value at the top of the
counter stack at the end of each pass through the loop. The loop ends
when the counter expires (decrements to 1). At loop end, program execu-
tion automatically continues with the instruction directly following the
end of the loop.
Infinite Loops (DO <loop> [UNTIL FOREVER]). To end an infinite loop, the
loop must contain an explicit JUMP to an instruction outside the loop to
exit and end it. The JUMP is based on a condition created inside the loop
and typically branches to a POP LOOP instruction to recover the loop
stacks—the goal is to adjust the loop stack pointers, not retrieve the loop
start and end addresses. After that, another JUMP instruction returns pro-
gram execution to the next sequential instruction following the loop’s end.
PUSH/POP LOOP. You can explicitly push and pop the loop stacks.
These operations are necessary to recover and maintain the loop stacks
when you abort a loop.
PUSH/POP LOOP instructions operate on all three loop stacks in parallel.
Both operations involve the STACKA, STACKP, LPSTACKA, LPSTACKP, and
CNTR registers. Before you issue a PUSH LOOP instruction, you must load the
STACKA, STACKP, LPSTACKA, and LPSTACKP registers with appropriate values.

   • The 16-bit STACKA and 8-bit STACKP register supply or receive the
     loop start address from the loop begin stack.
       STACKA holds the sixteen LSBs of the 24-bit, loop start address, and
       STACKP holds the eight MSBs.




                           ADSP-219x Instruction Set Reference          8-11
Program Flow Instructions




       • The 16-bit LPSTACKA and 16-bit LPSTACKP register supply or receive
         the loop end address from the loop end stack. (Only bit 15 and bits
         7:0 of LPSTACKP are valid—bits 14:8 should always be zero.)
          LPSTACKA holds the sixteen LSBs of the 24-bit, loop end address, and
          LPSTACKP holds the eight MSBs in bits 7:0 and the loop terminator
          condition, CE or FOREVER, in bit 15. When the FOREVER bit is set, the
          loop logic ignores the loop counter value.
       • The 16-bit CNTR register supplies or receives the counter value from
         the counter stack.
          On a pop, the CNTR register receives whatever value is at the top of
          the counter stack. For finite loops, since the value in the counter
          stack is decremented at the end of each pass through the loop, a POP
          loads CNTR with a new value, overwriting the original count value,
          unless the POP occurs before the first pass through the loop.
          For infinite loops, the PUSH LOOP instruction pushes the current
          value of the CNTR register onto the loop counter stack. This value is
          irrelevant but pushing it maintains the pointer’s correct position in
          the loop counter stack.

   " Abut a or or
            PUSH
                PUSH
                    POP PC has one cycle of latency for all SSTAT register bits,
                        POP LOOP or STS has one cycle of latency only for the
          STKOVERFLOW bit in the SSTAT register.


Stack Status Flags
   As shown in Table 2-7 on page 2-14, bits 0 through 7 of the SSTAT register
   record the status of the DSP’s stacks. This status information is useful for
   managing the stack and servicing stack interrupts.
   The stack interrupt is always generated by a stack overflow condition, but
   can also be generated by ORing together the stack overflow status (STK-




8-12     ADSP-219x Instruction Set Reference
                                                                    Interrupts




  OVERFLOW) bit and stack high/low level status ( PCSTKLVL) bit. The level bit
  is set when:
     • The PC stack is pushed and the resulting level is at the high water
       mark.
     • The PC stack is popped and the resulting level is at the low water-
       mark.
  This spill-fill mode (using the stack to generate a stack interrupt) is dis-
  abled on reset. Two bits in the ICNTL register (bit 10 —PC Stack
  Interrupt Enable) can be used to enable interrupts for the three corre-
  sponding stacks.

  " When  switching on spill-fill mode, a spurious low water mark inter-
    rupt may occur (depending on the level of the stack). In this case,
         the interrupt handler should push some values on the stack to raise
         the level above the low watermark level.

Interrupts
  The DSP uses interrupts to communicate with the outside world. The
  DSP’s core generates internal interrupts, the peripherals generate external
  interrupts, and software can generate software interrupts.
  When an interrupt occurs, the DSP suspends its current operation, saving
  the ASTAT and MSTAT registers, and jumps to the location in memory of the
  interrupt’s service routine (ISR) and begins executing that program code.
  When it has completed the interrupt’s ISR, an RTI instruction at the end
  of the routine forces program flow to return to the suspended operation
  and continue executing code at the location where it left off, after the DSP
  restores the ASTAT and MSTAT registers.
  Each interrupt has a priority rank and its own vector address. The inter-
  rupt’s vector address specifies the location in memory of its service
  routine. Its priority determines the order in which the interrupt gets ser-




                             ADSP-219x Instruction Set Reference          8-13
Program Flow Instructions




   viced relative to the other interrupts. An interrupt with higher priority
   gets serviced before one with lower priority. As shown in Table 2-5 on
   page 2-10, the lower the interrupt’s position in the IMASK/IRPTL register
   the higher its priority.
   To implement and use interrupts, your software must perform these tasks:
       • Globally enable interrupts.
       • Individually enable the particular interrupt.
       • At the beginning of the ISR, switch context to secondary register
         sets and perform the necessary tasks to handle the interrupt condi-
         tion. For details, see “Switching Contexts” on page 8-16.
          If your program requires nested interrupts, it might need to perform
          a few extra tasks within each interrupt’s ISR. For details, see “Nest-
          ing Interrupts” on page 8-16.
       • At the end of the ISR, insert an RTI instruction to branch back (RTI)
         to the suspended operation. The RTI instruction automatically
         switches context back to the primary register sets.
       • Continue executing program code at the return address.

Enabling Interrupts
   When an interrupt occurs, the DSP services it only when all interrupts are
   globally enabled and the particular interrupt is individually enabled. Typ-
   ically, you enable interrupts both globally and individually in your main
   program and at the appropriate place wait for an interrupt to occur.
   Global Interrupts. You can enable and disable interrupts globally using
   these instructions:
       ENA INT;       /* Enable interrupts globally */
       DIS INT;       /* Disable interrupts globally */




8-14     ADSP-219x Instruction Set Reference
                                                                 Interrupts




With interrupts globally disabled, the DSP does not recognize or latch any
interrupts that occur and so cannot service them.
Individual Interrupts. You can enable and disable interrupts individually
using the register load instruction (for details, see, “Direct Register Load”
on page 7-27). For example, to enable (unmask) interrupts 3, 5, 7, and 8,
you set them to 1:
   IMASK = 0x01A8; /* Enable interrupts 8, 7, 5, & 3 only */

Interrupt 0 is nonmaskable in IMASK and cannot be enabled or disabled
globally.
With interrupts globally enabled and individual interrupts enabled in
IMASK, the DSP automatically services them when it detects their respec-
tive bits set in IRPTL.
With interrupts globally enabled and individual interrupts disabled in
IMASK, when they occur and are latched in IRPTL, you can choose to
unmask their respective bits in IRPTL and service them or to clear their bits
and reject them. For example:
   ENA INT;           /* globally enable ints */
   IMASK = 0x0000;    /* individually disable all ints */
   NOP;
   NOP;               /* any number of instructions */
   NOP;
   AX0 = IRPTL;           /* load IRPTL into AX0 */
   AF = TSTBIT 8 OF AX0; /* test interrupt 8 */
   IF NE JUMP normal;    /* If 0 continue normal flow */
   AR = CLRBIT 8 of AX0; /* else clear interrupt (bit 8) */
   IRPTL = AR;           /* load IRPTL with new value */
   normal:
      NOP;               /* continue normal program flow */

IMASK is the interrupt mask register, and IRPTL is the interrupt latch regis-
ter. As shown in Table 2-5 on page 2-10, the IMASK and the IRPTL registers
match each other bit for bit.




                           ADSP-219x Instruction Set Reference          8-15
Program Flow Instructions




Switching Contexts
   The DSP has two sets of DAG address registers and two sets of data regis-
   ters that enable you to quickly switch between the context of normal
   processing and the context of interrupt processing as needed. The second-
   ary register sets eliminate the need to save the state of the data and address
   registers before processing an interrupt and reduces interrupt latency. (For
   details on DSP modes, see “MSTAT Mode Control Register” on
   page 8-4.)
   Typically, you switch from primary to secondary registers at the beginning
   of the interrupt’s ISR. To do so, you use the following instructions:
       ENA SEC_REG;       /* enable secondary data registers */
       ENA SEC_DAG;       /* enable secondary DAG address registers */

   You use the RTI instruction at the end of the routine to return program
   flow to the main program. This instruction automatically switches context
   back to the primary registers when it restores the ASTAT, MSTAT, and SSTAT
   registers. So, for example, an interrupt service routine might look like this:
       service_interrupt:
         ENA SEC_REG, ENA SEC_DAG;        /* enable secondary registers */
         NOP;
         NOP;                             /* ISR code */
         NOP;
         RTI;                             /* return from interrupt and */
                                          /* enable primary registers */


Nesting Interrupts
   Nested interrupts enable the DSP to respond to more than one interrupt
   at a time. A higher priority interrupt suspends a lower priority interrupt’s
   routine. After the higher priority interrupt’s RTI executes, the lower prior-
   ity interrupt’s routine continues executing.
   Without nested interrupts, only one interrupt at a time gets serviced, so
   other interrupts remain pending until the RTI of the current routine exe-
   cutes. Then the pending interrupt with highest priority gets serviced.



8-16     ADSP-219x Instruction Set Reference
                                             Application Performance




  To use nested interrupts, you must enable them in the ICNTL register. To
  do so, you explicitly set bit 4 of INCTL:
     ICNTL = 0x0010;

  Once enabled, any interrupt with higher priority than the currently exe-
  cuting ISR suspends that ISR’s execution. Table 2-4 on page 2-8 lists and
  describes the bits of the ICNTL register.
  The DSP supports up to sixteen nested interrupts, but has only one set of
  secondary data and DAG address registers. So, if your application uses
  deeply nested interrupts, you may need to manually save the state of the
  data registers and DAG address registers to memory in your ISR routines.
   To do so:
     • Set up a segment in memory to save the current state of the data and
       DAG address registers.
     • In the ISR, save to memory the state of the data registers and the
       state of the DAG address registers that you intend to use.

Application Performance
  The ADSP-219x’s instruction set provides many ways to optimize code to
  accommodate particular applications. This section discusses optimization
  strategies for these topics:
     • Exiting a loop
     • Using long jumps and calls
     • Effect latencies

Exiting a Loop
  When you exit an infinite loop or abort a finite loop prematurely, the loop
  hardware fixes and restores the loop stacks before the POP LOOP instruction



                            ADSP-219x Instruction Set Reference         8-17
Program Flow Instructions




   executes. So, with few restrictions, you can branch out of a loop from
   almost any location, regardless of the length of the loop. However, for
   optimal performance, consider these scenarios:
       • Jumps or calls nearby loop ends may add extra cycles of loop stack
         clean-up when the jump or call is taken.
          CNTR = 5;
          MX0 = 0xFF;
          MY0 = 0xFF;
          DO mac_loop UNTIL CE;    /* start of mac_loop */
            NOP;
            NOP;
            MR = MX0 * MY0 (SS);
            IF MV JUMP abort_loop;
          mac_loop:
            NOP;                   /* end of mac_loop */
          NOP;                     /* 1st instr after mac_loop */
          NOP;                     /* 2nd instr after mac_loop */
          NOP;                     /* 3rd instr after mac_loop */
          abort_loop:              /* loop exit routine */
            POP LOOP;
            JUMP mac_loop + 1;

          The jump to abort_loop takes 1, 2, or 3 extra cycles, depending on
          whether the first, second, and third instruction after the end of the
          mac_loop are also loop ends, to clean up the loop stacks before the
          POP LOOP instruction executes. Impact on performance is minimal if
          the POP occurs only once.
       • Jumps or calls nearby loop ends add 1, 2, or 3 extra cycles each time
         the branch is taken.
          CNTR = 5;
          DO little_loop UNTIL CE;
            NOP;          /* 1st instr. of little_loop */
            NOP;          /* 2nd instr. of little_loop */
            NOP;          /* 3rd instr. of little_loop */
            IF MV CALL fix_my_data;
          little_loop:
            NOP;          /* end of little_loop */
            NOP;          /* 1st instr. after little_loop */




8-18     ADSP-219x Instruction Set Reference
                                        Application Performance




     NOP;             /* 2nd instr. after little_loop */
     NOP;             /* 3rd instr. after little_loop */
     NOP;             /* 4th instr. after little_loop */

   fix_my_data:
     NOP;
     NOP;
     RTS;

   The call to fix takes 1, 2, or 3 extra cycles, depending on whether
   the first, second, and third instructions after the end of little_loop
   are also loop ends, to clean up the loop stacks. To avoid the degra-
   dation in performance this construct incurs, you could move the
   CALL instruction further up in the loop or insert the called subrou-
   tine in the loop.
• Because the loop begin stack and PC stack are separate and distinct,
  this loop construct causes a loop to fall gracefully through the next
  loop end.
   CNTR = 5;
   DO bigger_loop UNTIL CE;
     NOP;          /* 1st instr. of bigger_loop */
     NOP;          /* 2nd instr. of bigger_loop */
     NOP;          /* 3rd instr. of bigger_loop */
     IF MV CALL fix_bigger_data;
     NOP;
     NOP;
   bigger_loop:
     NOP;          /* end of bigger_loop */
     NOP;          /* 1st instr. after bigger_loop */
     NOP;          /* 2nd instr. after bigger_loop */
     NOP;          /* 3rd instr. after bigger_loop */

   fix_bigger_data:
     NOP;
     NOP;
     RTS;

   The call to fix_bigger_data takes no extra cycles, unless the loop is
   aborted. One abort routine can serve all loops in nearby code space




                      ADSP-219x Instruction Set Reference          8-19
Program Flow Instructions




          since the routine is identical for each. Even after the loop is aborted,
          the end of the bigger_loop still executes, and the loop falls grace-
          fully out.

Using Long Jumps and Calls
   The instruction set provides several jump/call instructions that support
   different address ranges for addressing branch targets:
       • -4096 to +4095           “Direct JUMP (PC relative)” on page 8-27
       • -32768 to +32767         “CALL (PC relative)” on page 8-30
       • -32768 to +32767         “JUMP (PC relative)” on page 8-34
       • -16777216 to +16777215“Long CALL” on page 8-37
       • -16777216 to +16777215“Long JUMP” on page 8-40
   Usually, programmers must determine in advance the offset of the target
   from the branch and use the appropriate branch instruction, making sure
   the address of the branch target falls within the address range of the
   branch instruction.
   However, using an option provided in the assembler and in the linker with
   any of the PC relative branch instructions, you can let the tools determine
   and select which branch instruction to use based on the actual address of
   the branch target. To do so, you encode PC relative branch instructions
   and use the assembler’s and linker’s -jcs21 option, which directs the tools
   to substitute, during linking, LJUMP or LCALL for any particular PC relative
   branch instruction as appropriate. For details, see the Assembler Manual
   for ADSP-219x Family DSPs and the Linker & Utilities Manual for
   ADSP-219x Family DSPs.
   When using the linker’s -jcs21 option, you need to understand how it
   alters the linker’s operation, so you can fine tune your code accordingly.




8-20     ADSP-219x Instruction Set Reference
                                               Application Performance




  When the linker substitutes LJUMP or LCALL for a corresponding PC rela-
  tive branch instruction:
     • It substitutes an absolute address for the PC relative address.
     • If it encounters the (DB) option in a PC relative instruction, it moves
       the 48 bits (either two one-word instructions or one two-word
       instruction) from the two delay slots following the PC relative
       instruction and inserts them directly in front of the LCALL or LJUMP
       instruction.
         For conditional PC relative instructions, this procedure could
         change the condition code upon which the branch instruction is
         predicated. To avoid this potential bug, base (DB) branch instruc-
         tions on negated conditions (IF NOT COND), not positive ones (IF
         COND).

     • For unconditional PC relative instructions, it always encodes the
       TRUE condition.


Effect Latencies
  An effect latency occurs when some instructions write or load a value into
  a register, which changes the value of one or more bits in the register.
  Effect latency refers to the time it takes after the write or load instruction
  for the effect of the new value to become available for other instructions to
  use. For more information, see “Register Load Latencies” on page 7-9.




                             ADSP-219x Instruction Set Reference          8-21
Program Flow Instructions




DO UNTIL (PC relative)

     DO <Imm12> [UNTIL <Term>] ;


FUNCTION

    Sets up the looping circuitry for zero-overhead looping. The DO UNTIL
    instruction uses the current PC (Program Counter) as the basis for deter-
    mining the beginning of the loop and the PC-relative 12-bit offset value
    (Imm12) as the end of a loop.
INPUT

    Imm12    12-bit, positive offset value added to the address (PC) of the DO
             UNTIL instruction. Valid values range from 1 to 4095. (For good
             programming practice, use declared labels.)
    Term     Loop terminator. Valid loop termination conditions are FOREVER
             and CE.
OUTPUT

    None.
STATUS FLAGS


Affected Flags–set or cleared by the operation    Unaffected Flags

LPSTKEMPTY (always cleared), LPSTKFULL,            PCSTKEMPTY, PCSTKFULL, PCSTKLVL,
STKOVERFLOW                                        STSSTKEMPTY

For information on these status bits in the SSTAT register, see Table 2-7 on page 2-14.




8-22        ADSP-219x Instruction Set Reference
                                                    DO UNTIL (PC relative)




DETAILS

   The loop begins at the instruction directly following the DO UNTIL instruc-
   tion (PC + 1) and ends at the instruction located at the offset address
   specified in the DO UNTIL instruction—(PC + <imm12>).
   When using the FOREVER (infinite loop) termination condition, you must
   explicitly exit the loop by generating a status condition on which to base a
   jump to a location outside the loop. If you omit a terminator (DO <loop>),
   the instruction defaults to FOREVER.
   When using the CE (counter expired) termination condition, before enter-
   ing the loop, you must load the CNTR register with the number of times to
   execute the loop. Each pass through the loop decrements and tests the
   counter value in the loop counter stack, not the CNTR register (for details,
   see “Loop Stacks Operation” on page 8-10). When the counter expires,
   looping terminates.

   " Ifter.using termination, you must load a value >1 in the
                  CE                                                CNTR regis-



   Finite loops ( CE terminator) execute repeatedly until the loop terminator
   occurs. Infinite loops (FOREVER) execute repeatedly until a condition
   occurs that invokes an explicit jump to the address of an instruction out-
   side the loop.
   At execution, the DO UNTIL instruction pushes:
      • The address of the loop start instruction (PC + 1) onto the loop begin
        stack.
      • The address of the loop end instruction (PC + <imm12>) and the code
        of the loop terminator onto the loop end stack.
      • The contents of the CNTR register onto the loop counter stack.




                             ADSP-219x Instruction Set Reference          8-23
Program Flow Instructions




   During execution of a finite loop, the DSP tests and decrements the loop
   counter value stored in the loop counter stack—not the value in the CNTR
   register—at the end of each pass of the loop.

   " The        register retains the original loop counter value until you
               CNTR
     load it with a new value, either explicitly with a load instruction or
          with a POP LOOP instruction.

          To test the current value of the decrementing loop counter, you pop
          the value off the loop counter stack into the CNTR register, move the
          CNTR contents into a data register, and then push the CNTR contents
          back onto the stack.
   During execution of an infinite loop, the DSP pushes the current value of
   the CNTR register and the FOREVER bit onto the loop counter stack. When
   the FOREVER bit is set, the loop logic ignores the loop counter value. If you
   set up an infinite loop with the PUSH LOOP instruction instead of the DO
   UNTIL instruction, you must set the FOREVER bit of LPSTACKP (bit 15). (For
   details, see “Loop Stacks Operation” on page 8-10 and “PUSH or POP
   Stacks” on page 8-55.)
   You can nest up to eight loops because each of the loop stacks have eight
   locations. The DSP pushes the loop begin stack, loop end stack, and loop
   counter stack for each level of nesting.
   Follow these guidelines when coding loops:
       • For nested loops, set up a separate counter for each loop, and end
         each loop with a separate instruction.
       • Do not use the RTI or RTS instruction inside a loop.
       • Do not use a PUSH or POP instruction in the last seven lines of a loop.
         Avoid using PUSH or POP instructions within loops.




8-24     ADSP-219x Instruction Set Reference
                                                 DO UNTIL (PC relative)




     • Do not use a CALL instruction in the last line of a loop because the
       return address then resides outside of the loop, a condition that
       causes incorrect sequencing.
     • You can use a JUMP instruction in the last line of an infinite loop.
     • If you use a JUMP or CALL instruction to abort a loop, make sure you
       handle the loop stacks properly (POP LOOP). POP LOOP automatically
       pops each of the loop stacks. For details, see “Stacks” on page 8-7
       and “PUSH or POP Stacks” on page 8-55.
EXAMPLES

     /* a finite loop example */
     CNTR = 0xF;
     IOPG = 0x1;
     SI = AX0;
     DM(I0 += M0) = SI;
     MR=0, MX0 = DM(I0+=M0), MY0 = PM(I4+=M4);
     DO a_finite_loop UNTIL CE;
        MR = MR+MX0*MY0(SS), MX0 = DM(I0+=M0), MY0=PM(I4+=M4);
        MR = MR+MX0*MY0(RND);
     a_finite_loop:
        IO(0xFF) = MR1;

     /* an infinite loop example */
     IOPG = 0x1;
     I0 = 0x1000;
     M0 = 1;
     L0 = 0;
     DO an_infinite_loop;
       AX0 = DM(I0+=M0);
       AR = AX0 + AY0;
       IF AV JUMP exit_an_infinite_loop;
     an_infinite_loop:
       DM(I0 + 100) = AR;
     NOP;              /* 1st instruction after an infinite loop */
     NOP;
     NOP;              /* any number of instructions */
     NOP;
     exit_an_infinite_loop:
       POP LOOP;




                           ADSP-219x Instruction Set Reference         8-25
Program Flow Instructions




           JUMP an_infinite_loop +1;

       /* a nested loop example */
       AX0 = DM(I0 += M0), AY0 = PM(I4 += M4);
       CNTR = 10;
       DO outer_nested_loop UNTIL CE;
         CNTR = 20;
         DO middle_nested_loop UNTIL CE;
           CNTR = 30;
           DO inner_nested_loop UNTIL CE;
              AR =AX0 + AY0, AX0=DM(I0 += M0), AY0=PM(I4 += M4);
           inner_nested_loop:
              DM(I2 += M2) = AR;
         middle_nested_loop:
           NOP;
       outer_nested_loop:
         NOP;

SEE ALSO

       • “Type 11: Do ··· Until” on page 9-34
       • “Conditions” on page 8-2
       • “Counter-Based Conditions” on page 8-3
       • “Stacks” on page 8-7




8-26       ADSP-219x Instruction Set Reference
                                                Direct JUMP (PC relative)




Direct JUMP (PC relative)

    [IF COND] JUMP <Imm13> [(DB)] ;


FUNCTION

   This branch instruction causes program execution to continue at the offset
   address specified in the instruction. The offset address is the sum of the PC
   of the JUMP instruction and the 13-bit immediate value supplied in the
   instruction (PC + <imm13>).
   If execution is based on an optional condition, the JUMP instruction exe-
   cutes only if the condition evaluates true and a NOP operation executes if
   the condition evaluates false. Omitting the condition forces unconditional
   execution of the loop. For a list of valid conditions, see “Conditions” on
   page 8-2.
   The branch can be immediate or delayed (using the optional ((DB)). If
   immediate, the branch instruction executes immediately, but the instruc-
   tion at the offset address (branch target) executes after a latency of four
   NOP cycles.

   If using the optional delayed branch ((DB)) syntax, the branch instruction
   executes immediately, but the instruction at the offset address (branch tar-
   get) executes after a latency equal to four cycles. The two instructions
   directly following the JUMP instruction execute in sequence during the first
   two latency cycles if the branch is taken. Even if the branch is not taken,
   the instructions occupying the two branch delay slots still execute.
INPUT

   Imm13   A 13-bit, twos-complement offset value added to the address (PC)
           of the JUMP instruction. Valid values range from −4096 to + 4095.

           For good programming practice, always use a label, rather than a
           numeric value, since a label is relocatable.




                              ADSP-219x Instruction Set Reference         8-27
Program Flow Instructions




OUTPUT

   None.
STATUS FLAGS

   None.
DETAILS

   When using the (DB) option, you cannot insert the following instructions
   after the JUMP instruction, in the two delayed branch slots:
       • Stack manipulation instructions—PUSH/POP
       • Branch instructions—JUMP, CALL, RTI, RTS
       • Loop instruction—DO UNTIL
   You can use the Indirect 16-bit Memory Write—Immediate Data instruc-
   tion. For details, see “Indirect 16-bit Memory Write—immediate data” on
   page 7-55. Because it is a double-word instruction, you must place it in
   the first delay branch slot, right after the CALL instruction.
   The number of cycles required to perform a JUMP operation depends on
   whether the branch is taken or not. With the immediate branch option,
   when the branch is taken, the DSP flushes the instruction pipeline except
   for the JUMP instruction and inserts four NOP cycles. As shown in Table 8-1
   on page 8-29, when you use the (DB) option, the operation still takes five
   cycles (JUMP instruction + four cycles of latency), but the DSP executes in
   sequence the two instructions following the JUMP instruction, flushing
   only the top of the instruction pipeline.
   If the address range of this instruction is inadequate, you can use the
   LJUMP instruction, but lose use of the (DB) option, or you can retain the
   (DB) option and let the tools determine during assembly/linking whether
   to use this instruction or substitute the LJUMP instruction. For details see
   “Using Long Jumps and Calls” on page 8-20.




8-28       ADSP-219x Instruction Set Reference
                                                   Direct JUMP (PC relative)




   Table 8-1. Branch (JUMP) Execution Cycles

Branch Case        Time to Execute      Delayed Branch Fills   Delayed Branch NOPs

Taken               5 cycles            2 cycles               2 cycles

Not Taken           1 cycle             0 cycles               0 cycles


EXAMPLES

          JUMP first_branch_target; /* immediate branch jump */
          NOP;                     /* any number of instructions */
        first_branch_target:
          NOP;                     /* any number of instructions */
          NOP;
          Jump second_branch_target (DB); /* delayed branch jump */
          AR = PASS 0;
          AR = AX0 + AY0; /* these two instr. after jump execute */
          NOP;
          NOP;                     /* any number of instructions */
        second_branch_target:
          NOP;
          NOP;                     /* any number of instructions */
          IF NE JUMP third_branch_target (DB);
            MR = 0;     /* these two instr. after (DB) jump execute */
            AR = PASS 0; /* whether or not cond branch is taken */
          NOP;
          NOP;                    /* any number of instructions */
        third_branch_target:
          NOP;
          NOP;                     /* any number of instructions */

SEE ALSO

        • “Type 10: Direct Jump” on page 9-32
        • “Branch Options” on page 8-5
        • “Addressing Branch Targets” on page 8-6




                               ADSP-219x Instruction Set Reference            8-29
Program Flow Instructions




CALL (PC relative)

    CALL <Imm16> [(DB)] ;


FUNCTION

   This instruction causes the Program Sequencer to branch to the offset
   address specified in the instruction and execute the subroutine at that
   location. The offset address is the sum of the PC of the CALL instruction
   and the 16-bit immediate value supplied in the instruction (PC + <imm16>).
   The branch can be immediate or delayed (using the optional ((DB)). If
   immediate, the branch instruction executes immediately, but the instruc-
   tion at the offset address (branch target) executes after a latency of four
   NOP cycles.

   If using the optional delayed branch ((DB)) syntax, the branch instruction
   executes immediately, but the instruction at the offset address (branch tar-
   get) executes after a latency equal to four cycles. The two instructions
   directly following the CALL instruction execute in sequence during the first
   two latency cycles of the branch.
INPUT

   imm16   16-bit, twos-complement offset value added to the address (PC) of
           the CALL instruction or a declared label. Valid values range from
           −32768 to +32767.

           For good programming practice, always use a label, rather than a
           numeric value, since a label is relocatable.
OUTPUT

   None.




8-30       ADSP-219x Instruction Set Reference
                                                                       CALL (PC relative)




STATUS FLAGS


Affected Flags–set or cleared by the operation    Unaffected Flags

PCSTKFULL, PCSTKLVL, STKOVERFLOW,                  LPSTKEMPTY, LPSTKFULL, STSSTKEMPTY
PCSTKEMPTY

For information on these status bits in the SSTAT register, see Table 2-7 on page 2-14.


DETAILS

    Before branching, the Program Sequencer automatically pushes onto the
    PC stack the return address of the next instruction to execute after return-
    ing from the called subroutine. The next instruction to execute is:
        • Immediate CALL                   The first instruction following the CALL
                                           instruction.
        • Delayed CALL                    The third instruction following the CALL
                                          instruction.
    To return from the subroutine, you must explicitly issue an RTS instruc-
    tion. For details, see “Return from Subroutine” on page 8-52.
    When using the (DB) option, you cannot insert the following instructions
    after the CALL instruction, in the two delay branch slots:
        • Stack manipulation instructions—PUSH/POP
        • Branch instructions—JUMP, CALL, RTI, RTS
        • Loop instruction—DO UNTIL
    You can use the Indirect 16-bit Memory Write—Immediate Data instruc-
    tion. For details, see “Indirect 16-bit Memory Write—immediate data” on
    page 7-55. Because it is a double-word instruction, you must place it in
    the first delay branch slot, right after the CALL instruction.




                                      ADSP-219x Instruction Set Reference                 8-31
Program Flow Instructions




   The number of cycles required to perform a CALL operation depends on
   whether the branch is taken or not. With the immediate branch option,
   when the branch is taken, the DSP flushes the instruction pipeline except
   for the CALL instruction and inserts four NOP cycles. As shown in Table 8-2
   on page 8-32, when you use the (DB) option, the operation still takes five
   cycles (CALL instruction + four cycles of latency), but the DSP executes in
   sequence the two instructions following the CALL instruction, flushing
   only the top of the instruction pipeline.

   Table 8-2. Branch (CALL) Execution Cycles

Branch Case           Time to Execute   Delayed Branch Fills   Delayed Branch NOPs

 Taken                5 cycles          2 cycles               2 cycles

 Not Taken            1 cycle           0 cycles               0 cycles


   If the address range of this instruction is inadequate, you can use the
   LCALL instruction, but you lose use of the (DB) option, or you can retain
   the (DB) option and let the tools determine during assembly/linking
   whether to use this instruction or substitute the LCALL instruction. For
   details see “Using Long Jumps and Calls” on page 8-20 and “Long CALL”
   on page 8-37.
EXAMPLES

         CALL data_shift_subroutine (DB);
           AX0 = DM(I0 += M1), AY0 = PM(I4 += M5); /* these two instr. */
           AR = PASS 0;          /* execute before (DB) branch starts */
         DM(I1 += M1) = SR0;            /* RTS returns here */
         NOP;
         NOP;     /* any number of instructions */
         NOP;
         data_shift_subroutine:
           AR = AX0 + AY0;
           AX1 = 3; SE = AR;
           SR = ASHIFT SI (HI);
           RTS;                   /* returns operation */




8-32         ADSP-219x Instruction Set Reference
                                                  CALL (PC relative)




SEE ALSO

      • “Type 10: Direct Jump” on page 9-32
      • “Branch Options” on page 8-5
      • “Addressing Branch Targets” on page 8-6




                          ADSP-219x Instruction Set Reference   8-33
Program Flow Instructions




JUMP (PC relative)

    JUMP <Imm16> [(DB)] ;


FUNCTION

   This branch instruction causes program execution to continue at the offset
   address specified in the instruction. The offset address is the sum of the PC
   of the JUMP instruction and the 16-bit immediate value supplied in the
   instruction (PC + <imm16>).
   The branch can be immediate or delayed (using the optional ((DB)). If
   immediate, the branch instruction executes immediately, but the instruc-
   tion at the offset address (branch target) executes after a latency of four
   NOP cycles.

   If using the optional delayed branch ((DB)) syntax, the branch instruction
   executes immediately, but the instruction at the offset address (branch tar-
   get) executes after a latency equal to four cycles. The two instructions
   directly following the JUMP instruction execute in sequence during the first
   two latency cycles of the branch.
INPUT

   imm16   16-bit, twos-complement offset value added to the address (PC) of
           the JUMP instruction or a declared label. Valid values range from
           −32768 to +32767.

           For good programming practice, always use a label, rather than a
           numeric value, since a label is relocatable.
OUTPUT

   None.




8-34       ADSP-219x Instruction Set Reference
                                                       JUMP (PC relative)




STATUS FLAGS

   None.
DETAILS

   When using the (DB) option, you cannot insert the following instructions
   in the two delay branch slots directly after the JUMP instruction:
      • Stack manipulation instructions—PUSH/POP
      • Branch instructions—JUMP, CALL, RTI, RTS
      • Loop instruction—DO UNTIL
   You can use the Indirect 16-bit Memory Write—Immediate Data instruc-
   tion. For details, see “Indirect 16-bit Memory Write—immediate data” on
   page 7-55. Because it is a double-word instruction, you must place it in
   the first delay branch slot, right after the CALL instruction.
   The number of cycles required to perform a JUMP operation depends on
   whether the branch is taken or not. With the immediate branch option,
   when the branch is taken, the DSP flushes the instruction pipeline except
   for the JUMP instruction and inserts four NOP cycles. As shown in Table 8-1
   on page 8-29, when you use the (DB) option, the operation still takes five
   cycles (JUMP instruction + four cycles of latency), but the DSP executes in
   sequence the two instructions following the JUMP instruction, flushing
   only the top of the instruction pipeline.
   If the address range of this instruction is inadequate, you can use the
   LJUMP instruction, but you lose use of the (DB) option, or you can retain
   the (DB) option and let the tools determine during assembly/linking
   whether to use this instruction or substitute the LJUMP instruction. For
   details see “Using Long Jumps and Calls” on page 8-20 and “Long JUMP”
   on page 8-40.




                             ADSP-219x Instruction Set Reference         8-35
Program Flow Instructions




EXAMPLES

       .SECTION/PM seg_code;
         JUMP my_cod2_label; /* jumps to 16-bit relative address */
         NOP;
         NOP;                 /* any number of instructions */
         NOP;
       my_code_exit_label:
         NOP;                /* jump from seg_cod2 comes here */
         NOP;
         NOP;                 /* any number of instructions */
         NOP;
       .SECTION/PM seg_cod2;
       my_cod2_label:
         NOP;
         NOP;                 /* any number of instructions */
         NOP;
         JUMP my_code_exit_label;

SEE ALSO

       • “Type 10: Direct Jump” on page 9-32
       • “Branch Options” on page 8-5
       • “Addressing Branch Targets” on page 8-6




8-36       ADSP-219x Instruction Set Reference
                                                                 Long CALL




Long CALL

    [IF COND] LCALL <Imm24> ;


FUNCTION

   This instruction causes the Program Sequencer to branch to the absolute
   address specified in the instruction and execute the subroutine at that
   location. The absolute address is the 24-bit immediate value supplied in
   the instruction. The 24-bit immediate value enables programs to access
   any location in program memory address space.
   If execution is based on a condition, the JUMP instruction executes only if
   the condition evaluates true and a NOP operation executes if the condition
   evaluates false. Omitting the condition forces unconditional execution of
   the loop. For a list of valid conditions, see “Conditions” on page 8-2.
INPUT

   Imm24   24-bit, twos-complement value or a declared label. Values range
           from −16777216 to +16777215.

           For good programming practice, always use a label, rather than a
           numeric value, since a label is relocatable.
OUTPUT

   None.




                             ADSP-219x Instruction Set Reference         8-37
Program Flow Instructions




STATUS FLAGS


Affected Flags–set or cleared by the operation    Unaffected Flags

PCSTKFULL, PCSTKLVL, STKOVERFLOW,                  LPSTKEMPTY, LPSTKFULL, STSSTKEMPTY
PCSTKEMPTY

For information on these status bits in the SSTAT register, see Table 2-7 on page 2-14.


DETAILS

    For details on using the assembler’s and linker’s -jcs21 option to direct
    the tools to determine when to replace PC relative CALL instructions with
    this instruction, see “Using Long Jumps and Calls” on page 8-20.
    This is a double-word instruction, so it executes in six (2 instruction + 4
    latency) cycles.
    Before branching, the Program Sequencer automatically pushes onto the
    PC stack the return address of the next instruction to execute after return-
    ing from the called subroutine. The next instruction to execute is the first
    instruction following the LCALL instruction.
    To return from the subroutine, you must explicitly issue an RTS instruc-
    tion. For details, see “Return from Subroutine” on page 8-52.
EXAMPLES

        .SECTION/PM seg_code;
        IF EQ LCALL my_faraway_routine;
          NOP;                /* execution returns here */
          NOP;
          NOP;                /* any number of instructions */
          NOP;

        .SECTION/PM seg_cod2;
        my_faraway_routine:
          NOP;
          NOP;                /* any number of instructions */




8-38        ADSP-219x Instruction Set Reference
                                                          Long CALL




           NOP;
           RTS;

SEE ALSO

      • “Type 36: Long Jump/Call” on page 9-59
      • “Branch Options” on page 8-5
      • “Addressing Branch Targets” on page 8-6
      • “Using Long Jumps and Calls” on page 8-20.




                          ADSP-219x Instruction Set Reference   8-39
Program Flow Instructions




Long JUMP

    [IF COND] LJUMP <Imm24> ;


FUNCTION

   This branch instruction causes program execution to continue at the abso-
   lute address specified in the instruction. The absolute address is the 24-bit
   immediate value supplied in the instruction. The 24-bit immediate value
   enables programs to access any location in program memory address space.
   If execution is based on a condition, the JUMP instruction executes only if
   the condition evaluates true and a NOP operation executes if the condition
   evaluates false. Omitting the condition forces unconditional execution of
   the loop. For a list of valid conditions, see “Conditions” on page 8-2.

   " This instruction is a two-word instruction and requires (at mini-
     mum) six cycles to execute. For more information, see “Type 36:
           Long Jump/Call” on page 9-59.
INPUT

   Imm24   24-bit, twos-complement value or a declared variable. Values range
           from −16777216 to +16777215.

           For good programming practice, always use a label, rather than a
           numeric value, since a label is relocatable.
OUTPUT

   None.
STATUS FLAGS

   None.




8-40       ADSP-219x Instruction Set Reference
                                                               Long JUMP




DETAILS

   For details on using the ADSP-219x assembler’s -jcs2l (convert
   Jump/Call Short to Long) option to direct the tools to determine when to
   replace PC relative JUMP instructions with LJUMP instructions, see “Using
   Long Jumps and Calls” on page 8-20.
EXAMPLES

      /* Long JUMP example nearby half */

      .SECTION/PM seg_code;
      .GLOBAL my_local_exit_label;
      .EXTERN my_faraway_label;
         LJUMP my_faraway_label; /* jumps to 24-bit relative addr */
         NOP;
         NOP;                /* any number of instructions */
         NOP;
       my_local_exit_label:
         NOP;               /* jump from seg_cod2 comes here */
         NOP;
         NOP;                /* any number of instructions */

      /* Long JUMP example faraway half */

      .SECTION/PM seg_xpmc;
      .GLOBAL my_faraway_label;
      .EXTERN my_local_exit_label;
      my_faraway_label:
        NOP;                /* any number of instructions */
        NOP;
        LJUMP my_local_exit_label;

SEE ALSO

      • “Type 36: Long Jump/Call” on page 9-59
      • “Branch Options” on page 8-5
      • “Addressing Branch Targets” on page 8-6
      • “Using Long Jumps and Calls” on page 8-20.



                            ADSP-219x Instruction Set Reference        8-41
Program Flow Instructions




Indirect CALL

    [IF COND] CALL (<Ireg>) [(DB)] ;


FUNCTION

   This instruction causes the Program Sequencer to branch to the address
   pointed to by the DAG index register ( Ireg). The Ireg supplies the six-
   teen LSBs of the 24-bit address, and the IJPG register supplies the eight
   MSBs (page address) of the 24-bit address. You must explicitly load the
   IJPG register with the eight MSBs of the address before executing this
   instruction (for details, see “Data Move Instructions” on page 7-1).
   If execution is based on a condition, the CALL instruction executes only if
   the condition evaluates true, and a NOP operation executes if the condition
   evaluates false. Omitting the condition forces unconditional execution of
   the loop. For a list of valid conditions, see “Conditions” on page 8-2.
   The branch can be immediate or delayed (using the optional ((DB)). If
   immediate, the branch instruction executes immediately, but the instruc-
   tion at the offset address (branch target) executes after a latency of four
   NOP cycles.

   If using the optional delayed branch ((DB)) syntax, the branch instruction
   executes immediately, but the instruction at the offset address (branch tar-
   get) executes after a latency equal to four cycles. The two instructions
   directly following the CALL instruction execute in sequence during the first
   two latency cycles if the branch is taken. Even if the branch is not taken,
   the instructions occupying the two branch delay slots still execute.
INPUT

   Ireg    I0–I3 (DAG1 index registers) or I4–I7 (DAG2 index registers)

OUTPUT

   None.



8-42       ADSP-219x Instruction Set Reference
                                                                               Indirect CALL




STATUS FLAGS


Affected Flags–set or cleared by the operation    Unaffected Flags

PCSTKFULL, PCSTKLVL, STKOVERFLOW,                  LPSTKEMPTY, LPSTKFULL, STSSTKEMPTY
PCSTKEMPTY

For information on these status bits in the SSTAT register, see Table 2-7 on page 2-14.


DETAILS

    Before branching, the Program Sequencer automatically pushes onto the
    PC stack the return address of the next instruction to execute after return-
    ing from the called subroutine. The next instruction to execute is:
        • Immediate CALL                   The first instruction following the CALL
                                           instruction.
        • Delayed CALL                    The third instruction following the CALL
                                          instruction.

    " Toinstruction.
            return from the subroutine, you must explicitly issue an
                     For details, see “Return from Subroutine” on
                                                                                          RTS


             page 8-52.
    When using the (DB) option, you cannot insert the following instructions
    after the CALL instruction, in the two delay branch slots:
        • Stack manipulation instructions—PUSH/POP
        • Branch instructions—JUMP, CALL, RTI, RTS
        • Loop instruction—DO UNTIL
    You can use the Indirect 16-bit Memory Write—Immediate Data instruc-
    tion (for details, see page 7-55), but because it is a double-word
    instruction, you must place it in the first delay branch slot, right after the
    CALL instruction.




                                      ADSP-219x Instruction Set Reference                  8-43
Program Flow Instructions




   The number of cycles required to perform a CALL operation depends on
   whether the branch is taken or not. With the immediate branch option,
   when the branch is taken, the DSP flushes the instruction pipeline except
   for the CALL instruction and inserts four NOP cycles. As shown in Table 8-2
   on page 8-32, when you use the (DB) option, the operation still takes five
   cycles (CALL instruction + four cycles of latency), but the DSP executes in
   sequence the two instructions following the CALL instruction, flushing
   only the top of the instruction pipeline.
EXAMPLES

       I5 = sampling_routine;
       AR = AR + AX0;
       IF EQ CALL (I5) (DB);
         DM(I0 += M1) = AR;   /* these two instr. execute */
         AR = 0;    /* whether or not the branch is taken */
       AR = PASS 0; /* RTS returns execution to this instr. */
       NOP;
       NOP;         /* any number of instructions */
       NOP;

       sampling_routine:
         MX0 = DM(I0+=M1);
         MR = MX0 * MY0 (SS);
         NOP;
         NOP;       /* any number of instructions */
         NOP;
         RTS;

SEE ALSO

       • “Type 19: Indirect Jump/Call” on page 9-41
       • “Branch Options” on page 8-5
       • “Addressing Branch Targets” on page 8-6




8-44       ADSP-219x Instruction Set Reference
                                                             Indirect JUMP




Indirect JUMP

    [IF COND] JUMP (<Ireg>) [(DB)] ;


FUNCTION

   This branch instruction causes program execution to continue at the
   address pointed to by the DAG index register (Ireg). The Ireg supplies
   the sixteen LSBs of the 24-bit address, and the IJPG register supplies the
   eight MSBs (page address) of the 24-bit address. You must explicitly load
   the IJPG register with the eight MSBs of the address before executing this
   instruction (for details, see “Data Move Instructions” on page 7-1).
   If execution is based on a condition, the JUMP instruction executes only if
   the condition evaluates true, and a NOP operation executes if the condition
   evaluates false. Omitting the condition forces unconditional execution of
   the loop. For a list of valid conditions, see “Conditions” on page 8-2.
   The branch can be immediate or delayed (using the optional ((DB)). If
   immediate, the branch instruction executes immediately, but the instruc-
   tion at the offset address (branch target) executes after a latency of four
   NOP cycles.

   If using the optional delayed branch ((DB)) syntax, the branch instruction
   executes immediately, but the instruction at the offset address (branch tar-
   get) executes after a latency equal to four cycles. The two instructions
   directly following the JUMP instruction execute in sequence during the first
   two latency cycles if the branch is taken. Even if the branch is not taken,
   the instructions occupying the two branch delay slots still execute.
INPUT

   Ireg    I0–I3 (DAG1 index registers) or I4–I7 (DAG2 index registers)

OUTPUT

   None.



                             ADSP-219x Instruction Set Reference          8-45
Program Flow Instructions




STATUS FLAGS

   None.
DETAILS

   Loading the IJPG register or an Ireg has a zero (0) effect latency for this
   instruction, so the new value is available on the next instruction cycle.
   When using the (DB) option, you cannot insert the following instructions
   after the JUMP instruction, in the two delay branch slots:
       • Stack manipulation instructions—PUSH/POP
       • Branch instructions—JUMP, CALL, RTI, RTS
       • Loop instruction—DO UNTIL
   You can use the Indirect 16-bit Memory Write—Immediate Data instruc-
   tion. For details, see “Indirect 16-bit Memory Write—immediate data” on
   page 7-55. Because it is a double-word instruction, you must place it in
   the first delay branch slot, right after the JUMP instruction.
   The number of cycles required to perform a JUMP operation depends on
   whether the branch is taken or not. With the immediate branch option,
   when the branch is taken, the DSP flushes the instruction pipeline except
   for the JUMP instruction and inserts four NOP cycles. As shown in Table 8-1
   on page 8-29, when you use the (DB) option, the operation still takes five
   cycles (JUMP instruction + four cycles of latency), but the DSP executes in
   sequence the two instructions following the JUMP instruction, flushing
   only the top of the instruction pipeline.
EXAMPLES

       I4 = sampling;
       I5 = next_sample;

       sampling:
       AR = AR + AX0;
       IF EQ JUMP (I5) (DB);




8-46       ADSP-219x Instruction Set Reference
                                                        Indirect JUMP




           DM(I0 += M1) = AR;    /* these two instr. execute */
           AR = 0;     /* whether or not the branch is taken */
           JUMP (I4) (DB);
             AX0 = DM(I0 += M1); /* these two instr. execute */
             AR = AX0;           /* before the branch starts */

      next_sample:
        MX0 = DM(I0 += M1);
        MR = MX0 * MY0 (SS);
        NOP;
        NOP;       /* any number of instructions */
        NOP;
        JUMP (I4); /* goes back to sampling */

SEE ALSO

      • “Type 19: Indirect Jump/Call” on page 9-41
      • “Branch Options” on page 8-5
      • “Addressing Branch Targets” on page 8-6




                            ADSP-219x Instruction Set Reference   8-47
Program Flow Instructions




Return from Interrupt

    [IF COND] RTI [(DB)] [(SS)] ;


FUNCTION

   This instruction executes a return from an interrupt service routine (ISR).
   It returns program execution to the address of either the first or third
   instruction following the branch instruction that launched the ISR.
   If execution is based on a condition, the RTI instruction executes only if
   the condition evaluates true, and a NOP operation executes if the condition
   evaluates false. Omitting the condition forces unconditional execution of
   the loop. For a list of valid conditions, see “Conditions” on page 8-2.
   The branch can be immediate or delayed (using the optional ((DB)). If
   immediate, the branch instruction executes immediately, but the instruc-
   tion at the offset address (branch target) executes after a latency of four
   NOP cycles.

   If using the optional delayed branch ((DB)) syntax, the branch instruction
   executes immediately, but the instruction at the offset address (branch tar-
   get) executes after a latency equal to four cycles. The two instructions
   directly following the RTI instruction execute in sequence during the first
   two latency cycles if the branch is taken. Even if the branch is not taken,
   the instructions occupying the two branch delay slots still execute.
   For emulation, the RTI instruction supports an additional option, the sin-
   gle-step (SS) return interrupt. This option causes the instruction at the
   return address to generate an interrupt when it executes during emulation.
INPUT

   None.




8-48       ADSP-219x Instruction Set Reference
                                                                     Return from Interrupt




OUTPUT

    None.
STATUS FLAGS


Affected Flags–set or cleared by the operation    Unaffected Flags

 PCSTKFULL, PCSTKEMPTY, PCSTKLVL                   LPSTKEMPTY, LPSTKFULL, STKOVER-
                                                   FLOW, STSSTKEMPTY

For information on these status bits in the SSTAT register, see Table 2-7 on page 2-14.


DETAILS

    This instruction pops and uses the address at top of the PC stack for the
    return address. It also pops the value at the top of the status stack and
    loads it into the arithmetic status register (ASTAT) and the mode status reg-
    ister (MSTAT). So if the ISR enabled secondary registers or changed other
    DSP modes in MSTAT, the RTI instruction automatically disables them
    when it executes.

    " Do  not use an    instruction inside a loop without explicitly per-
      forming stack maintenance.
                                RTI



    When using the (DB) option, you cannot insert the following instructions
    after the RTI instruction, in the two delay branch slots:
        • Stack manipulation instructions—PUSH/POP
        • Branch instructions—JUMP, CALL, RTI, RTS
        • Loop instruction—DO UNTIL
    You can use the Indirect 16-bit Memory Write—Immediate Data instruc-
    tion. For details, see “Indirect 16-bit Memory Write—immediate data” on
    page 7-55. Because it is a double-word instruction, you must place it in
    the first delay branch slot, directly following the RTI instruction.



                                      ADSP-219x Instruction Set Reference                 8-49
Program Flow Instructions




   The number of cycles required to perform an RTI depends on whether the
   branch is taken or not. With the immediate branch option, when the
   branch is taken, the DSP flushes the instruction pipeline except for the
   RTI instruction and inserts four NOP cycles. As shown in Table 8-3, when
   you use the (DB) option, the operation still takes five cycles (RTI instruc-
   tion + four cycles of latency), but the DSP executes in sequence the two
   instructions following the RTI instruction, flushing only the top of the
   instruction pipeline.

   Table 8-3. Branch (RTI) Execution Cycles

Branch Case             Time to Execute    Delayed Branch Fills   Delayed Branch NOPs

 Taken                  5 cycles           2 cycles               2 cycles

 Not Taken              2 cycle            0 cycles               1 cycle


EXAMPLES

         interrupt_setup:
           /* defined addr of inter. priority registers in IO() memory */
           #define IPR0 0x203
           #define IPR1 0x204
           #define IPR2 0x205
           #define IPR3 0x206
           /* loads interrupt priorities into IPR registers */
           AX0 = 0x3210;
           IO(IPR0) = AX0; /* set priorities for peripherals 3-0 */
           AX0 = 0x7654;
           IO(IPR1) = AX0; /* set priorities for peripherals 7-4 */
           AX0 = 0xBA98;
           IO(IPR2) = AX0; /* set priorities for peripherals 11-8 */
           AX0 = 0x0BBB;
           IO(IPR3) = AX0; /* set priorities for peripherals 14-12 */

             ICNTL = 0x0010;        /* set GIE global interrupt enable bit */
             IMASK = 0x4000;        /* unmask interrupt ID 14, which is
                                     assigned to Timer Interrupt A by IPR2 */
             ENA INT;               /* enable interrupts */




8-50         ADSP-219x Instruction Set Reference
                                               Return from Interrupt




      wait_here_for_interrupt: /* loop waiting for interrupt */
        NOP;
        NOP;             /* any number of instructions */
        NOP;
        JUMP wait_here_for_interrupt;

      .SECTION/PM irq_14; /* map this ISR to addr. 0x01C0 with LDF */
      timer_a_int:
        ENA SEC_REG, ENA SEC_DAG;
        NOP;
        NOP;             /* up to 32 instructions */
        NOP;
        RTI;

SEE ALSO

      • “Type 20: Return” on page 9-42
      • “Interrupts” on page 8-13
      • “Set Interrupt” on page 8-62
      • “Clear Interrupt” on page 8-64.




                          ADSP-219x Instruction Set Reference     8-51
Program Flow Instructions




Return from Subroutine

    [IF COND] RTS [(DB)] ;


FUNCTION

   This instruction executes a return from a subroutine. It returns program
   execution to the address of either the first or third instruction following
   the branch instruction that called the subroutine.
   If execution is based on a condition, the RTS instruction executes only if
   the condition evaluates true, and a NOP operation executes if the condition
   evaluates false. Omitting the condition forces unconditional execution of
   the branch. For a list of valid conditions, see “Conditions” on page 8-2.
   The branch can be immediate or delayed (using the optional ((DB)). If
   immediate, the branch instruction executes immediately, but the instruc-
   tion at the offset address (branch target) executes after a latency of four
   NOP cycles.

   If using the optional delayed branch ((DB)) syntax, the branch instruction
   executes immediately, but the instruction at the offset address (branch tar-
   get) executes after a latency equal to four cycles. The two instructions
   directly following the RTS instruction execute in sequence during the first
   two latency cycles if the branch is taken. Even if the branch is not taken,
   the instructions occupying the two branch delay slots still execute.

   " Do  not use an    instruction inside a loop without explicitly per-
                         RTS
     forming stack maintenance. For details, see begin stack.
INPUT

   None.
OUTPUT

   None.




8-52       ADSP-219x Instruction Set Reference
                                                                Return from Subroutine




STATUS FLAGS


Affected Flags–set or cleared by the operation    Unaffected Flags

 PCSTKFULL, PCSTKEMPTY, PCSTKLVL                   LPSTKEMPTY, LPSTKFULL, STKOVER-
                                                   FLOW, STSSTKEMPTY

For information on these status bits in the SSTAT register, see Table 2-7 on page 2-14.


DETAILS

    This instruction pops and uses the address at top of the PC stack for the
    return address.
    When using the (DB) option, you cannot insert the following instructions
    after the RTS instruction, in the two delay branch slots:
        • Stack manipulation instructions—PUSH/POP
        • Branch instructions—JUMP, CALL, RTI, RTS
        • Loop instruction—DO UNTIL
    You can use the Indirect 16-bit Memory Write—Immediate Data instruc-
    tion (for details, see page 7-55), but because it is a double-word
    instruction, you must place it in the first delay branch slot, right after the
    RTI instruction.

    The number of cycles required to perform an RTS depends on whether the
    branch is taken or not. With the immediate branch option, when the
    branch is taken, the DSP flushes the instruction pipeline except for the
    RTS instruction and inserts four NOP cycles. As shown in Table 8-4 on
    page 8-54, when you use the (DB) option, the operation still takes five
    cycles (RTS instruction + four cycles of latency), but the DSP executes in




                                      ADSP-219x Instruction Set Reference                 8-53
Program Flow Instructions




   sequence the two instructions following the RTS instruction, flushing only
   the top of the instruction pipeline.

   Table 8-4. Branch (RTS) Execution Cycles

Branch Case           Time to Execute   Delayed Branch Fills   Delayed Branch NOPs

 Taken                5 cycles          2 cycles               2 cycles

 Not Taken            1 cycle           0 cycles               0 cycle


EXAMPLES

         I5 = sample_routine;
         AR = AR + AX0;
         IF EQ CALL (I5) (DB);
           DM(I0 += M1) = AR;   /* these two instr. execute */
           AR = 0;    /* whether or not the branch is taken */
         AR = PASS 0; /* RTS returns execution to this instr. */
         NOP;
         NOP;         /* any number of instructions */
         NOP;

         sample_routine:
           MX0 = DM(I0+=M1);
           MR = MX0 * MY0 (SS);
           NOP;
           NOP;       /* any number of instructions */
           NOP;
           RTS;

SEE ALSO

         • “Type 20: Return” on page 9-42
         • “Branch Options” on page 8-5
         • “Addressing Branch Targets” on page 8-6




8-54         ADSP-219x Instruction Set Reference
                                                       PUSH or POP Stacks




PUSH or POP Stacks

     PUSH              PC         ;
      POP             LOOP
                      STS


FUNCTION

  This instruction PUSHes (stores) or POPs (retrieves) a value from the top of
  the specified stack: PC, LOOP, or STS.
     •     PC

           On a PUSH, stores onto the top of the PC stack a 24-bit address value
           assembled from the STACKA and STACKP registers. STACKA provides
           the sixteen LSBs of the address, and STACKP provides the eight MSBs
           of the address.
           On a POP, retrieves the most recently stacked 24-bit address value
           from the top of the PC stack into the STACKA and STACKP registers.
           STACKA receives the sixteen LSBs of the address, and STACKP receives
           the eight MSBs of the address.
     •     LOOP

           On a PUSH, stores onto the top of the loop begin stack the 24-bit
           loop start address assembled from the STACKA and STACKP registers,
           pushes onto the top of the loop end stack the 24-bit loop end
           address assembled from the LPSTACKA and LPSTACKP registers, and
           pushes onto the top of the loop counter stack the current loop
           counter value from the CNTR register.
           On a POP, retrieves the most recently stacked 24-bit loop start
           address from the top of the loop begin stack into the STACKA and
           STACKP registers, pops the most recently stacked 24-bit loop end
           address from the top of the loop end stack into the LPSTACKA and




                              ADSP-219x Instruction Set Reference          8-55
Program Flow Instructions




             LPSTACKP registers, and pops the current loop counter value from
             the top of the loop counter stack into the CNTR register.
        •    STS

             On a PUSH, stores the current values of the ASTAT and MSTAT registers
             onto the status stack. After each push, the status stack pointer incre-
             ments by one to access the next available location in the stack.
             On a POP, retrieves the most recently stacked 16-bit value of the
             ASTAT and MSTAT registers from the top of the status stack. After each
             individual pop, the status stack pointer decrements by one to access
             the next lowest location (next register value) in the stack.

    " Abut a or or
                PUSH
                    PUSH
                          POP PC has one cycle of latency for all SSTAT register bits,
                               POP LOOP or STS has one cycle of latency only for the
             STKOVERFLOW bit in the SSTAT register.

INPUT

    None.
OUTPUT

    None.
STATUS FLAGS


Affected Flags–set or cleared by the operation    Unaffected Flags

PCSTKEMPTY (affected on POP), PCSTK-               (none)
FULL, PCSTKLVL (affected on POP),
LPSTKEMPTY, LPSTKFULL, STSSTKEMPTY
(affected on POP), STKOVERFLOW

For information on these status bits in the SSTAT register, see Table 2-7 on page 2-14.




8-56        ADSP-219x Instruction Set Reference
                                                       PUSH or POP Stacks




DETAILS ( PUSH )

   You can push up to two stacks in parallel by issuing two PUSH instructions
   on the same instruction line, pushing either:
        PUSH PC, PUSH STS;

   or
        PUSH LOOP, PUSH STS;


   " Do not). push the PC and LOOP stacks in parallel (
           LOOP;
                                                               PUSH PC, PUSH



            If you push the PC and loop stacks in parallel, you push the same
           address value onto both the PC stack and the loop begin stack. This
           occurs because STACKA and STACKP serve as the source registers for
           both stacks.
   Regardless of the number of stacks pushed, this instruction always exe-
   cutes in a single cycle.
   Subroutines, loops, and interrupts automatically push certain stacks:
        • Calls to subroutines and entry into interrupt service routines auto-
          matically push the PC stack.
        • Execution of the DO UNTIL instruction pushes the loop begin stack,
          the loop end stack, and the loop counter stack.
Do not use this instruction in either of the two slots directly following a
delayed branch instruction.

   " Do  not use this instruction inside a loop without explicitly perform-
     ing stack maintenance. For details, see “PUSH or POP Stacks” on
           page 8-55




                              ADSP-219x Instruction Set Reference             8-57
Program Flow Instructions




   " Ifmustyousetsetbitup15anofinfinite looptowith
                               LPSTACKP
                                                   thePUSH LOOP instruction, you
                                               indicate   FOREVER. Although the
           LPSTACKP register has sixteen bits, but only bit 15 and bits 7:0 are
           valid. When the FOREVER bit is set (bit 15 = 1), the loop logic ignores
           the loop counter value. When the FOREVER bit is cleared (bit 15 = 0),
           CE is the loop terminator condition, and the loop logic decrements
           the loop counter value.
DETAILS ( POP )

   You can pop up to two stacks in parallel by issuing two POP instructions
   on the same instruction line, popping either:
        POP PC, POP STS;

   or
        POP LOOP, POP STS;


   " Do not pop the PC and loop stacks in parallel (            POP PC, POP LOOP;).


           If you pop the PC and loop stacks in parallel, you lose the loop start
           address retrieved from the loop begin stack. This occurs because
           STACKA and STACKP serve as the destination registers for values
           popped from both the PC stack and the loop begin stack. In this
           case, STACKA and STACKP receive the most recently stacked PC value.
   Regardless of the number of stacks popped, this instruction always exe-
   cutes in a single cycle.
   Subroutines, loops, and interrupts automatically pop certain stacks:
        • Upon exiting, RTS and RTI instructions automatically pop the PC
          stack.
        • Loop termination automatically pops the loop begin stack, the loop
          end stack, and the loop counter stack




8-58      ADSP-219x Instruction Set Reference
                                                     PUSH or POP Stacks




   " Do  not use this instruction in either of the two slots directly follow-
     ing a delayed branch instruction.

   " Do  not use this instruction inside a loop without explicitly perform-
     ing stack maintenance. For details, see “PUSH or POP Stacks” on
          page 8-55.
EXAMPLES ( PUSH )

      /* Pushing an infinite loop—loop terminator condition =
      FOREVER: */

      STACKA = 0x0045;
      STACKP = 0x03;
      LPSTACKA = 0x004C;
      LPSTACKP = 0x03;
      PUSH LOOP;

      /* Saving the DSP’s current state: */

      STACKA = 0x0022;
      STACKP = 0x05;
      PUSH PC, PUSH STS;

EXAMPLES ( POP )

      /* Restoring the DSP’s current state: */

      POP PC, POP STS;
      AR = TSTBIT 6 OF AX0;
      IF EQ CALL primary;
      AX1 = STACKA;
      AY1 = STACKP;
      IJPG = AY1;
      primary: DIS SEC_DAG, DIS SEC_REG;
               RTS;

      /* Aborting a loop: */

      CNTR = 10;
      MX0 = DM(I2 += M2),
      MY0 = PM(I5 += M5);
      DO mac UNTIL CE;




                            ADSP-219x Instruction Set Reference         8-59
Program Flow Instructions




         MR = MR + MX0 * MY0 (SS),
         MX0 = DM(I2 += M2),
         MY0 = PM(I5 += M5);
         IF MV JUMP abort;
       mac:
         DM(I0 += M1) = MR0;
       NOP;
       NOP;   /* any number of instructions */
       NOP;
       abort:
         POP LOOP;
         JUMP mac + 1;

SEE ALSO

       • “Type 26:Push/Pop/Cache” on page 9-50
       • “MSTAT Mode Control Register” on page 8-4
       • “Stacks” on page 8-7
       • “PC and Status Stack Operation” on page 8-8
       • “Loop Stacks Operation” on page 8-10




8-60       ADSP-219x Instruction Set Reference
                                                                 FLUSH CACHE




FLUSH CACHE

    FLUSH CACHE ;


FUNCTION

   This instruction flushes the instruction cache, invalidating all instructions
   currently cached, so the next instruction fetch results in a memory access.
   Use this instruction when program memory changes to resynchronize the
   instruction cache with program memory.
INPUT

   None.
OUTPUT

   None.
STATUS FLAGS

   None.
DETAILS

   This operation may require up to six cycles to take effect.

   " Do  not use this instruction in either of the two slots directly follow-
     ing a delayed branch instruction.
EXAMPLES

        FLUSH CACHE;

SEE ALSO

        • “Type 26:Push/Pop/Cache” on page 9-50




                              ADSP-219x Instruction Set Reference          8-61
Program Flow Instructions




Set Interrupt

    SETINT n     ;


FUNCTION

   This instruction sets bit n (n = 1) in the interrupt latch register (IRPTL) and
   its associated interrupt. If the specified interrupt is unmasked, its corre-
   sponding bit in the IMASK register is set, program flow immediately
   branches to and executes the interrupt’s service routine. Otherwise, the
   interrupt request remains latched but ignored until the program unmasks
   it or clears it. If unmasked, the interrupt’s ISR executes; if cleared, the
   interrupt request is rejected.
INPUT

   n       Specifies which bit (and interrupt) in the IRPTL register to set.
           Valid values range from 0–15.
           The mapping of bits to interrupts is specific to particular DSPs in
           the ADSP-219x family. For details, see the ADSP-219x/2191 DSP
           Hardware Reference.
OUTPUT

   None.
OPTIONS

   None.




8-62       ADSP-219x Instruction Set Reference
                                                                                 Set Interrupt




STATUS FLAGS


Affected Flags–set or cleared by the operation    Unaffected Flags

PCSTKFULL, PCSTKEMPTY, PCSTKLVL,                   LPSTKEMPTY, LPSTKFULL
STSSTKEMPTY, STKOVERFLOW

For information on these status bits in the SSTAT register, see Table 2-7 on page 2-14.


DETAILS

    This instruction has no associated effect latency.
EXAMPLES

        MR = MR+MX0*MY0(SS), MX0 = DM(I0+=M0), MY0 = PM(I4+=M4);
        IF MV SAT MR;
        IF LT JUMP adjust;

        adjust: SETINT 12;

SEE ALSO

    “Stacks” on page 8-7.
    “Interrupts” on page 8-13.
    “Clear Interrupt” on page 8-64.
    “Type 37: Interrupt” on page 9-60.




                                      ADSP-219x Instruction Set Reference                 8-63
Program Flow Instructions




Clear Interrupt

    CLRINT n     ;


FUNCTION

   This instruction clears bit n ( n = 0) in the interrupt latch register (IRPTL)
   and its associated interrupt.
   This instruction clears a pending interrupt. It is used, in an ISR for exam-
   ple, to clear a pending interrupt that has been detected, but not yet been
   serviced.
INPUT

   n       Specifies which bit (and interrupt) in the IRPTL register to clear.
           Valid values range from 0–15.
           The mapping of bits to interrupts is specific to particular DSPs in
           the ADSP-219x family. For details, see the ADSP-219x/2191 DSP
           Hardware Reference.
OUTPUT

   None.
OPTIONS

   None.




8-64       ADSP-219x Instruction Set Reference
                                                                             Clear Interrupt




STATUS FLAGS


Affected Flags–set or cleared by the operation    Unaffected Flags

                                                   PCSTKFULL, PCSTKEMPTY, PCSTKLVL,
                                                   STSSTKEMPTY, STKOVERFLOW, LPST-
                                                   KEMPTY, LPSTKFULL

For information on these status bits in the SSTAT register, see Table 2-7 on page 2-14.


DETAILS

    This instruction has no associated latency.
EXAMPLES

        AX0 = IRPTL;
        AR = TSTBIT 12 of AX0;
        IF EQ JUMP clear;

        clear: CLRINT 12;

SEE ALSO

    “Stacks” on page 8-7.
    “Interrupts” on page 8-13.
    “Return from Interrupt” on page 8-48.
    “Set Interrupt” on page 8-62.
    “Type 37: Interrupt” on page 9-60.




                                      ADSP-219x Instruction Set Reference                 8-65
Program Flow Instructions




No Operation

    NOP    ;


FUNCTION

   This instruction causes the DSP’s core to perform no operation for one
   cycle. Program execution continues with the instruction directly following
   the NOP instruction.
INPUT

   None.
OUTPUT

   None.
STATUS FLAGS

   None.
DETAILS

   Only the core ceases operation for one cycle; the on-chip peripherals con-
   tinue their respective operations.
EXAMPLES

        NOP;   /* no operation */

SEE ALSO

   “Type 30: NOP” on page 9-52.




8-66       ADSP-219x Instruction Set Reference
                                                                          Idle




Idle

    IDLE ;


FUNCTION

   This instruction directs the DSP’s core to wait indefinitely in a low-power
   state until an interrupt occurs. When an interrupt occurs, the DSP’s core
   exits the low-power state, services the interrupt, then continues program
   execution at the instruction directly following the IDLE instruction.
INPUT

   None.
OUTPUT

   None.
OPTIONS

   <imm4> A 4-bit divisor value used to calculate the reduction in frequency of
           the DSP’s internal clock during Slow Idle mode. The Slow Idle rate
           equals the frequency of the internal clock divided by this value.
           Valid values are 0-15.

   " This option is not available on the 2192 or 2191.
STATUS FLAGS

   None.
DETAILS

   Applications typically use this instruction to implement a low-power
   standby loop:
        standby: IDLE(16);
                 JUMP standby;




                              ADSP-219x Instruction Set Reference         8-67
Program Flow Instructions




       next_instruction;

   In Idle mode, the DSP’s response time to incoming interrupts is one cycle.
   In Slow Idle mode, the DSP’s response time to incoming interrupts slows
   accordingly. When an incoming interrupt occurs, full recovery from the
   IDLE(imm4) state takes up to <imm4> DSP cycles.

   Using IDLE(imm4) in systems that have an externally-generated serial clock
   may result in a serial clock rate that is faster than the DSP’s reduced inter-
   nal clock rate. Because of this and the DSP’s reduced response time to
   interrupts, applications must avoid generating interrupts faster than the
   DSP can service them.
   Some DSPs in the ADSP-219x family also support a sleep mode, in which
   the DSP’s core and all of its on-chip peripherals enter Idle mode. To
   invoke sleep mode, the application must program the appropriate bits in
   the PLL control and I/O clock control registers and use the standard IDLE
   instruction. Exiting sleep mode requires a hardware reset.
EXAMPLES

       IDLE;          /* Idle at internal clock’s rate */

SEE ALSO

   “No Operation” on page 8-66.
   “Type 31: Idle” on page 9-53.




8-68       ADSP-219x Instruction Set Reference
                                                              Mode Control




Mode Control

        ENA               SEC_REG       ;
                          BIT_REV
        DIS
                         AV_LATCH
                          AR_SAT
                          M_MODE
                           TIMER
                          SEC_DAG
                            INT


FUNCTION

   This instruction enables (ENA) or disables (DIS) from one to seven DSP
   modes in parallel. To enable or disable a mode, this instruction sets (1) or
   clears (0), respectively, the mode’s bit in the mode status register, MSTAT
   (for details, “Mode Status (MSTAT) Register” on page 2-11). The DSP
   modes are:
        •     SEC_REG        Secondary computation register bank (MSTAT[0]).
        •     BIT_REV        Bit-reversed addressing mode (MSTAT[1]).
        •     AV_LATCH       ALU overflow status mode (MSTAT[2]).
        •     AR_SAT         ALU AR register saturation mode (MSTAT[3]).
        •     M_MODE         MAC integer operand format mode (MSTAT[4]).
        •     TIMER          Timer enable (MSTAT[5]).
        •     SEC_DAG        Secondary DAG address register bank (MSTAT[6]).
        •     INT            Global interrupts
INPUT
   SEC_REG, BIT_REV, AV_LATCH, AR_SAT, M_MODE, TIMER, SEC_DAG, INT




                                ADSP-219x Instruction Set Reference        8-69
Program Flow Instructions




OUTPUT

   None.
STATUS FLAGS

   None.
DETAILS

   You can enable or disable one or more modes in parallel by issuing multi-
   ple DIS or ENA instructions on the same instruction line, as in:
       ENA AR_SAT, ENA M_MODE, ENA AV_LATCH, ENA SEC_REG;


   " You  cannot issue both      and
                                 DIS    instructions on the same instruc-
                                          ENA
     tion line to enable and disable modes in parallel (as in:      ENA AR_SAT,
           DIS AV_LATCH, ENA SEC_DAG;)

   As shown in Table 7-2 on page 7-10, changing modes using this instruc-
   tion, as opposed to register writes or popping the status stack, does not
   incur any cycles of latency. Latency is the delay, in number of instruction
   cycles, between the time the mode change instruction executes and the
   time when the mode change takes effect, such that other instructions can
   execute operations based on the new value. A latency of 0 means that
   mode change is available to the instruction directly following the mode
   change instruction.

   " effect on thesetsnextorinstruction
           ENA/DIS INT       clears bit 5 in the
                                         cycle.
                                                   ICNTL register. The write takes



EXAMPLES

       /* Switching contexts during an ISR: */

       ENA INT;
       IMASK = 0x21A0;
       ENA SEC_REG, ENA SEC_DAG;
       AY0 = DM(I0 += M0);
       RTI (DB);




8-70       ADSP-219x Instruction Set Reference
                                                        Mode Control




       AR = AX0 + AY0;
       DM(I0 += M0) = AR;

      /* Bit-reversing DAG1 output to memory: */

      ENA BIT_REV;
      AY0 = DM(I0 += M0);
      AR = AX0 + AY0;
      DM(I0 += M0) = AR;
      DIS BIT_REV;

SEE ALSO

      • “Type 18: Mode Change” on page 9-40
      • “MSTAT Mode Control Register” on page 8-4
      • “Enabling Interrupts” on page 8-14
      • “Effect Latencies” on page 8-21




                            ADSP-219x Instruction Set Reference   8-71
Program Flow Instructions




8-72    ADSP-219x Instruction Set Reference
