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 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 [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 [UNTIL ] ; 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 + ). 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 ), 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 + ) 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 [(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 + ). 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 [(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 + ). 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 [(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 + ). 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 ; 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 ; 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 () [(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 () [(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 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 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