# Copyright (C) 2002, The Perl Foundation.
# $Id: CGP.pm 22368 2007-10-21 18:15:33Z rblasch $
=head1 NAME
Parrot::OpTrans::CGP - C Goto Predereferenced Transform
=head1 DESCRIPTION
C<Parrot::OpTrans::CGP> inherits from C<Parrot::OpTrans::CPrederef> and
C<Parrot::OpTrans::CGoto> to provide predereferenced register addressing
and C C<goto> run loop.
=head2 Instance Methods
=over 4
=cut
package Parrot::OpTrans::CGP;
use strict;
use warnings;
use base qw( Parrot::OpTrans::CPrederef Parrot::OpTrans::CGoto );
=item C<core_type()>
Returns C<PARROT_CGP_CORE>.
=cut
sub core_type {
return 'PARROT_CGP_CORE';
}
=item C<suffix()>
The suffix is C<'_cgp'>.
=cut
sub suffix {
return "_cgp";
}
=item C<core_prefix()>
The core prefix is C<'cgp_'>.
=cut
sub core_prefix {
return "cgp_";
}
=item C<defines()>
Returns the C C<#define> macros required by the ops.
=cut
sub defines {
my ( $self, $pred_def );
$self = shift;
$pred_def = $self->SUPER::defines();
my $type = __PACKAGE__;
return $pred_def . <<END;
/* defines - $0 -> $type */
# define opcode_to_prederef(i, op) \\
(opcode_t *) (op - CONTEXT(i->ctx)->pred_offset)
END
}
=item C<goto_address($address)>
Transforms the C<goto ADDRESS($address)> macro in an ops file into the
relevant C code.
=cut
sub goto_address {
my ( $self, $addr ) = @_;
#print STDERR "pbcc: map_ret_abs($addr)\n";
if ( $addr eq '0' ) {
return "return (0);";
}
else {
return "if ($addr == 0)
return 0;
_reg_base = (char*)interp->ctx.bp.regs_i;
goto **(void **)(cur_opcode = opcode_to_prederef(interp, $addr))";
}
}
=item C<goto_offset($offset)>
Transforms the C<goto OFFSET($offset)> macro in an ops file into the
relevant C code.
=cut
sub goto_offset {
my ( $self, $offset ) = @_;
return "goto **(void **)(cur_opcode += $offset)";
}
=item C<goto_pop()>
Transforms the C<goto POP()> macro in an ops file into the relevant C
code.
=cut
sub goto_pop {
my ($self) = @_;
return "goto **(void **)(cur_opcode = opcode_to_prederef(interp,
(opcode_t*)pop_dest(interp)))";
}
sub run_core_func_start {
my $type = __PACKAGE__;
return <<END_C;
/* run_core_func_start - $0 -> $type */
/* at least gcc 2.95.2 miscompiles set_args - %edi
* is used for the vtable call and _reg_base is clobbered
* # if 1191 := PARROT_OP_set_args_pc
* (gdb) disas l_ops_addr[1191] l_ops_addr[1192]
*/
#if defined(__GNUC__) && defined(I386) && defined(PARROT_CGP_REGS)
register opcode_t * cur_opcode __asm__ ("esi") = cur_op;
register char * _reg_base __asm__ ("edi");
#else
opcode_t *cur_opcode = cur_op;
char * _reg_base;
#endif
static void *const l_ops_addr[] = {
END_C
}
=back
=head1 SEE ALSO
=over 4
=item C<Parrot::OpTrans>
=item C<Parrot::OpTrans::C>
=item C<Parrot::OpTrans::CGoto>
=item C<Parrot::OpTrans::CPrederef>
=item C<Parrot::OpTrans::CSwitch>
=item C<Parrot::OpTrans::Compiled>
=back
=cut
1;
# Local Variables:
# mode: cperl
# cperl-indent-level: 4
# fill-column: 100
# End:
# vim: expandtab shiftwidth=4:
syntax highlighted by Code2HTML, v. 0.9.1