Language Implementation
7-69
7
Example 7-6 atadd.c (continued)
int
raise_priority int(n)
{
unsigned cur_pc;
cur_pc = modpc(0, 0); /* just read the pc */
if ((cur_pc & 0x2) != 0)
{
/* we're in supervisor mode, so we can change it */
unsigned priority = ((cur_pc >> 16) & 0x1f) + n;
unsigned priority_mask = 0x1f << 16;
if (priority > 31)
priority = 31;
cur_pc &= ~priority_mask;
cur_pc |= priority << 16;
modpc(cur_pc, priority_mask);
return 1;
}
return 0;
}
Consider the lines containing the asm:
__asm__ __volatile__("modpc %1,%1,%0" : "=d"(new_pc), :
"dI"(mask),"0" (new_pc));
• "modpc %1,%1,%0" is the
asm-template
. The modpc instruction
reads and modifies the i960 architecture's process control register.
The instruction takes three arguments.
•
"=d"(new_pc) is the only
output-spec
. It is the first operand, i.e.,
operand 0. The
"=d"
constraint
indicates that this is an output
operand, and that any global or local word register can be used.
•
"dI"(mask) is the first
input-spec
. It is operand 1. The "dI"
constraint
indicates that the operand must be a word register, or be
a constant in the range 0 through 31. Note that operand 1 is
referenced twice in the
asm-template
because the modpc instruction
requires the same input operand in two places.