Yet another keyed ops proposal[1]

Given the Perl6 expression:

@a[$i] = @b[1] + $k;

This should translate to

add P0[I0], P1[1], I2

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.

So here is another proposal to implement these ops.

1) The assembler splits above PASM statement into two:

  keyed P0[I0], P1[1], 0
  add   Px,     Py,    I2

2) There is one keyed opcode with all possible key-permutations.
3) For keyed arguments get_pointer_keyed* is called on source operands,
   non-keyed operands are replaced by 0.
   get_pointer_keyed* return a PMC* ptr to the store inside the
   aggregate.
4) For a keyed destination the set_pointer_keyed* is called,
   preparing the aggregate store and returning that PMC*.
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];
6) The next (add) opcode is modified, so that for all keyed operands a
   plain PMC operand is emitted, the register number is x..z.
   Non-keyed operands are as is.

This adds one opcode dispatch and increases code size a bit, but we
we wouldn't need any additional keyed vtables. And all the checks for
passed NULL keys (i.e. no key) aren't necessary.

Comments welcome,
leo

[1] And I hear Dan groaning: ONNTA
[2] we could of course reserve regs# 29..31 or 0..2 too for this purpose



Reply via email to