On Wed, Jun 13, 2018 at 2:14 AM, Luke Kenneth Casson Leighton
<
lk...@lkcl.net> wrote:
> On Wed, Jun 13, 2018 at 2:02 AM, Andrew Waterman
> <
wate...@eecs.berkeley.edu> wrote:
>> If we were to only write a caveat about
C.MV, it would make the manual
>> more confusing, by implying
C.MV is special. It's not.
>
> ok so you're saying there's more (which i had missed).
>
> so i'm quite happy to review those as well and comprehensively check
> the language in each case and get back to you. i *believe* the reason
> that i'm picking up on this one is because it's the only one that
> makes the mistake of implying that the (REAL) instruction is a
> pseudo-one.
>
> yeah. i think that's it. without doing a full analysis (yet) i
> think
C.MV is the only instruction that i've encountered that is
> actually real.
ok, so apologies for going through this as an inline email (where a
static wiki page would be far better).
the context is not that there are pseudo-instructions that are
unclear, but that there are *real* instructions in C that refer *to*
instructions that are "pseudo-implemented". the hypothesis being
tested is that
C.MV's language is the only one of these which has:
(a) advice (unclear advice) on what pseudo-instruction to map to
(b) implementation advice for optimising the micro-architecture
as such the confusion stems from the multiple different things that
need to be communicated.
delineated with minuses, conclusion / analysis below
------
13.3 load/store
stack-based: C.SXSP uses language "It expands to sd ..." which itself
is a pseudo that expands to auipc. does not contain implementation
advice. also expansion is unambiguous: no other implementations
really possible anyway.
register-based: C.LX / C.FLX: ditto. uses "it expands to..." a
pseudo-op. ditto no implementation advice. ditto no ambiguity or
choice about what implementors should be doing
13.4 control-transfer
C.J / C.JAL. ditto with the exception that the offset is 2 rather than 4.
C.BEXZ. ditto. still uses "expands to", still expands to a
pseudo-op, (BXX r, x0, offs in this case), still clear, implementors
still nothing but obvious choices about what to do.
13.5 integer computation
integer constant-generation:
C.LI ah HA! still uses "expands to",
still expands to a pseudo-op... BUT, just like
C.MV, implementations
could hypothetically do something OTHER than "addi, r0, x0, #imm". so
*that's* what this is about... iiiinteresting.
again integer constant-generation: C.LUI: is *NOT* a pseudo-op.
unambiguous and clear.
integer register-immediate ops: C.ADDI/C.SLLI/C.SRRI/C.ANDI/ORI/XORI -
i... think... these ones are ok. not sure. still uses "expands to",
the ops they expand to are definitely not pseudo-ops, however they are
all 2-op (srcreg=destreg) which would give implementors the option to
do some optimisation... howeverrrrr.... chances are that implementors
would do the exact same optimisation in the *non* C variant so i
*believe* all these ones are ok (i.e. unambiguous and clear)
integer register-register ops:
C.MV - maps to a pseudo-op, still uses
"expands to". this is the one where there is *more than one way to do
it*, just like
C.LI. *that's* what this is about.
again integer register-register ops: C.ADD/OR/SUB/XOR etc - this one
by contrast, you don't do ADD any other way other than "add". clear
and unambiguous implementation, despite being only 2-op.
13.X oink? looks like there's a section-heading missing here called "Misc"
defined illegal instruction: clear. unambiguous.
C.NOP: ah ha! same category as
C.MV and
C.LI: there are multiple
potential implementations.
breakpoint: clear. unambiguous.
------
ok! so that was really interesting. it's not so much the use of
"expands to" as it is the fact that certain operations have *multiple*
potential implementation possibilities:
C.MV, C.NOP and
C.LI were the
three that i could identify (and wasn't expecting). all other
instructions are pretty clear (even the 2-op ones of the form "op rd
rd rs"), there's really no other option but to implement the *exact*
advised "expands to ABCXYZ".
C.LI *could* be actually implemented as a *real* "actually put this
constant directly into the register" instruction. C.NOP *could* be
implemented as OR rd, rd, x0, or ANDI rd, rd, #0xfffffffff (maybe) or
XORI rd, rd, #0 or XOR rd, rd, x0 or... as just a genuine actual NOP
which really really does nothing. implementors probably *won't* do
that in the case of C.NOP, but that's not the point.
the other interesting thing is, i now see where you're coming from
with the repeated / regular use of "expands to". however if we look
at the top 3 of table 23.3, "NOP, LI, MV", it's those three that *all*
actually have "myriad sequences" as possible implementations. it's
therefore not a coincidence that i picked up on (one of) them.
now, where this *would not matter at all* is if C did not exist. why?
because as pseudo-ops (and only pseudo-ops) we don't actually care.
it's taken care of by gcc and binutils. implementor doesn't like what
gcc and binutils puts out? no problem, they can change that.
but here, we are talking *REAL* instructions
C.MV C.NOP
C.LI, where
the spec *explicitly* says *IN HARDWARE* you *MUST* do it *EXACTLY* as
is described.... which for all *other* ops that really doesn't matter
because there is no other choice.
but for these three ops there *are* other options, and that's why the
use of the words "expands to" are not appropriate in these three
(identified) cases *and these cases only*.
whewwww :)
l.