On Mar 6, 2006, at 23:16, Jonathan Worthington wrote:

"Leopold Toetsch" <[EMAIL PROTECTED]> wrote:

$I0 = pio.'print'("sample data\n") # return sucess (>=0) or failure (<0)
  pio.'print'("sample data\n")           # throw exception on failure

Could perhaps get fun for compilers though - what if the program just throws away the return value? So some optimizer that doesn't know this subtlety sees this code and throws away the unused return value or just never emits the assignment, and the behaviour changes. I'm not sure I like this idea.

Good point. Then I prefer exceptions + return value (which may be ignored eventually - depending on strictness of retval/result count error checking).

Depending on the arch (32 vs 64 bits) one of these opcodes is suboptimal. With a new "L" (Long) register type the functionality could be handled transparently:

  $L0 = pio.'tell'()


Yes, but as you add more register types you get a combinatorial blow-up on various opcodes.

This depends on the implementation of 'opcodes'. With the current scheme any such extension isn't really implementable because of the combinatorial opcode explosion. I've written a (still internal) proposal that would prevent the combinatorial issue. It (or some similar thing) would be indeed necessary to even think about more register types like int8, int16, int32/int64 or float32.

My understanding was that "I" registers were native integers so you could get good performance, and you used a PMC if you wanted some guarantees about what size you were talking about.

In the long run, we certainly don't want to use PMCs for e.g. immplementing bytes (int8) or some such for performance reasons. 'long long' aka int64 is usually supported by compilers and has for sure by far better performanche than a BigInt PMC. Actually using 'int8' or 'float32' is usually only important, if you have huge arrays of these. That means that there's a very limited need for opcodes using these types, just some basic math mainly and array fetch/store. Or in other words: what is supported by the hardware CPU.


The register allocator would map 'L0' either to a pair (I0, I1) on 32 bit arch or just to 'I0' on 64 bit arch.
Yes, but surely it becomes somewhat more than just a mapping problem? For example, what do we do about:

add L0, L1, L2
mul L0, L1, L2

I don't see any problem with above code.

The register mapping rules would be something like:
- Lx occupies registers I(2x, 2x+1) - this is compile time,
that is 'L1' prevents 'I2' and 'I3' from being assigned by the register allocator
- the runtime mapping isn't portable due to endianess and sizeof types
  'L1' might be 'I1' on 64-bit arch or (I2,I3) or (I3,I2) on 32-bit arch
- if you write PASM, overlapping Ix/Ly may cause warnings or errors, but could be used in a non-portable way, if you know what you are doing on a specific platform.

Jonathan

leo

Reply via email to