[Libre-soc-dev] Compressed instructions

Luke Kenneth Casson Leighton lkcl at lkcl.net
Sun Nov 22 18:54:16 GMT 2020

On 11/22/20, Alexandre Oliva <oliva at gnu.org> wrote:

> we were working on.  Now I think I have a solid picture.  We may have:
>   <32-bit insn>

only in standard v3.0B

>   <10-bit insn>

when in v3.0B mode the only way to identify "getting in" to 16 bit
mode is: use the v3.0B Major Opcode to do do.

this takes surpriiiise 6 bits

>   <16-bit insn>

once transitioned "out" of v3.0B mode the entire 16 bits may be
interpreted any way you like.

>   <more 16-bit insns>

still in 16bit mode, still doing anything--we-like

>   <16-bit insn with bits to switch back to 32-bit mode>

bit 15, yes.

>   <32-bit insn>

finally back to v3.0B mode.

at this point the only way to flip back to 16bit mode is: to use a
10bit encoding.

however we deemed that to be wasteful, so decidate one precious extra
bit of the 16bit mode to say, "actually please only return to v3.0B
mode for only ONE instruction"

this allows efficient embedding of just the one 32bit opcode and not
wasting space.

> This means we do have the problem of, by just looking at the bits at a
> certain location, not knowing how it ought to be decoded.

this is absolutely no different from LE/BE mode and 32/64 bit mode, or
from Program.Compatibility Register dynamic switching mode, or from
IEEE754 non-compatibility mode.

which, reiterating, kindly and firmly, it is not our problem that
current versions of binutils do not support these dynamic
modeswitching bits.

>  That may be
> trouble for the disassembler, but given we spend 6 bits just for the
> mode-switch, I very much doubt it would be viable and wise to make pairs
> of 16-bit instructions immediately recognizable as such, rather than as
> a single 32-bit instruction, by their encoding.

indeed.  this wastes up to 50% potential space if there is only one
16bit instruction (the other is a nop which is a total waste, you
might as well use the 32bit version). worse is that the 1st must be a
10bit because you need 6 bits major opcode to identify 16bit mode.

hypothetically you could say "if this instruction is 16bit the next 3
are 16bit" i.e. take 2x32 this would actually be 10bit 16 16 16
because you need the v3 0B major opcode to identify the sequence

again, here: on an odd count the last instruction is wasted as a nop.

> Since the extra bit needed to tell how to interpret the code stream is
> dynamic, in a status register,


> we will need to find some other way for a
> disassembler to identify 16-bit-encoded code ranges.

mirror the state tracked by the status register.

this is actually very simple: take the status register and shove a
copy onto the MSBs of the current instruction being decoded... and
*then* start decoding.

in other words: the status register **IS** repeat **is** part of the
*actual* instruction.

the fact that it did not come from the instruction stream of bytes is
completely irrelevant.

this should already be done in binutils for changes to ppc64 MSR that
alter LE/BE and if it is not then that is quite a bug in binutils
objdump.  however given that very few programs are likely to do that,
combined with it being a privileged operation, it's understandable
that it's never come up.

>  This will likely
> not be very unreliable :-(

if the hard rule is set that a function call may only be entered and
exited in standard v3.0B Mode to respect standard ABI the problem is
99.9% solved.

this just leaves raw assembly to sort out and for that there is
commandline switches (LE/BE, 32/64 being existing examples of such).


More information about the Libre-soc-dev mailing list