# 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 inherits from C and C to provide predereferenced register addressing and C C 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 Returns C. =cut sub core_type { return 'PARROT_CGP_CORE'; } =item C The suffix is C<'_cgp'>. =cut sub suffix { return "_cgp"; } =item C The core prefix is C<'cgp_'>. =cut sub core_prefix { return "cgp_"; } =item C 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 . < $type */ # define opcode_to_prederef(i, op) \\ (opcode_t *) (op - CONTEXT(i->ctx)->pred_offset) END } =item C Transforms the C 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 Transforms the C 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 Transforms the C 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 < $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 =item C =item C =item C =item C =item C =back =cut 1; # Local Variables: # mode: cperl # cperl-indent-level: 4 # fill-column: 100 # End: # vim: expandtab shiftwidth=4: