- Standalone Python disassembler for 24-bit ADSP-219x instructions - Complete instruction set reference (PDFs + extracted text) - Architecture documentation and getting-started guide - Test ROM generator with packed (3-byte) and padded (4-byte) formats - r2pipe-based analysis script for radare2 integration
2865 lines
99 KiB
Plaintext
2865 lines
99 KiB
Plaintext
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
|
||
|