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