Ok, I've uploaded my current snapshot to
http://hg.genunix.org/libdisasm.hg for all that wish to take a look.
I've also included copies of libdisasm*.[ch] to simplify the build
(obviously these will be redundant once/if this is integrated).

Currently, there is an environment variable that can be set,
_LIBDISASM_DEBUG, that can take a combination of the following values:

   none        Do no special formatting (i.e. no synthetic
instructions, no elimination of redundant values
   compat    Output as compatible as possible (more below) with the
current closed source disassembler (based on trial and error) --
Default.
   synth-all   Output all supported synthetic instructions
   format      Wriite on stderr the individual field values of the instructions
   binary      Output the instruction value in binary on stderr

Values can be combined with a , (i.e. export _LIBDISASM_DEBUG=compat,format)

The following table shows what is done when:

For addresses,
    [ %rXX + %g0 ] -> [ %rXX ]      compat, synth-all
    [ %rXX + 0x0 ] -> [ %rXX]        compat, synth-all
    [ %g0 + %rXX ] -> [%rXX]        compat, synth-all

Synthetic Instructions:
  subcc %rs1, reg_or_imm, %g0  -> cmp %rs1, reg_or_imm     compat,synth-all

  jmpl address, %g0                   -> jmp address
    compat
  jmpl address, %o7                   -> call address
     compat

  bn.a.pt %xcc, label                  -> iprefetch label
  orcc %g0, %rs2, %g0              -> tst %rs2
   compat, synth-all

  jmpl %i7+8, %g0                     -> ret
          compat, synth-all
  jmpl %o7+8, %g0                    -> retl
         compat, synth-all

  restore %g0, %g0, %g0           -> restore
    compat,synth-all
  save %g0, %g0, %g0               -> save
     compat,synth-all

  sra %rs1, %g0, %rd                -> signx %rs1, %rd
  sra %rd, $g0, %rd                   -> signx %rd

  xnor %rs1, %g0, %rd               -> not %rs1, %rd
        compat,synth-all
  xnor %rd, %g0, %rd                 -> not %rd
            compat,synth-all

  sub %g0, %rs2, %rd                ->neg %rs2, %rd
         compat,synth-all
  sub %g0, %rd, %rd                  -> neg %rd
             compat,synth-all

  casa [%rs1]#ASI_P, %rs2, %rd -> cas [%rs1], %rs2, %rd                synth-all
  casa [%rs1]#ASI_L_P, %rs2, %rd -> casl [%rs1], %rs2, %rd            synth-all
  casxa [%rs1]#ASI_P, %rs2, %rd -> casx [%rs1], %rs2, %rd             synth-all
  casxa [%rs1]#ASI_L_P, %rs2, %rd -> casxa [%rs1], %rs2, %rd        synth-all

  add %rd, 1, %rd                       -> inc %rd
                  synth-all
  add %rd, const13, %rd             -> inc const13, %rd
          synth-all
  addcc %rd, 1, %rd                   -> incc %rd
                synth-all
  addcc %rd, const13, %rd         -> incc const13, %rd
        synth-all

  sub %rd, 1, %rd                       -> dec %rd
                 synth-all
  sub %rd, const13, %rd             -> dec const13, %rd
         synth-all
  subcc %rd, 1, %rd                   -> deccc %rd
              synth-all
  subcc %rd, const13, %rd         -> deccc const13, %rd
      synth-all

  andcc %rs1, reg_or_imm, %g0  -> btst reg_or_imm, %rs1
compat,synth-all
  or %rd, reg_or_imm, %rd          -> bset reg_or_imm, %rd
 synth-all
  andn %rd, reg_or_imm, %rd      -> bclr reg_or_imm, %rd
  xor %rd,reg_or_imm, %rd         -> btog reg_or_imm, %rd

  or %g0, %g0,%rd                     -> clr %rd
            compat,synth-all

  stb %g0, [addr]                        -> clrb [addr]
             compat, synth-all
  sth %g0, [addr]                        -> clrh [addr]
              compat, synth-all
  stw %g0, [addr]                       -> clr [addr]
              compat, synth-all
  stx %g0, [addr]                        -> clrx [addr]
             compat, synth-all

  srl %rs1, %g0, %rd                 -> clruw %rs1, %rd
  srl %rd, %g0, %rd                   -> clruw %rd

  or %g0, reg_or_imm, %rd         -> mov reg_or_imm, %rd
compat, synth-all
  rd %y, %rd                             -> mov %y, %rd
  rd %asrN, %rd                         -> mov %asrN, %rd
  wr %g0, reg_or_imm, %y         -> mov reg_or_imm, %y
 compat, synth-all
  wr %g0, reg_or_imm, %asrN    -> mov reg_or_imm, %asrN
compat, synth-all


The current closed source disassembler does not seem to use the
correct floating point register names for double and quad precision
floats -- it's always %fNN (not %dNN or %qNN).  While in some cases
%fNN is an alias, as far as I can tell, that is not the case for all
of the double and quad registers (%q48 or %d50 for example).  My
preference would be to use the %dNN or %qNN names as I suspect it
makes the intent more obvious.

The other deficiency with compat mode is that for certain load and
store variants, the closed source library will still output '[%rs1 +
0x0]' but not in others.  I'm not convinced it'd be a good use of time
to try to figure out when it does and when it does not print the '+
0x0', and instead just never print '+ 0x0' except when
_LIBDISASM_DEBUG=none

All of the settings are easily tweaked if there's a strong desire to
have or not have certain synthetic instructions be used.

I've tested it (using the bundled compare.pl script) against /usr/bin,
/bin, /usr/sbin, /sbin, /kernel/drv/sparcv9,
/platform/sun4u/kernel/sparcv9/{gen}unix, and so far everything
appears to check out.  I'm planning to add a little more
sophistication to the compare.pl script to recognize some of the
differences I mentioned, and ignore those, that way the noise is cut
down further.

So, the next question I'd have is what the next step would be to get
things closer towards integration. Or rather, what things I can do now
to help make the process go smooth when things are ready.
_______________________________________________
tools-discuss mailing list
tools-discuss@opensolaris.org

Reply via email to