Quoting Steve Reinhardt <[email protected]>:
On Wed, Apr 25, 2012 at 1:03 AM, Gabriel Michael Black <
[email protected]> wrote:
Quoting nathan binkert <[email protected]>:
0x20: IntegerOperate('addq', 'Rc = Ra + Rb_or_imm;')
We can make this work:
0x20: IntegerOperate.addq('Rc = Ra + Rb_or_imm;')
We could even make this work:
0x20: IntegerOperate.addq(R.c = R.a + R.b.imm)
Of course, then you're getting into magic land :)
There are a couple of reasons I like actually declaring classes for the
different instructions. First, you can have inheritance, and you can also
override select things on a per instruction basis. Second, I'd like to see,
say, all the integer instructions get defined adjacent to the machinery
that they use. If we had an IntegerOp class and the IntegerOpCc class
inherited from it and the Add class inherited from that, we could put all
that in one place so it would be easy to look up what different things were
doing.
I'm not saying that declaring classes is a bad idea... just that it's less
concise. The early part of this slice of the discussion got cut off, but
it was all about conciseness.
I wasn't saying you were, I was saying I like having the classes more
than something like
0x20: IntegerOperate.addq('Rc = Ra + Rb_or_imm;')
It's also a bit less verbose. If you have 1 instruction having IntegerOp
in front isn't that much clutter. When you have 200, the little bits add up.
I'm not sure what you're saying is less verbose than what here. I
definitely agree with your sentiment about lots of little redundant bits
adding up to a lot of clutter though, which is one thing I like about the
ISA language. Note that the ISA language uniquely allows you to eliminate
basically all per-line redundancy in the instruction definitions (beyond
punctuation) *without* requiring the definition of per-instruction classes
elsewhere.
Again, I'm not saying that that means the ISA language is unquestionably
the best way to do it. This piece of the discussion got started because
you expressed doubts that the ISA language was more concise, and my point
was just to convince you that it is (at least for the RISC ISAs it was
designed for). It may be appropriate to trade away that conciseness for
other benefits, but it's true that we are trading something away.
I think you thought I was comparing against the parser. I was really
comparing against the alternative syntax(es) Nate proposed. Even
though I'd prefer the classes, I still don't think those are a bad
idea either. Maybe we could support both somehow and use them
situationally.
If we use execfile to execute the isa parser stuff, then we can have
default values for unknown variables (as of python 2.4 the dict can be
any mapping object):
class default(object):
def __call__(self, *args, **kwargs):
print args, kwargs
class Dict(dict):
def __getitem__(self, name):
try:
return dict.__getitem__(self, name)
except KeyError:
val = default()
self[name] = val
return val
d = Dict()
exec "asdf(99)" in d
The python sorcery/python library design aspect of this is where my past
efforts at this have come apart. Help getting that part right is definitely
appreciated.
It would be nice to avoid python sorcery, IMO... doing it all in python
that's so customized and rewired that it doesn't look like python doesn't
seem like a big advantage over the custom language to me.
I actually kind of liked the code sketch that Gabe had in his earlier email
(from 2:04 AM Tue 4/24). From what I've seen of the x86 description, the
ISA language itself gets in the way more than it helps. So you could
revamp the "library" code we have to support an interface kind of like what
Gabe proposes there, reimplement x86 and maybe ARM in that pure-python
style, and reimplement the language parser back end to call those same
methods to eliminate redundancy but provide backward compatibility with
existing ISAs like Alpha.
So for example, Gabe has a SwitchDecode method (that looks like it mimics
the current ISA language decode block functionality) and an IfDecode method
(which is new). (Or are these classes and not methods? Doesn't matter
really, except for how I'd prefer the capitalization to end up.) We could
redo the parser to pull the SwitchDecode stuff out into a separate
method/class, then just have the parser call SwitchDecode after it parses a
decode block. Meanwhile IfDecode wouldn't be accessible from the language,
but that's OK for now, since clearly none of the existing ISA descriptions
uses it.
This would have the side effect of saying "if you want to use IfDecode, you
can't use the language at all", but I think that's OK, since most of the
language is really designed just to set things up for the decode block, and
if you're not using the decode block, you really don't get anything out of
the rest of the language either (IMO).
Yeah, I'm not a proponent of too much fanciness either, but a little
bit is often useful. The trick is knowing which little bit and being
able to apply it properly. I do like my example too. Even though it
was off the cuff, it looks like something like it would work pretty
well. I think what we're doing has a pretty natural representation in
python for the most part, and that's one of the reasons I'm a
proponent of doing things that way. I'd like the decode building
blocks to be classes/objects so they can be built up in a persistent
hierarchy and operated on with different functions for different
purposes (something like emitHeader, emitDecoder, etc.) or even be
built ahead of time if there are chunks that show up in multiple spots
(Neon decoding in ARM is an example I can think of) or if you want to
somehow put different parts of the decoder in different files to give
the compiler a break and bring down its peak memory usage. The space
between doing things with functions and doing things with
classes/objects is not wide in python though, so I can believe it
would work out either way.
Gabe
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev