[comp.arch] isamax and instruction set design, and IEEE interval arith.

john@acorn.co.uk (John Bowler) (06/18/91)

In article <1991Jun17.163456.30549@qut.edu.au> ifn249reilly@qut.edu.au writes:
>It might not be the world's fastest RISC processor, but the Acorn ARM certainly
>does have some nice design ideas.  On the ARM _all_ instructions are conditional
>so conditional loads are just the case where you don't select the "do always"
>condition code on the load instruction.
>
>For another current thread, on IEEE maths and interval arithmetic, the ARM
>floating point instruction format specifies the rounding mode as part of the
>instruction, rather than a separate "change mode" instruction.  I'm not sure
>whether the FP instructions are conditional too, it's a while since I looked
>at the data book.  I'd be surprised if they weren't, though.

The whole instruction set space is conditional; the most significant four
bits of any instruction specify the condition.  The current ARM cpus do not
implement the FP instructions; rather they are emulated in software or
implemented using a hardware coprocessor.  Part of the instruction space is
allocated to coprocessor instructions, some of which are defined as the FP
instructions.  The format of the coprocessor instructions is understood by
the CPU (to an obviously limited extent).  The cpu decodes the condition
field and avoids presenting the instruction to the coprocessor if it will
not be executed (hum, I'm not sure if this is always the case).

The real problem with this is that much of the instruction space is wasted
with instructions which are hardly ever used in practice (not a very RISCy
thing to do!)  Almost all instructions in a compiled problem use the
``Always'' condition code.  The ``Never'' condition code is never used :-).
NV alone wastes 1/16 of the possible instructions for the ARM.  However some
nice things are possible.  For example:-

	if (condition) a = b; else b = a;

and similarly simple if/then/else statements (including ones with an empty
else clause) can be executed without branches - on the ARM a branch breaks
the pipeline, meaning that a branch instruction takes the time of four
register-register instructions on a cpu without a cache.  As a result it is
worth using conditional instruction sequences of up to four instructions in
length.

Some extreme results can be obtained by loading values into the program
status register (setting the four condition code flags) and executing
appropriate conditional statements.  In some (even more extreme :-) cases
this can be worth doing for performance reasons.  But, on balance, I think
I would prefer a delayed branch and more registers (32 rather than 16).

The assembler syntax is relatively simply, for an instruction iii (all instructions
have three letters, even ORR :-), a condition cc (always two letters) and
instruction (iii) specific bits z:-

	iiiccz

for example:-

	LDREQ		; load register if zero flag is set
	ADDGTS		; register+register -> register iff ``GT'' (ie appropriate
			; combinations of carry and overflow), set the condition
			; codes (iii==ADD, cc==GT, z==S).

Notice that all register/register instructions only set the condition codes
if the ``S'' flag is set in the instruction - else it is rather difficult
to write conditional instruction sequences!  This also means that careful
code writing can be used to preserve the condition codes across a sequence
of unrelated instructions, allowing:-

	if (condition) statement1;
	statements;
	if (condition) statement2;

to (effectively) store the CSE ``condition'' in the PSR flags (but our
compiler *doesn't* currently do this, although assembler hackers often do).

John Bowler (jbowler@acorn.co.uk)