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