This is the mail archive of the cgen@sources.redhat.com mailing list for the CGEN project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

arbitrary range checks on fields.


I'm working on a port that has an oddball encoding of PC-relative
displacements for branch/jump/call insns.  Insns are either 16 bits,
or 32-bits when a 16-bit immediate is present.  The branch/jump/call
immediate-operand forms all have a PC-relative target (right-shifted 1
bit since insns are 2-byte aligned) and come in either a short 8-bit-
displacement form or a long 21-bit displacement form.  The length of
the displacement is determined by the most-significant 4 bits of the
displacement--the same opcode is used for both short and long.

A short displacement after right-shift is in the range [-112..112),
which better understood in hex as [0x90..0x6f] or (0x8f..0x70), that
is to say that the top nybble of a short displacement has any bit
pattern except 7 or 8.  7 in the top nybble indicates that the
displacement is long and positive, and 8 means long and negative.  For
the long forms, the full 21-bit displacement is formed by ignoring the
3 least significant bits of the top nybble so that we take the top bit
as sign bit, and the 20 least significant bits of the 24-bit
displacement, like so:

      positive: 0x7XXXX => 0x0XXXX
      negative: 0x8XXXX => 0x1XXXX

For the long displacement, I had to do some funky things to get this
to assemble and disassemble properly, and had to write a BFD reloc
special function that cloned much of bfd_install_relocation.

The short form is comparatively easy to handle *except* that I don't
get tight enough range-checking when inserting the 8-bit displacement
operand.  CGEN automatically checks that the encoded displacement is
in the range [-128..128), appropriate for a full 8-bit signed field,
but the operand's true valid range is [-112..112).  CGEN lacks a
mechanism for range checking, and the encode/decode hooks for
define-field have no means of returning an error message.

It's not good enough to handle the error with a custom operand-parse
hook because the field most often parses as a label and insertion
isn't done until the fixup pass.

How do people think this should be done?  Perhaps add min & max
members to the field class?  More flexible would be to add a
range-check hook to the field class, but what should it return?
Boolean for valid/invalid is easy to write in scheme inline, but can't
produce an error message that tells the valid range.  Alternatively,
the hook could return a string error message on failure and NULL on
success, but it's more of a nuisance since it must be written in C
and invoked via c-raw-call (is that right, or is there a convenient
way to format strings in scheme?)

Comments?

Greg


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]