I've pasted below a copy of one of the functions from the code generator
module.  A smaller section (with my first pass modifications for PASM)
is pasted below.  Modifications are on lines prefixed with ###.

A quick glance over the code suggests that only this module would need
to be updated to generate PASM or PIR instead of x86 assembly.  The
compiler also includes a runtime library--maybe this would be a good
candidate for the native call interface initially?  Any calls to the
runtime library could be handled with NCI so that converting the library
could be put off.

One other thought: I don't have a great understanding of PMCs, but I
think they're intelligent registers.  Why not create PMCs that simulate
the standard x86 registers?  My idea isn't to coerce people to use an
inefficient system, but it seems like a lot of compilers might be more
easily modified to generate PASM if compiler updaters didn't need to
consider why a given x86 register was being used in the generator
function.  That is, in my example, I don't know exactly why eax is used,
so I just substituted an integer register for eax, but if I could have
loaded an eax simulating PMC into P0 then I could have used set P0 with
more assurance that the code would do what I wanted.

        if (sy == NULL) {
                fprintf(o_src,"\txorl\t%%eax,%%eax\n");
###             fprintf(o_src,"\tset\t%%I0,%%0\n");
                return; 
        }
        if (sy->litflag) {
                int i, bSign=0;
                char cDigit;
                /* if it's an integer, compute it now, not at runtime!
*/
                value = 0;
                /* integer's name is just it's value in ascii */
                for (i=0; (cDigit = sy->name[i]); i++) {
                        if (cDigit=='}') {
                                cDigit = 0;
                        } else if (cDigit=='{') {
                                cDigit = 0;
                                bSign = 1;
                        } else if ((cDigit >= 'A') && (cDigit <= 'I')) {
                                cDigit -= 'A'-1;
                        } else if ((cDigit >= 'J') && (cDigit <= 'R')) {
                                cDigit -= 'J'-1;
                                bSign = 1;
                        } else {
                                cDigit -= '0';
                        }
                        value = value * 10 + cDigit;
                }
                if (bSign)
                        value = -value;
                fprintf(o_src,"\tmovl\t$%d,%%eax\n",(int)value);
###             fprintf(o_src,"\tset\t$%d,%%I0\n",(int)value);




void value_to_eax ( struct sym *sy ) {

        long long value;
        long value2;
        int stack_save;
#ifdef DEBUG_COMPILER
        if (sy) fprintf(o_src,"# value_to_eax %s\n",sy->name);
#endif
        if (sy == NULL) {
                fprintf(o_src,"\txorl\t%%eax,%%eax\n");
                return; 
        }
        if (sy->litflag) {
                int i, bSign=0;
                char cDigit;
                /* if it's an integer, compute it now, not at runtime!
*/
                value = 0;
                /* integer's name is just it's value in ascii */
                for (i=0; (cDigit = sy->name[i]); i++) {
                        if (cDigit=='}') {
                                cDigit = 0;
                        } else if (cDigit=='{') {
                                cDigit = 0;
                                bSign = 1;
                        } else if ((cDigit >= 'A') && (cDigit <= 'I')) {
                                cDigit -= 'A'-1;
                        } else if ((cDigit >= 'J') && (cDigit <= 'R')) {
                                cDigit -= 'J'-1;
                                bSign = 1;
                        } else {
                                cDigit -= '0';
                        }
                        value = value * 10 + cDigit;
                }
                if (bSign)
                        value = -value;
                fprintf(o_src,"\tmovl\t$%d,%%eax\n",(int)value);
                value2 = value >> 32;
                if ((value2!=0) && (value2!=-1))
        
fprintf(o_src,"\tmovl\t$%d,%%edx\n",(int)value2);
        } else if (sy->type == DTYPE_BININT || sy->type == DTYPE_FLOAT)
{ 
                /* load binary (comp) value directly */
                /* %eax doesn't hold greater than 4 bytes binary types
                        so we use %edx to get the most significant part
*/
                if (symlen(sy) > 4) {
                        fprintf(o_src,"\tleal\t%s,
%%eax\n",memrefat(sy));
                        fprintf(o_src,"\tmovl\t4(%%eax), %%edx\n");
                        fprintf(o_src,"\tmovl\t0(%%eax), %%eax\n");
                } else {
                        if (symlen(sy)>=4) {
                                switch (sy->sec_no) {
                                case SEC_CONST:
        
fprintf(o_src,"\tmovl\tc_base%d+%d, %%eax\n",
        
pgm_segment,sy->location);
                                        break;
                                case SEC_DATA:
        
fprintf(o_src,"\tmovl\tw_base%d+%d, %%eax\n",
        
pgm_segment,sy->location);
                                        break;
                                case SEC_STACK:
        
fprintf(o_src,"\tmovl\t-%d(%%ebp), %%eax\n",sy->location);
                                        break;
                                        break;
                                }
                        } else { 
                                switch (sy->sec_no) {
                                case SEC_CONST:
        
fprintf(o_src,"\tmovs%cl\tc_base%d+%d, %%eax\n",
        
varsize_ch(sy),pgm_segment,sy->location);
                                        break;
                                case SEC_DATA:
        
fprintf(o_src,"\tmovs%cl\tw_base%d+%d, %%eax\n",
        
varsize_ch(sy),pgm_segment,sy->location);
                                        break;
                                case SEC_STACK:
        
fprintf(o_src,"\tmovs%cl\t-%d(%%ebp), %%eax\n",
        
varsize_ch(sy),sy->location);
                                        break;
                                }
                        }
                }
        } else {
                fprintf(o_src,"#val to eax complex $c_base+%u, %%eax\n",
                        sy->descriptor);
                stack_save=stackframe_cnt;
                stackframe_cnt = 0;
                gen_loadvar( sy );
                fprintf(o_src,"#\tmovl\t$c_base+%u, %%eax\n",
                        sy->descriptor);
                asm_call("tcob_get_index");
                stackframe_cnt=stack_save;
        }
} 

-----Original Message-----
From: Dan Sugalski [mailto:[EMAIL PROTECTED] 
Sent: Wednesday, August 04, 2004 8:29 AM
To: [EMAIL PROTECTED]
Subject: If you're up for a real challenge

There's a GPL COBOL compiler, TinyCOBOL. 
http://tiny-cobol.sourceforge.net/ If anyone wants to take a shot at
giving it a PIR back end... (And yes, this would actually be very
useful. Imagine using Parrot as a way to migrate legacy COBOL apps to,
well, almost anything else. This would be a Good Thing for an awful lot
of folks)
-- 
                                Dan

--------------------------------------it's like this-------------------
Dan Sugalski                          even samurai
[EMAIL PROTECTED]                         have teddy bears and even
                                       teddy bears get drunk


Reply via email to