>> Before I mentioned using @, and I have a patch that makes that change in
>> the parser and in all the ISA descs. It was less painful than you may
>> assume.
>>
> I haven't looked at your patches yet... is the main point of switching from
> . to @ to allow structure field accesses?

Basically. It could be structure fields or the bitfields of a BitUnion.
This had actually cropped up with the Twin(32|64)_t types SPARC uses,
and to get around it we added clunky parenthesis so the .foo didn't sit
directly next to the operand. gcc figured it out, but it could slip by
the parser.

>
>> I don't think there's a good way to figure out whether operands are a
>> source and/or destination in a setup like this. In the past, I've tried to
>> come up with a scheme that would force gcc/C++ to figure it out for us, but
>> no matter how clever/depraved I allow my solutions to be, they still don't
>> work. It might be possible to use a fancy compiler system like LLVM to build
>> a new tool to do it, but that isn't a near term solution (although I
>> wouldn't rule it out entirely).
>
> One potentially interesting angle to pursue is gcc-xml... I don't know much
> about it except that, as the name implies, it generates an xml
> representation rather than machine code, which should be reasonably
> analyzable.  I bet it's still hairy, but it might be the least hairy
> alternative.
>
> I expect the big problem with most of these approaches is that the final
> compilation context for most of the C snippets is not known at the time the
> code is parsed by the parser for operands etc.  Thus there will be symbols
> that you can't disambiguate as types etc. because the proper include files
> haven't been included (which could be undecidable if the proper include
> files are also being generated in the same isa_parser run, so maybe they
> don't even exist yet at the point where you need them).

The XML thing is an interesting possibility, and it avoids having to
make a whole new thing that understands C++. It would still mean we'd
have to make a whole new thing that understands XML (which is much
easier), but then there's the chicken and egg issue you mention. I don't
think we do anything sneaky with deciding what header files to include,
though, and we could probably tell the tool about the operands somehow,
maybe by making them globals that get thrown away later. The current
approach is far from 100% correct in that sense, so if we're a little
fuzzy around the edges that should be ok.

> This is why the ad hoc yet (as you say) surprisingly effective heuristics
> were used.  Perhaps the heuristics could simply be extended to deal with
> structure field accesses... if the thing after the symbol is a ".", then you
> look past that to see if there's an equals sign or not, and behave
> appropriately.

"appropriately" isn't clearly defined, really. There's an example in ARM
where there's a bit broken out of a status register which is set if some
condition happens. If you set it, you're really setting the whole thing
even though it looks like you're just setting the bitfield. Treating
that operand as a source isn't necessary in that case even though it
would normally be.

>
>
>> Another solution might be to explicitly list source and destination
>> operands like inline assembly blocks.
>
> I definitely don't like this idea.  One of the main motivations for the
> current implementation was the old SimpleScalar ISA definition macros, which
> required explicit listing of operands... and which as a result had subtle
> bugs that went undetected for years where particular dependencies weren't
> being enforced because someone left an operand out of the list.
>
> As you say, the current approach "works remarkably well most of the time",
> so while I'm all for improving it and addressing its shortcomings, I see no
> need to throw it out and replace it with something that's more manual
> effort, less concise, and more error prone.
>
> An extension that allows you to manually override what the parser finds. to
> deal with those cases where it's getting confused, would be fine though...
> basically sort of what you've been doing already, except that instead of
> "overriding" its heuristics by coming up with awkward code sequences that
> trick it into doing the right thing, you have a more blunt and effective
> path to do that.  That's probably not as big a step forward as you want, but
> to me it's preferable to just switching to a fully manual explicit scheme.

The manual override would get us there, but one thing I worry about is
that if BitUnions or composite operands are used often, you might need
to have them all over the place. Some sort of inheritance or being able
to associate the overrides with a blob of code once that gets reused a
lot (like setting condition codes, checking predicates, etc.) would help.

>
>> Any ideas how we can get this to work better? This is a big stumbling block
>> for this sort of set up, and this will lead to operand types which can be
>> automatically composited from component values instead of having to have
>> hacks that, for instance, retrofit/filter code blobs to build double
>> precision floating point values from single precision ones behind the
>> scenes, or to merge control and condition code bits everywhere the whole
>> control register is needed, etc. I expect that last part to be important for
>> x86 to get the control flags dependency issues fixed in O3.
>>
> Would it help to have a way to explicitly declare compound operand types so
> that the parser can treat them intelligently?  Maybe it could be as simple
> as declaring "operand foo has fields a, b, and c" and having that
> autmoatically turn into separate internal entries for foo, foo.a, foo.b, and
> foo.c in the operand-matching code, which are linked together so that the
> right inferences are made when any of them are found.
>
> Just a thought...

My idea is to be able to inherit from the standard op types like
IntRegOperand and allow them to install more than one index and/or
change how they're declared, read, and written. So say for example you
had a 128 bit wide SIMD instruction operating on four floating point
registers which are normally accessible as 32 bit, indexed through some
strange scheme. You could say that operand generates 4 indices,
determined by whatever weird formula or just sequentially. Then you
could define a structure which was the union of an array of 4 32 bit
ints and 4 floats or 2 doubles, or 16 bytes, or ... The constructor
could take the return of reading the 4 indices with
readFloatRegOperandBits to fill it's main array, and then the
instruction could access whatever other representation it needed. The
other direction would work as well. Then, assuming we get this
source/dest thing straightened out, you could have an instruction that,
say, did parallel byte adds defined like this:

for (int i = 0; i < 7; i++)
    Dest.bytes[i] = Source1.bytes[i] + Source2.bytes[i];

And all the other goop would figure itself out. If some other scheme was
needed (runtime selectable width, selectable float vs. int, etc) then
the IntRegOperand subclass combined with the composite operand type
could have the smarts to do the right thing all tidily hidden away after
it was set up. Note that Dest is just a dest, even though it uses a
structure field.

Also the operands might be smart enough to change how they set
themselves up on the fly. Lets say in a particular mode you only need 2
32 bit floats and the other two spots are zeros. The operand
initialization code could figure out what mode it's in at construction
time that it doesn't need all 4 operands and could only fill in 2 spots.
The next operand would then pack in behind it. This would hopefully make
it easier to get multiple behaviors without having to define a new
instruction (or just code blob) for each one.

There are some things to be careful of too. If one of those FP values
was used independently for some reason, there might not be any
coordination and one version might get squashed somehow. That could
happen if, say, you did the pairwise add but also divided by some other
scalar value for each pair. Often it's not clear what the instruction
should do in these cases anyway, so this might be ok.

I'm sure there are other nice things this can be used for too, but these
are the sort of the immediate uses I had in mind.

Gabe
_______________________________________________
m5-dev mailing list
m5-dev@m5sim.org
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to