Dan Sugalski <[EMAIL PROTECTED]> wrote:
> At 11:56 AM +0100 12/12/03, Leopold Toetsch wrote:
>>
>>But having multi-keyed variants of all relevant opcodes would burst
>>our opcode count to #of-keyed-opcodes * #of-key-permutations. That's
>>not feasable.
> Definitely not. Here's an alternative.

I meant #of-implemented-key-permutations, which is anything from 1 to
4^3 (or more if string keyes are supported in ops, or we consider the
no-key case too ...)

> ... I'd originally planned on
> there being a single keyed variant of each op, so the above would be
> written:

>    add P0[S0], P1[S1], P2[]

> Note that a key is passed in for $k, just a NULL key, all keys were
> meant to be in S registers, and there weren't going to be constant
> keys or pure-integer. Things have changed a bit. :)

I know that The Plan was, to use one *all* keyed opcode. But - "Things
have changed a bit" - when going with only one multi-keyed we have:
- one constant PMC per argument, these have to be constructed at program
  load time, albeit keys are folded (identical keys in different
  instructions are only generated once) and they don't need marking, its
  some overhead
- each keyed access needs a check, if the key is non NULL - that are
  three ifs per vtable meth
- and finally extracting the index

This all reduces the advantage of having all keyed ops towards zero.

Further: We have then e.g. add_p_p_p and add_p_k_p_k_p_k. Overloading
the add operator would need to delegate 2 vtable methods and implement 2
different subs to do the job.

> Note that I'm perfectly OK mandating the following:

> 1) All keys must be of the same type (integer key or key struct keys)

Already starting permutations ...

>>1) The assembler splits above PASM statement into two:

> This is the one thing that I'll grumble about -- we can argue over
> other things, but the assembler should *not* implicitly split stuff
> out like this. Maybe (Only maybe!) IMCC should, but I'd argue not
> there as well.

Imcc *is* the assembler. Assembler input is a multi-keyed opcode as
defined in pdd06. Its like a macro expansion one line generating 2
opcodes.

> ... It should be explicitly specified in the source where
> the keys should be fetched.

These 2 operations are always adjacent.

>>5) These returned pointers are stored in REG_PMC(x) .. REG_PMC(z)
>>    (x = 32, y = 33, z = 34) [2]
>>    struct PReg has    PMC *registers[NUM_REGISTERS + 3];

> This would be the clever bit -- key registers. I'm fine with key
> registers however... if we're going to add them, why not just have a
> separate set of key registers and be done with it?

The problem is addressing these key registers in the opcode. A non keyed
C<add> calls a vtable on and with PREG(i), where PREG(i) is
REG_PMC(cur_opcode(i)). When key registers are accessed with a
different scheme, we again get code duplication with all the drawbacks.

So my proposal uses key registers, which are more or less special
depending, if they are outside or inside the regular register file.
But e.g. using REG_PMC(32) doesn't need any further change to the
vtables. C<add> is C<add> nothing more. And there is no overhead for
e.g. adding a constant to a keyed operand. We can continue using all the
optimized (e.g. integer indexed) vtable meths.

leo

Reply via email to