Port-vax archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: VAX addressing modes
On Thu, 27 Jul 2017, Mouse wrote:
> > Therefore the correct solution is to insert a symbol of the data type
> > (STT_OBJECT in ELF-speak) at the beginning of any text content that
> > is supposed to be intepreted as data and then a symbol of the code
> > type (STT_FUNC in ELF-speak) at the end (if applicable). This has to
> > be done by the compiler (or whoever has written handcoded assembly
> > code). Some GCC target backends do this already, the VAX one clearly
> > does not, as shown by this example.
>
> I think I disagree.
>
> The jump table for a case instruction actually is code; I wrote too
> briefly. It is just unusual code. But it is still code; it is fetched
> from the instruction stream, cached in the I-cache (if the CPU has
> one), is subject to all the restrictions on code (such as not coming
> within 512 bytes of nonexistent memory) - the VAX is more von Neumann
> than Harvard, but from a Harvard point of view the displacement table
> comes from instruction memory.
Whether I$ or D$ is used for jump table data by VAX implementations is I
believe a microarchitectural feature. At least I cannot find anything in
the VAX Architecture Standard to claim that CASEx is not just a slightly
complicated variant of an ordinary indexed PC-relative data load with the
value retrieved added to the PC as the destination register. And using
the instruction fetcher to load the piece of data from a random location
within the jump table seems rather unlikely to me -- it would require
dedicated logic for this specific instruction rather than the usual
address generation and data path.
What seems likely to me is that the address is generated the usual way
(except that with the displacement hardwired to 0) and then the data path
is used to load the PC such as with (pardon my GNU-speak):
subl3 $32, %r0, %r1
cmpl %r1, $5
bgtru (2 * (5 + 1)) + 0f
cvtwl 0f[%r1], %r1
jmp 0f[%r1]
0:
which (barring my limited VAX assembly skills) is supposed to be an
open-coded equivalent of:
casel %r0, $32, $5
(CASEW and CASEB can be similarly expanded). I see no reason for a jump
table used with one of the CASEx instructions to be treated specially by a
disassembler.
NB several MIPS processors have issues with MIPS16 PC-relative loads from
the split memory they have (ISPRAM vs DSPRAM) for the very reason the data
path fetches through the D$ rather than I$ for these instructions just as
with any other load instructions and hw people say making an exception for
PC-relative loads to use I$ for their data path is costly in RTL terms.
This problem precludes the use of constant pools with code intended to run
on these processors, requiring much longer code to calculate the value to
be loaded instead.
> Starting disassembly in the middle of a CASE jump table is no different
> from starting disassembly in the middle of any other multi-byte
> instruction. I would not expect a disassembler to look backwards in
> either case.
Symbol table annotation would at least tell the tool the stream requested
is actually data, as well as where exactly the next instruction starts,
e.g.:
$ cat casel.s
.text
.globl foo
.type foo, @function
foo:
.word 0
subl2 $4, %sp
casel 4(%ap), $32, $5
0:
.type __jump_foo_1, @object
__jump_foo_1:
.rept 6
.word 1f - 0b
.endr
__jend_foo_1:
1:
ret
.size foo, . - foo
$ vax-linux-as -o casel.o casel.s
$ vax-linux-objdump -dr casel.o
casel.o: file format elf32-vax
Disassembly of section .text:
00000000 <foo>:
0: 00 00 .word 0x0000 # Entry mask: < >
2: c2 04 5e subl2 $0x4,sp
5: cf ac 04 20 casel 0x4(ap),$0x20,$0x5
9: 05
0000000a <__jump_foo_1>:
a: 0c 00 0c 00 0c 00 0c 00 0c 00 0c 00 ............
00000016 <__jend_foo_1>:
16: 04 ret
$
FWIW,
Maciej
Home |
Main Index |
Thread Index |
Old Index