Sujet : Re: Oops (Concertina II Going Around in Circles)
De : mitchalsup (at) *nospam* aol.com (MitchAlsup1)
Groupes : comp.archDate : 11. May 2024, 20:16:46
Autres entêtes
Organisation : Rocksolid Light
Message-ID : <46067b1e52e8998acdd607199d3dbf30@www.novabbs.org>
References : 1 2 3
User-Agent : Rocksolid Light
Anton Ertl wrote:
jgd@cix.co.uk (John Dallman) writes:
Also, teaching development tools about vast instruction sets is likely to
demonstrate the RISC lesson again: compilers only use the simple parts.
That needs some elaboration. There are several potential reasons for
that:
1) The compiler writers found it too hard to use the complex
instructions or addressing modes. For some kinds of instructions that
is the case (e.g, for the AES instructions in Intel and AMD CPUs), but
at least these days such instructions are there for use in libraries
written in assembly language/with intrinsics.
The 801 was correct on this::
The compiler must be developed at the same time as ISA, if ISA has it and the compiler cannot use it then why is it there {yes there are certain privileged instructions lacking this property} Conversely is compiler could almost use an instruction but does not, then adjust the instruction specification so the compiler can !!
2) Some instructions are slower than a sequence of simpler
instructions, so compilers will avoid them even if they would
otherwise use them.
VAX CALL instructions did more work than what was required, it did
the work it was specified to perform as rapidly as the HW could perform
the specified task. It took 10 years to figure out that the CALL/RET
overhead was excessive and wasteful.
That has been reported by both the IBM 801
project about some S/370 instructions and by the Berkeley RISC project
about the VAX. I don't remember any reports about addressing modes
with that problem.
The problem with address modes is their serial decode, not with the ability
to craft any operand the instruction needs. The second problem with VAX-like
addressing modes is that it is overly expressive, all operands can be
constants, whereas a good compiler will never need more than 1 constant
per instruction (because otherwise some constant arithmetic could be
performed at compile (or link) time.)
3) Some instructions or addressing modes can be selected by compilers
and are beneficial when they are used, but they are selected rarely
because they fit the needs of the compiled program rarely.
The following constructs are seen often enough that the memory reference
instructions should support them well::
*p LD Rd,[Rp]
p->next LD Rd,[Rp,#next]
p->array[i] LD Rd,[Rp,Ri<<scale,#array] // RISC-V fails
p[i] LD Rd,[Rp,Ri<<scale] // RISC-V fails
p[i].field LD Rd,[Rp,Ri<<scale,#field] // RISC-V fails
Given the above: local variables just use SP and the variable's offset on
the stack or frame; global variables resolved by the linker are accessed
with 32-bit displacements off the IP (instruction pointer); while external
variables are accessed through GOT as::
extern[i] LD Rp,[IP,,#GOT[i].address-.]
LD Rd,[Rp,#GOT[i].offsset]
or an entry point called with::
extern f() CALX [IP,,#GOT[f].address-.]
{{CALX is effectively LD IP,[address] while storing the return address in R0}}
CALX was invented/developed specifically to optimize external calling of subroutines (and adjusted until it fit the requirements.) Thus, not only
should the compiler be n development with ISA, so should the linker !!
IIRC the RISC papers mentioned mainly 2), with a little bit of 3).
- anton