Mercurial > hg > CbC > old > device
changeset 89:917947ffeb7c
power pc version
author | kono |
---|---|
date | Thu, 06 Mar 2003 23:47:42 +0900 (2003-03-06) |
parents | 5c8553d7f984 |
children | 07e3113c3c13 |
files | Changes mc-code-ia32.c mc-code-powerpc.c mc-code.h mc-codegen.c mc-codegen.h mc.h test/basic.c |
diffstat | 8 files changed, 2122 insertions(+), 248 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Wed Mar 05 23:07:00 2003 +0900 +++ b/Changes Thu Mar 06 23:47:42 2003 +0900 @@ -1920,3 +1920,91 @@ FCONST �Ȥ���3���ǽ��褿�͡� (gcc �������ä������������ʤ�...) + goto.c ���̤�ʤ��ʤäƤ�ʡ� + +Thu Mar 6 14:00:13 JST 2003 + +PowerPC��non-lazy pointer�äơ��ơ��֥�����äƤ��Ƥ������ +�߹�������ʤΤ͡����ä��쥸�������ɤ߹�����顢������ +���Ѥ�������ɤ��餷�����Ȥ������Ȥϡ�code_gvar �˥���å��� +����ʤ��Ȥ����ʤ��������� RLU �Ǥ���? (���ɤ�����) +�Ǥ⡢�������ʤ��ȡ� + i = i+1; +�ʤ�ƤΤǤ⡢�Ҥɤ��ܤˤ��äƤ��ޤ��� + +local variable ��ǽ�� move mutilple register ����Ⱦ�� +�쥸�������ɤ߹��㤦�ߤ����͡�pointer �ǻ��Ȥ����� +�����Ǥ��礦���ɡ��ޤ���31�Ĥ⤢��С������������Ȥ� +���Ƥ⤢�ޤ�����ʤ��Τ����Τ�ʤ����ɡ� + +creg ���˲����ʤ������ˤ���С������Ϥޤ��ˤʤ��ʤ�? +(IA32�Ǥϡ������������) + +Thu Mar 6 20:50:24 JST 2003 + +��äѤꡢ�Ȥä�ʬ����register����¸����褦�ʥ����ɤ� +�ʤ�ߤ�����one path �ǡ�����뤿��ˤϡ� + .align 2 +_main0__: + lwz r5,2136(r1) + addi r1,r1,2128 + lmw r23,-36(r1) + mtlr r5 + blr + .align 2 + .globl _main0 +_main0: + mflr r2 + stmw r30,-8(r1) + stw r2,8(r1) + li r11,0 + stwu r1,-480(r1) + li r2,100 + mtctr r2 + mr r30,r3 + addi r0,r1,64 + mr r9,r0 + b _main0__; +�Ȥ����������ˤ��뤷���ʤ��͡� + +���Ȱ����ϡ��쥸�������Ѥ�褦�ˤʤäƤ���ߤ���������... r3 ����? + + mflr r31 + li r0,7 + stw r0,56(r1) + +������8�ĤޤǤϥ쥸�������Ѥ�ߤ����͡� +r3-r10 ���͡� + +��¤�Τ�register�˥��ԡ������Τ��������ơ�����¦�Ǽ���� +���ԡ���Ԥ��櫓���͡���Ƭ��return struct�ؤΥݥ�������Τ� +Ʊ���� + +(������memcpy���ޤ����...) + +��ư��������쥸�����Ϥ���������f1���顣(�ʤ�ۤ�) + +saveFP�äƤΤ�ƤӽФ��ơ� f24-f31��save����餷���� +(31-24)*8 �����ʤ���? + +pointer �Τ��Ȥ�ͤ���ȡ��쥸�������Ȥޤ�����Τ⤢�� +�櫓�����ɡ����ɥ쥹�����Ƥ���Ǵ֤˹礦��ʤ�? +����ʤɤϡ���Ȥ�Ȥ��������������(?)�ϳ��ݤ���Ȥ��ơ� + +���������դˡ�r3-r10 �ϰ����Ǥʤ���в����Ƥ��ɤ��櫓���� +(�����r9�Ȥ��ɤ��Ȥ��Ƥ���櫓��...) +�Ȥ������Ȥ���ʤ��ʤä��顢�������֤�����ɤ��櫓�͡� +(�äƤ��Ȥϡ�LVAR ���� REGISTER �äƤ���������������... +�ޤ������������ɤ�...) +����� get_register �����ɤ������� + +�ɤ��⡢r11-r12 ������ϼ�ͳ�˻ȤäƤ���餷���� + +�������äƤ�������Ǵؿ��ƽФ�����Ȥ��ϡ��ɤ������? +r30�ʤɤ˰�ư����Τ�? + +�ʤ��Τ�ɡ�in file call name �� out file call name �� +�㤦�ߤ����͡�(sigh...) ����ʤΤʤ�Ȥ��ʤ�Τ��ʤ��� +������stub �ˤ��Ƥ����ơ�.set �ǽ�����Ȥ�����⤢�뤱�ɡ� + +(�������˰����ǤϤǤ��ʤ���...)
--- a/mc-code-ia32.c Wed Mar 05 23:07:00 2003 +0900 +++ b/mc-code-ia32.c Thu Mar 06 23:47:42 2003 +0900 @@ -100,8 +100,7 @@ void code_leave(char *name); int lvar(int l); void global_table(void); - -char * fstore(int d); +int virtual(int real); char * fload(int d); int code_d1(double d); int code_d2(double d); @@ -163,6 +162,170 @@ return virtual(r+REG_ESI); } + + +int +get_register(void) +{ /* �Ȥ��Ƥ��ʤ��쥸������Ĵ�٤� */ + int i; + for(i=0;i<MAX_REGISTER;i++) { + if (! regs[i]) { /* �Ȥ��Ƥ��ʤ��ʤ� */ + regs[i]=1; /* ���Υ쥸������Ȥ����Ȥ������ */ + return i; /* ���ξ���ɽ���ֹ���֤� */ + } + } + return -1; /* �����Ƥ����꤬�ʤ��ʤ顢�����ɽ�� -1 ���֤� */ +} + +void +free_register(int i) { /* ����ʤ��ʤä��쥸�������� */ + regv[i]=regs[i]=0; +} + +int +register_full(void) +{ + int i; + for(i=0;i<MAX_REGISTER;i++) { + if (! regs[i]) { + return 0; + } + } + return 1; +} + +int +free_register_count(void) +{ + int i,count; + count = 0; + for(i=0;i<MAX_REGISTER;i++) { + if (! regs[i] && ! regv[i]) count++; + } + return count; +} + +void +free_all_register(void) +{ + int i; + for(i=0;i<MAX_REGISTER;i++) { + regs[i]=regv[i]=0; + } + creg = get_register(); + dreg = get_register(); + return; +} + +void +use_register_var(int i) { + regv[i]=1; +} + +void +set_register_var() { +} + +void +code_arg_register(int args) +{ + NMTBL *n; + if (args) { + /* process in reverse order */ + n = (NMTBL*)caddr(args); + if(n->sc==REGISTER) { + if ((n->dsp = get_register_var()) <0) { + error(-1); return; + } + use_register_var(n->dsp); /* it has now value in it */ + } + code_arg_register(cadr(args)); + } +} + + +void +register_usage(char *s) +{ + int i; + if (chk) return; + printf("# %d: %s:",lineno,s); + printf(" creg=%s dreg=%s ",register_name(creg,0),register_name(dreg,0)); + for(i=0;i<MAX_REGISTER;i++) { + printf("%d",regs[i]); + } + printf(":"); + for(i=0;i<MAX_REGISTER;i++) { + printf("%d",regv[i]); + } +#if 0 + printf(" regs_stack",register_name(creg,0),register_name(dreg,0)); + for(i=reg_sp;i>=0;i--) { + if(reg_stack[i]>=0) + printf(" %s",register_name(reg_stack[i],0)); + } +#endif + printf("\n"); +} + +void +gexpr_init(void) +{ + while(reg_sp > 0) { + free_register(reg_stack[--reg_sp]); + } + text_mode(); + gexpr_code_init(); + register_usage("gexpr_init"); +} + + +void +emit_init(void) +{ + int i; + for(i=0;i<MAX_REGISTER;i++) { regs[i]=0; regv[i]=0;rname[i]=i;} + free_all_register(); + reg_sp = 0; + text_mode(); +} + +int +virtual(int real) +{ + int real_v,i; + real_v = -1; + for(i=0;i<MAX_REGISTER;i++) { + if (rname[i]==real) { + real_v=i; + break; + } + } + return real_v; +} + +int +pop_register(void) +{ /* �쥸���������ͤ���Ф� */ + return reg_stack[--reg_sp]; +} + +int +stack_used(void) { + return reg_stack[--reg_sp]<0; +} + +void +emit_pop_free(int xreg) +{ + if (xreg==dreg) { + regv[dreg]=0; + } else if (xreg!=-1) { + free_register(xreg); + } +} + + int get_register_var(void) { @@ -374,7 +537,8 @@ code_cpostinc(int e1,int e2) { char *xrn; if (car(e2)==REGISTER) { - printf("\tmovl %s,%s\n",register_name(cadr(e2),0),register_name(creg,0)); + printf("\tmovbl (%s),%s\n",register_name(cadr(e2),0), + register_name(creg,0)); printf("\taddl $%d,%s\n",caddr(e1),register_name(cadr(e2),0)); return; } @@ -391,7 +555,8 @@ code_cpreinc(int e1,int e2) { if (car(e2)==REGISTER) { printf("\taddl $%d,%s\n",caddr(e1),register_name(cadr(e2),0)); - printf("\tmovl %s,%s\n",register_name(cadr(e2),0),register_name(creg,0)); + printf("\tmovsbl (%s),%s\n",register_name(cadr(e2),0), + register_name(creg,0)); return; } g_expr(e2); @@ -403,7 +568,8 @@ void code_cpostdec(int e1,int e2) { if (car(e2)==REGISTER) { - printf("\tmovl %s,%s\n",register_name(cadr(e2),0),register_name(creg,0)); + printf("\tmovsbl (%s),%s\n",register_name(cadr(e2),0), + register_name(creg,0)); printf("\tdecl %s\n",register_name(cadr(e2),0)); return; } @@ -417,8 +583,8 @@ code_cpredec(int e1,int e2) { if (car(e2)==REGISTER) { printf("\tdecl %s\n",register_name(cadr(e2),0)); - printf("\tmovl %s,%s\n",register_name(cadr(e2),0),register_name(creg,0)); - return; + printf("\tmovsbl (%s),%s\n",register_name(cadr(e2),0), + register_name(creg,0)); } g_expr(e2); emit_push(); @@ -894,7 +1060,7 @@ case ADD: printf("\taddl %s,%s\n",orn,crn); break; - case SUB: + case SUB: case CMP: printf("\tsubl %s,%s\n",orn,crn); break; case BAND: @@ -1023,9 +1189,9 @@ } void -rexpr(int e1, int l1, char *s) +rexpr(int e1, int l1, char *s,int t) { - g_expr(list3(SUB,cadr(e1),caddr(e1))); + g_expr(list3(CMP,cadr(e1),caddr(e1))); printf("\tj%s\t_%d\n",s,l1); } @@ -1472,8 +1638,7 @@ case DSUB: printf("\tfsubp %%st,%%st(1)\n"); break; case DDIV: printf("\tfdivp %%st,%%st(1)\n"); break; case DMUL: printf("\tfmulp %%st,%%st(1)\n"); break; - case DCOMP: - /* printf("\tfxch\t%%st(1)\n"); */ + case DCMP: printf("\tfucompp\n"); printf("\tfnstsw\t%%ax\n"); break; @@ -1517,7 +1682,7 @@ void drexpr(int e1, int e2,int l1, int op) { - g_expr(list3(DCOMP,e1,e2)); + g_expr(list3(DCMP,e1,e2)); switch(op) { case DOP+GE: printf("\ttestb\t$5,%%ah\n");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mc-code-powerpc.c Thu Mar 06 23:47:42 2003 +0900 @@ -0,0 +1,1733 @@ +/* Micro-C Code Generatation Part for Power PC (Mac OS X) */ +/* $Id$ */ + +#define EXTERN extern +#include "mc.h" +#include "mc-codegen.h" + +#define TEXT_EMIT_MODE 0 +#define DATA_EMIT_MODE 1 +#define RODATA_EMIT_MODE 2 + +static int output_mode = TEXT_EMIT_MODE; +static int data_alignment = 0; + +static int code_disp_label; +static int func_disp_label; + +/* + -16 -8 local2 <-- r30 + -12 -4 local1 + -8 8 arg3 + -4 4 arg2 + 0 0 arg1 + local2 -20 4 0 (r5) + local1 <-- -16 0 local variable 0 (r4) + -12 <- disp_offset %ebp + r30 (sp) -8 + 0 <- r1 + r1 (fp) 8 <- arg_offset + arg1 8 0 + arg2 12 4 + see enter/enter1/leave see code_enter + + r0 link register + r30 stack pointer + r31 0 + r1 frame pointer + */ +int arg_offset = 8; +int disp_offset = -12; +int func_disp_offset = -12; +int code_disp_offset = 0; +int jump_offset = 0; + +int size_of_int = 4; +int size_of_float = 4; +int size_of_double = 8; +int size_of_longlong = 8; +int endian = 0; +int MAX_REGISTER=30; /* PowerPC�Υ쥸������10�ĤޤǻȤ�*/ +int REAL_MAX_REGISTER=32; /* PowerPC�Υ쥸������32�Ȥ�������*/ +int MAX_REGISTGER_VAR=30-10; +int MAX_FREGISTER=30; + +#define REG_fp 1 +#define REG_sp 30 +#define REG_VAR_BASE 30 +#define REG_ARG_BASE 3 +#define REG_ARG_MAX 10 +#define FREG_ARG_BASE 1 +#define FREG_ARG_MAX 13 + +int reg_sp=REG_sp; + +static char *reg_name[] = { + "r0","r1","r2","r3","r4","r5","r6","r7","r8","r9", + "r10","r11","r12","r13","r14","r15","r16","r17","r18","r19", + "r20","r21","r22","r23","r24","r25","r26","r27","r28","r29", + "r30","r31" +}; + +static char *freg_name[] = { + "f0","f1","f2","f3","f4","f5","f6","f7","f8","f9", + "f10","f11","f12","f13","f14","f15","f16","f17","f18","f19", + "f20","f21","f22","f23","f24","f25","f26","f27","f28","f29", + "f30","f31" +}; + +static char *creg_name[] = { + "cr0","cr1","cr2","cr3","cr4","cr5","cr6","cr7" +}; + +void use_register(int virt, int real, int move); +void code_preinc(int e1,int e2) ; +void code_cmp_register(int e2) ; +void code_assign_gvar(int e2,int byte) ; +void tosop(int op,int oreg); +void edx_cleanup(); +void shift(char *op, int reg); +void ld_indexx(int byte, int n, int xreg); +void jmp(int l); +void local_table(void); +void text_mode(void); +void data_mode(char *name); + +char *register_name(int i,int byte); +int register_var(int r); +int get_register_var(void); +void emit_push(void); +int emit_pop(int type); +void code_crlvar(int e2); +void code_preinc(int e1,int e2); +void code_postinc(int e1,int e2); +void code_bool(int e1); +void string(int e1); +void emit_copy(int from,int to,int length,int offset,int value,int det); +int struct_push(int e4,int t); +void function(int e1); +void code_assop(int op,int byte); +int edx_setup(); +void code_opening(char *filename); +void code_closing(); +void code_leave(char *name); +int lvar(int l); +void global_table(void); + +char * fstore(int d); +char * fload(int d); +int code_d1(double d); +int code_d2(double d); + +void +code_init(void) +{ + arg_offset = 8; + func_disp_offset = -12; + disp_offset = -12; + size_of_int = 4; + endian = 1; +} + +#define register_name(i) reg_name[i] + +void +gexpr_code_init(void){ + regv[creg]=0; +} + +int virtual(int real); +char * fload(int d); +int code_d1(double d); +int code_d2(double d); + + +int +get_register(void) +{ /* �Ȥ��Ƥ��ʤ��쥸������Ĵ�٤� */ + int i; + for(i=0;i<MAX_REGISTER;i++) { + if (! regs[i]) { /* �Ȥ��Ƥ��ʤ��ʤ� */ + regs[i]=1; /* ���Υ쥸������Ȥ����Ȥ������ */ + return i; /* ���ξ���ɽ���ֹ���֤� */ + } + } + return -1; /* �����Ƥ����꤬�ʤ��ʤ顢�����ɽ�� -1 ���֤� */ +} + +void +free_register(int i) { /* ����ʤ��ʤä��쥸�������� */ + regv[i]=regs[i]=0; +} + +int +register_full(void) +{ + int i; + for(i=0;i<MAX_REGISTER;i++) { + if (! regs[i]) { + return 0; + } + } + return 1; +} + +int +free_register_count(void) +{ + int i,count; + count = 0; + for(i=0;i<MAX_REGISTER;i++) { + if (! regs[i] && ! regv[i]) count++; + } + return count; +} + +void +free_all_register(void) +{ + int i; + for(i=0;i<MAX_REGISTER;i++) { + regs[i]=regv[i]=0; + } + creg = get_register(); + dreg = get_register(); + return; +} + +void +use_register_var(int i) { + regv[i]=1; +} + +void +set_register_var() { +} + +void +code_arg_register(int args) +{ + NMTBL *n; + if (args) { + /* process in reverse order */ + n = (NMTBL*)caddr(args); + if(n->sc==REGISTER) { + if ((n->dsp = get_register_var()) <0) { + error(-1); return; + } + use_register_var(n->dsp); /* it has now value in it */ + } + code_arg_register(cadr(args)); + } +} + + +void +register_usage(char *s) +{ + int i; + if (chk) return; + printf("# %d: %s:",lineno,s); + printf(" creg=%s dreg=%s ",register_name(creg,0),register_name(dreg,0)); + for(i=0;i<MAX_REGISTER;i++) { + printf("%d",regs[i]); + } + printf(":"); + for(i=0;i<MAX_REGISTER;i++) { + printf("%d",regv[i]); + } +#if 0 + printf(" regs_stack",register_name(creg,0),register_name(dreg,0)); + for(i=reg_sp;i>=0;i--) { + if(reg_stack[i]>=0) + printf(" %s",register_name(reg_stack[i],0)); + } +#endif + printf("\n"); +} + +void +gexpr_init(void) +{ + while(reg_sp > 0) { + free_register(reg_stack[--reg_sp]); + } + text_mode(); + gexpr_code_init(); + register_usage("gexpr_init"); +} + + +void +emit_init(void) +{ + int i; + for(i=0;i<MAX_REGISTER;i++) { regs[i]=0; regv[i]=0;rname[i]=i;} + free_all_register(); + reg_sp = 0; + text_mode(); +} + +int +register_var(int r) { + return virtual(REG_VAR_BASE-r); +} + +int +get_register_var(void) +{ + int i; + for(i=0;i<MAX_REGISTGER_VAR;i++) { + if (REG_VAR_Base-i<=REG_ARG_MAX) + return -1; + if (! regs[REG_VAR_Base-i]) { /* �Ȥ��Ƥ��ʤ��ʤ� */ + regs[REG_VAR_Base-i]=1; /* ���Υ쥸������Ȥ����Ȥ������ */ + regv[REG_VAR_Base-i]=0; + return i; /* ���ξ���ɽ���ֹ���֤� */ + } + } + return -1; +} + +void +emit_push(void) +{ + int new_reg; + new_reg = get_register(); + if(new_reg<0) { /* �⤦�쥸�������ʤ� */ + if (reg_sp>=MAX_MAX) error(-1); + reg_stack[reg_sp++] = -1; + printf("\tstwu %s,-%d(%s)\n",register_name(creg), + size_of_int,register_name(reg_sp)); + /* creg is used soon, don't regv[creg]=0 */ + } else { + reg_stack[reg_sp++] = creg; /* push ���뤫���˥쥸������Ȥ� */ + creg = new_reg; + regv[creg]=1; + } +} + +int +emit_pop() +{ + int xreg; + if ((xreg=pop_register())==-1) { + xreg=get_register(); + if(!xreg) error(-1); + printf("\tlwz %s,(%s)\n",register_name(xreg),register_name(reg_sp); + printf("\taddis %s,%s,%d\n", + register_name(reg_sp),register_name(reg_sp),size_of_int; + regv[xreg]=1; + } + return xreg; +} + +static char *code_base; + +#define MAX_PTR_CACHE 10 + +int ptr_cache=0; + +int +clear_ptr_cache() +{ + int ptcptr=ptr_cache; + while(ptcptr) { + if(car(ptcptr)) + free_register(caddr(ptcptr)); + car(ptcptr)=0; + caddr(ptcptr)=0; + ptcptr=cadr(ptcptr); + } +} + +int +init_ptr_cache() +{ + int i; + for(i=0;i<MAX_PTR_CACHE;i++) { + ptr_cache=glist3(0,ptr_cache,0); + } +} + + +int +get_ptr_cache(char *name) +{ + int r; + int ptcptr=ptr_cache; + int cache; + int i = 0; + int g = (int)name; + int p,p1; + + while(ptcptr) { + if(car(ptcptr)==g) return caddr(ptcptr); + p1=p; p=ptcptr; + ptcptr=cadr(ptcptr); + } + cadr(p1)=0; /* remove the last one */ + cadr(p) = ptr_cache; /* connect current queue to the last one */ + ptr_cache = p; /* now the last one is the top */ + if (!caddr(p)) { + if((r=get_register())) { + caddr(p)=r; + else + r=creg; + } + rrn = register_name(r); + printf("\taddis %s,r31,ha16(L_%s$non_lazy_ptr-%s)\n", + rrn,(char *)g,code_base); + printf("\tlzw %s,lo16(L_%s$non_lazy_ptr-%s)(%s)\n", + rrn,(char *)g,code_base,rrn); + return r; +} + +void +code_gvar(int e1) { + int r; + r = get_ptr_cache((char*)caddr(e1)); + if(r!=creg) + printf("\tmr %s,%s\n",register_name(creg),register_name(r)); + return; +} + +void +code_rgvar(int e1) { + printf("\tlwz %s,(%s)\n",register_name(creg), + register_name(get_ptr_cache((char*)caddr(e1)))); +} + +void +code_crgvar(e1){ + printf("\tlbz %s,(%s)\n",register_name(creg), + register_name(get_ptr_cache((char*)caddr(e1)))); + printf("\textsb %s,%s\n",register_name(creg),register_name(creg)); +} + +void +code_lvar(int e2) { + printf("\tla %d(r1),%s\n",e2,register_name(creg)); +} + + +void +code_register(int e2) { + printf("\tmr %s,%s\n",register_name(creg),register_name(e2)); +} + + +void +code_rlvar(int e2) { + printf("\tlwz %d(r1),%s\n",e2,register_name(creg)); +} + + +void +code_crlvar(int e2) { + printf("\tlbz %d(r1),%s\n",e2,register_name(creg)); + printf("\textsb %s,%s\n",register_name(creg),register_name(creg)); +} + + +void +code_fname(char *e2) { + int r; + r = get_ptr_cache(e2); + if(r!=creg) + printf("\tmr %s,%s\n",register_name(creg),register_name(e2)); + return; +} + + +void +code_const(int e2) { + char *crn = register_name(creg); + if (-32768<e2&&e2<32768) + printf("\tli %s,%d\n",crn,e2); + else { + printf("\tlis %s,ha16(%d)\n",crn,e2); + printf("\taddi %s,%s,lo16(%d)\n",crn,crn,e2); + } +} + + +void +code_neg() { + printf("\tneg %s,%s\n", register_name(creg), register_name(creg); +} + + +void +code_not() { + printf("\tnor %s,%s,%s\n", + register_name(creg), register_name(creg),register_name(creg)); +} + + +void +code_lnot() { + printf("\tsubfic r0,%s,0\n", register_name(creg)); + printf("\tadde %s,r0,%s\n", register_name(creg),register_name(creg)); +} + +void +code_preinc(int e1,int e2) { + char *xrn,*drn; + int i,dreg; + if (car(e2)==REGISTER) { + printf("\taddi %s,%s,%d\n", register_name(cadr(e2))); + printf("\tmr %s,%s\n",register_name(cadr(creg)),register_name(e2)); + return; + } + g_expr(e2); + xrn = register_name(creg); + dreg=get_register(); if (!dreg) error(-1); + drn = register_name(dreg); + printf("\tlwz %s,(%s)\n",drn,xrn); + printf("\taddi %s,%s,%d\n",drn,drn,caddr(e1)); + printf("\tstw %s,(%s)\n",drn,xrn); + i=creg;creg=dreg;dreg=i; + regv[creg=1]; + free_register(dreg); +} + + +void +code_postinc(int e1,int e2) { + char *xrn,*crn,*nrn; + int dreg,nreg; + if (car(e2)==REGISTER) { + printf("\tmr %s,%s\n",register_name(creg),register_name(cadr(e2))); + printf("\taddi %s,%s,%d\n", + register_name(cadr(e2)),register_name(cadr(e2))); + return; + } + g_expr(e2); + dreg=get_register(); if (!dreg) error(-1); + xrn = register_name(dreg); + nreg=get_register(); if (!nreg) error(-1); + nrn = register_name(nreg); + printf("\tlwz %s,(%s)\n",xrn,crn); + printf("\taddi %s,%s,%d\n",nrn,xrn,caddr(e1)); + printf("\tstw %s,(%s)\n",nrn,crn); + i=creg;creg=dreg;dreg=i; + free_register(nreg); + free_register(dreg); + regv[creg]=1; +} + + +void +code_cpostinc(int e1,int e2) { + char *xrn,*crn; + int i,nreg,dreg; + if (car(e2)==REGISTER) { + printf("\tlbz %s,(%s)\n",register_name(creg),register_name(cadr(e2))); + printf("\textsb %s,%s\n",register_name(creg),register_name(creg)); + printf("\taddi %s,%s,%d\n", + register_name(cadr(e2)),register_name(cadr(e2)),caddr(e1)); + return; + } + g_expr(e2); + crn = register_name(creg); + dreg=get_register(); if (!dreg) error(-1); + xrn = register_name(dreg); + nreg=get_register(); if (!nreg) error(-1); + nrn = register_name(nreg); + printf("\tlwz %s,(%s)\n",xrn,crn); + printf("\tlbz %s,(%s)\n",nrn,xrn); + printf("\textsb %s,%s\n",nrn,nrn); + printf("\taddi %s,%s,%d\n", xrn,xrn); + printf("\tstw %s,(%s)\n",xrn,crn); + i=creg;creg=nreg;nreg=i; + free_register(nreg); + free_register(dreg); + regv[creg]=1; +} + + +void +code_cpreinc(int e1,int e2) { + char *xrn,*crn; + int i,nreg,dreg; + if (car(e2)==REGISTER) { + printf("\tlbzu %s,%d(%s)\n",register_name(creg),caddr(e1),register_name(cadr(e2))); + printf("\textsb %s,%s\n",register_name(creg),register_name(creg)); + return; + } + g_expr(e2); + crn = register_name(creg); + dreg=get_register(); if (!dreg) error(-1); + xrn = register_name(dreg); + nreg=get_register(); if (!nreg) error(-1); + nrn = register_name(nreg); + printf("\tlwz %s,(%s)\n",xrn,crn); + printf("\tlbzu %s,%d(%s)\n",nrn,caddr(e1),xrn); + printf("\tstw %s,(%s)\n",xrn,crn); + printf("\textsb %s,%s\n",nrn,nrn); + i=creg;creg=nreg;nreg=i; + free_register(nreg); + free_register(dreg); + regv[creg]=1; +} + + +void +code_cpostdec(int e1,int e2) { + char *xrn,*crn; + int i,nreg,dreg; + if (car(e2)==REGISTER) { + crn=register_name(creg); + xrn=register_name(cadr(e2)); + printf("\tlbz %s,(%s)\n",crn,xrn); + printf("\taddi %s,%s,%d\n",xrn,xrn,caddr(e1)); + printf("\textsb %s,%s\n",crn,crn); + return; + } + g_expr(e2); + crn = register_name(creg); + dreg=get_register(); if (!dreg) error(-1); + xrn = register_name(dreg); + nreg=get_register(); if (!nreg) error(-1); + nrn = register_name(nreg); + printf("\tlwz %s,(%s)\n",xrn,crn); + printf("\tlbz %s,(%s)\n",nrn,xrn); + printf("\taddi %s,%s,%d\n",xrn,xrn,caddr(e1)); + printf("\tstw %s,(%s)\n",xrn,crn); + printf("\textsb %s,%s\n",nrn,nrn); + i=creg;creg=nreg;nreg=i; + free_register(nreg); + free_register(dreg); + regv[creg]=1; +} + + +void +code_cpredec(int e1,int e2) { + char *xrn,*crn; + int i,nreg,dreg; + if (car(e2)==REGISTER) { + crn=register_name(creg); + xrn=register_name(cadr(e2)); + printf("\tlbzu %s,%d(%s)\n",crn,caddr(e1),xrn); + printf("\textsb %s,%s\n",crn,crn); + return; + } + g_expr(e2); + crn = register_name(creg); + dreg=get_register(); if (!dreg) error(-1); + xrn = register_name(dreg); + nreg=get_register(); if (!nreg) error(-1); + nrn = register_name(nreg); + printf("\tlwz %s,(%s)\n",xrn,crn); + printf("\tlbzu %s,%d(%s)\n",nrn,caddr(e1),xrn); + printf("\tstw %s,(%s)\n",xrn,crn); + printf("\textsb %s,%s\n",nrn,nrn); + i=creg;creg=nreg;nreg=i; + free_register(nreg); + free_register(dreg); + regv[creg]=1; +} + + +void +code_return() { + int r; + printf("\taddis %s,r31,ha16(_%d-%s)\n",crn,retcont,code_base); + printf("\tla %s,lo16(_%d-%s)(%s)\n",crn,retcont,code_base,crn); +} + + +void +code_environment() { + printf("\tmr %s,r1\n",register_name(creg)); +} + + +void +code_bool(int e1) { + char *xrn; + int e2,e3; + b_expr(e1,1,e2=fwdlabel(),1); /* including > < ... */ + xrn = register_name(creg); + printf("\tli %s,0\n",xrn); + jmp(e3=fwdlabel()); + fwddef(e2); + printf("\tli %s,1\n",xrn); + fwddef(e3); +} + +char * +code_gt(int cond) { + return (cond?"gt":"le"); +} + +char * +code_ugt(int cond) { + return (cond?"gt":"le"); +} + +char * +code_ge(int cond) { + return (cond?"ge":"lt"); +} + +char * +code_uge(int cond) { + return (cond?"ge":"lt"); +} + +char * +code_eq(int cond) { + return (cond?"eq":"ne"); +} + +void +code_cmp_crgvar(int e1) { + int r; + char *crn = register_name(creg); + r = get_ptr_cache((char *)caddr(e1)); + printf("\tlbz %s,(%s)\n",crn,register_name(r)); + printf("\tcmpwi cr0,%s,0\n",crn); +} + + +void +code_cmp_crlvar(int e1) { + char *crn = register_name(creg); + printf("\tlbz %s,%d(r1)\n",crn,e1); + printf("\tcmpwi cr0,%s,0\n",crn); +} + + +void +code_cmp_rgvar(int e1) { + int r; + char *crn = register_name(creg); + r = get_ptr_cache((char *)caddr(e1)); + printf("\tlwz %s,(%s)\n",crn,register_name(r)); + code_cmp_register(creg); +} + + +void +code_cmp_rlvar(int e1) { + char *crn = register_name(creg); + printf("\tlwz %s,%d(r1)\n",crn,e1); + code_cmp_register(creg); +} + + +void +code_cmp_register(int e2) { + printf("\tcmpwi cr0,%s,0\n",register_name(e2)); +} + + +void +ascii(char *s) +{ + printf("\t.ascii \""); + while(*s) { + if (*s=='\n') + printf("%cn",92); + else if (*s<' ') + printf("%c%03o",92,*s); + else if (*s==34) + printf("%c%c",92,34); + else + printf("%c",*s); + s++; + } + printf("\\0%c\n",34); +} + +void +string(int e1) +{ + char *s; + int i,lb; + + s=(char *)cadr(e1); + printf(".data\t.cstring\n\t.align 2\n"); + lb=fwdlabel(); + printf("_%d:\n",lb); + ascii(s); + if (output_mode==TEXT_EMIT_MODE) { + printf(".text\n"); + } else { + text_mode(); + } + printf("\taddis %s,r31,ha16(_%d-%s)\n",crn,lb,code_base); + printf("\tla %s,lo16(_%d-%s)(%s)\n",crn,lb,code_base,crn); +} + +#define MAX_COPY_LEN 20 + +void +emit_copy(int from,int to,int length,int offset,int value,int det) +{ + char *frn = register_name(from); + char *trn = register_name(to); + char *drn; + int fix = 0; + char *bcopy = "bcopy"; + int dreg = get_regiter(); if (!dreg) error(-1); + drn = register_name(dreg); + + /* length <0 means upward direction copy */ + switch (length) { + case 0: break; + case 1: case -1: + printf("\tlbz %s,%d(%s)\n",drn,offset,frn); + printf("\tstb %s,%d(%s)\n",drn,offset,trn); + break; + case 2: case -2: + printf("\tlhz %s,%d(%s)\n",drn,offset,frn); + printf("\tsth %s,%d(%s)\n",drn,offset,trn); + break; + case 4: case -4: + printf("\tlwz %s,%d(%s)\n",drn,offset,frn); + printf("\tstw %s,%d(%s)\n",drn,offset,trn); + break; + default: + if (-MAX_COPY_LEN<length && length <0) { + for(;length<=4;length+=4,offset-=4) + emit_copy(from,to,4,offset,0,det); + for(;length<=2;length+=2,offset-=2) + emit_copy(from,to,2,offset,0,det); + if(length>0) + emit_copy(from,to,length,offset,0,det); + break; + } else if (length <=MAX_COPY_LEN) { + for(;length>=4;length-=4,offset+=4) + emit_copy(from,to,4,offset,0,det); + for(;length>=2;length-=2,offset+=2) + emit_copy(from,to,2,offset,0,det); + if(length>0) + emit_copy(from,to,length,offset,0,det); + break; + } + if (det) { + printf("\tli r5,%d\n",length); + printf("\tmr r4,%s\n",trn); + printf("\tmr r3,%s\n",frn); + printf("\tbl L_%s$stub\n",bcopy); + regist_extern_function(bcopy); + break; + } + } + if (value) { + /* creg must point top of the destination data */ + /* this code is necessary for the value of assignment or function call */ + /* otherwise we don't need this */ + if (fix) printf("\taddi %s,%s,%d\n",trn,trn,fix); + if(creg!=to) { + free_register(creg); creg=to; + } + } + free_register(dreg); + regv[from]=regv[to]=regv[dreg]=0; + regv[creg]=1; +} + +int +struct_push(int e4,int t) +{ + int length,save,count; + int dreg; char *drn,*crn,*srn; + g_expr(e4); + length=size(t); + if(length%size_of_int) { + length += size_of_int - (length%size_of_int); + } + dreg = get_regiter(); if (!dreg) error(-1); + drn = register_name(dreg); + crn = register_name(dreg); + srn = register_name(reg_sp); + for(count=0;length<MAX_COPY_LEN;count++,length-=size_of_int) { + if (length==0) { + free_register(dreg); + return count; + } else { + printf("\tlwz %s,%d(%s)\n",drn,length-size_of_int,crn); + printf("\tstwu %s,%d(%s)\n",drn,-size_of_int,srn); + } + } + printf("\taddis %s,%s,ha16(%d)\n",srn,,srn,length); + printf("\taddi %s,%s,lo16(%d)\n",srn,,srn,length); + /* downward direction copy */ + printf("\tmr %s,%s\n",drn,srn); + emit_copy(creg,dreg,length,0,0,1); + /* we have value in creg, it may be changed */ + if (dreg!=creg) free_register(dreg); + return length/size_of_int; +} + +int +arg_offset(int arg) +{ +} + +void +function(int e1) +{ + int e2,e3,e4,e5,nargs,t; + int reg_arg,freg_arg; + NMTBL *n; + e2 = cadr(e1); + nargs = 0; + reg_arg = REG_ARG_BASE; + freg_arg = FREG_ARG_BASE; + for (e3 = caddr(e1); e3; e3 = cadr(e3)) { + t=caddr(e3); + n=(NMTBL *)(e5=(cadr(e4 = car(e3)))); + if(scalar(t)) { + g_expr(e4); + if (reg_arg<REG_ARG_MAX) + printf("\tmr %s,%s\n",register_name(reg_arg), + register_name(creg)); + else { + printf("\tstw %s,%d(r1)\n",register_name(creg), + arg_offset(nargs)); + } + nargs ++ ; reg_arg++; + } else if (t==DOUBLE||t==FLOAT) { + g_expr(e4); + nargs += size_of_double/size_of_int; + if (fregv[freg_arg]) + save_freg(freg_arg); + fregv[freg_arg]=1; + if (freg_arg<FREG_ARG_MAX) + printf("\tmr %s,%s\n",register_name(reg_arg++), + register_name(freg)); + else if(t==DOUBLE) { + printf("\tstfd %s,%d(r1)\n",register_name(freg), + arg_offset(nargs)); + nargs+=size_of_double/size_of_int; + } else { + printf("\tstfs %s,%d(r1)\n",register_name(freg), + arg_offset(nargs)); + nargs+=size_of_float/size_of_int; + } + freg_arg++; + continue; + } else if (car(t)==STRUCT||car(t)==UNION) { + nargs += struct_push(e4,t); + continue; + } else { + error(TYERR); + } + ++nargs; + } + if (car(e2) == FNAME) { + n=(NMTBL *)cadr(e2); + regv[creg]=0; + } else { + g_expr(e2); + regv[creg]=1; + } + + if (car(e2) == FNAME) { + printf("\tbl\tL_%s$stub\n",n->nm); + } else { + jmp=get_tmp_register(); + jrn = register_name(jmp); + printf("\tmr %s,%s\n",jrn,crn); + printf("\tmtctr %s\n",jrn); + printf("\tbctrl\n"); + free_register(jmp); + } + regv[creg]=1; +} + +void +code_frame_pointer(int e3) { + printf("\tmovl %s,r1\n",register_name(e3,0)); +} + + +void +code_fix_frame_pointer(int disp_offset) { + printf("\tla r1,%d(r1)\n",disp_offset); +} + + +void +code_jmp(char *s) { + printf("\tb L_%s$stub\n",s); +} + + +void +code_indirect_jmp(int e2) { + printf("\tmtctr %s\n",register_name(e2)); + printf("\tbctr\n"); +} + +void +rindirect(int e1) /* *(p +5 ) */ +{ + char *op; + int e2,e3,byte; + e3 = cadr(e2 = cadr(e1)); + g_expr(e2); + switch (car(e1)) { + case FRINDIRECT: case DRINDIRECT: + printf("\t%s (%s)\n",fload(car(e1)==DRINDIRECT),register_name(creg)); + break; + case CRINDIRECT: case RINDIRECT: + op = ((byte = (car(e1) == CRINDIRECT)) ? "movsbl" : "movl"); + printf("\t%s (%s),%s\n",op,register_name(creg),register_name(creg)); + } +} + + +void +code_assign_gvar(int e2,int byte) { + if (byte) use_data_reg(creg,1); + printf("\t%s %s,%s\n",move(byte),register_name(creg,byte),(char *)caddr(e2)); +} + +void +code_assign_lvar(int e2,int byte) { + if (byte) use_data_reg(creg,1); + printf("\t%s %s,%d(%%ebp)\n",move(byte),register_name(creg,byte),e2); +} + +void +code_assign_register(int e2,int byte) { + printf("\tmovl %s,%s\n",register_name(creg),register_name(e2,0)); +} + +void +code_assign(int e2,int byte) { + printf("\t%s %s,(%s)\n",move(byte),register_name(creg,byte),register_name(e2,0)); +} + + +void +code_register_assop(int e2,int op,int byte) { + int reg; + int xreg = creg; + creg = reg = e2; + tosop(op,xreg); + creg = xreg; + printf("\tmovl %s,%s\n",register_name(reg,0),register_name(creg)); +} + + +void +code_assop(int op,int byte) { + char *xrn; + int xreg; + int edx = edx_setup(); + xrn = register_name(xreg = emit_pop(0),0); /* pop e3 value */ + regv[xreg]=regs[xreg]=1; + printf("\tmovl %s,%s # assop \n",register_name(creg),register_name(edx,0)); + regv[edx]=1; + ld_indexx(byte,0,edx); + tosop(op,xreg); + printf("\t%s %s,(%s)\n",byte ? "movb" : "movl",register_name(creg,byte),register_name(edx,0)); + edx_cleanup(); + emit_pop_free(xreg); +} + + +void +tosop(int op,int oreg) +{ + int dx; + char *orn,*crn; + + switch(op) { + case LSHIFT: + case ULSHIFT: + shift("sall",oreg); + return; + case RSHIFT: + shift("sarl",oreg); + return; + case URSHIFT: + shift("shrl",oreg); + return; + } + if(oreg==-1) { + printf("\tpopl %s\n",register_name(dreg,0)); + oreg = dreg; + regv[dreg]=1; + } + regv[oreg]=1; regs[oreg]=1; + orn = register_name(oreg,0); + crn = register_name(creg); + switch(op) { + case ADD: + printf("\taddl %s,%s\n",orn,crn); + break; + case SUB: + printf("\tsubl %s,%s\n",orn,crn); + break; + case BAND: + printf("\tandl %s,%s\n",orn,crn); + break; + case EOR: + printf("\txorl %s,%s\n",orn,crn); + break; + case BOR: + printf("\torl %s,%s\n",orn,crn); + break; + case MUL: + case UMUL: + printf("\t%s %s,%s\n","imull",orn,crn); + break; + case DIV: + case UDIV: + use_register(creg,REG_EAX,1); + edx_setup(); + orn = register_name(oreg,0); + if (op==DIV) + printf("\tcltd\n\tdivl %s\n",orn); + else + printf("\txor %%edx,%%edx\n\tidivl %s\n",orn); + edx_cleanup(); + break; + case MOD: + case UMOD: + use_register(creg,REG_EAX,1); + edx_setup(); + orn = register_name(oreg,0); + if (op==DIV) + printf("\tcltd\n\tdivl %s\n",orn); + else + printf("\txor %%edx,%%edx\n\tidivl %s\n",orn); + dx = virtual(REG_EDX); + if (dx!=creg) { + rname[dx]=rname[creg]; + rname[creg]=REG_EDX; + } + edx_cleanup(); + break; + } + if (oreg!=dreg&&oreg>=0) + free_register(oreg); +} + +static int edx_stack=0; + +int +edx_setup() +{ + int edx_save; + /* make real EDX register empty */ + if (free_register_count()<1) { + for(edx_save = 0;edx_save==dreg||edx_save==creg;edx_save++); + printf("\tpushl %s\n",register_name(edx_save,0)); + edx_stack = list3(edx_save,edx_stack,0); + } else { + edx_save = get_register(); + edx_stack = list3(edx_save,edx_stack,1); + } + regv[edx_save]=0; + use_register(edx_save,REG_EDX,0); + return edx_save; +} + + +void +edx_cleanup() +{ + if (caddr(edx_stack)==0) { + printf("\tpopl %s\n",register_name(car(edx_stack),0)); + } else + free_register(car(edx_stack)); + edx_stack = cadr(edx_stack); +} + +void +shift(char *op, int reg) +{ + if (reg>=0) { + use_register(reg,REG_ECX,1); + } else { + use_register(dreg,REG_ECX,0); + printf("\tpopl %%ecx\n"); + } + printf("\t%s %%cl,%s\n",op,register_name(creg)); +} + +void +ld_indexx(int byte, int n, int xreg) +{ + char *op; + + op = byte ? "movsbl" : "movl"; + if (n) + printf("\t%s %d(%s),%s\n",op,n,register_name(xreg,0),register_name(creg,byte)); + else + printf("\t%s (%s),%s\n",op,register_name(xreg,0),register_name(creg,byte)); +} + +void +cmpdimm(int e, int csreg) +{ + /* used in dosiwtch() */ + if(chk) return; + use_register(creg,csreg,0); + printf("\tcmpl $%d,%s\n",e,register_name(creg)); +} + +void +code_opening(char *filename) +{ + printf("\t.file \"%s\"\n",filename); + printf("\t.version\t\"01.01\"\n"); + /* printf("gcc2_compiled.:\n"); */ + printf(".text\n"); +} + +void +code_closing() +{ + global_table(); + printf("\t.ident \"Micro-C compiled\"\n"); +} + +void +rexpr(int e1, int l1, char *s) +{ + g_expr(list3(SUB,cadr(e1),caddr(e1))); + printf("\tj%s\t_%d\n",s,l1); +} + + +void +jcond(int l, char cond) +{ + if (chk) return; + printf("\tj%s\t_%d\n",cond?"ne":"e",l); +} + +void +jmp(int l) +{ + control=0; + if (chk) return; + printf("\tjmp\t_%d\n",l); + /* align? */ + /* + this is not allowed because of ? operator + regv[creg]=regv[dreg]=0; + use_register(creg,REG_EAX,0); + use_register(dreg,REG_EBX,0); + */ +} + +void +gen_comment(char *s) +{ + if (chk) return; + printf("## %s",s); +} + + +void +code_enter(char *name) +{ + printf("\t.align 4\n"); + if (stmode!=STATIC) + printf(".globl %s\n",name); + printf("\t.type\t%s,@function\n",name); + printf("%s:\n",name); +} + + +void +code_enter1(int args) +{ + code_disp_label=fwdlabel(); + printf("\tlea _%d(%%ebp),%%esp\n",code_disp_label); + + printf("## args %d disp %d code_arg_offset=%d code_disp_offset=%d\n",args,disp,code_arg_offset,code_disp_offset); +} + +void +code_leave(char *name) +{ + disp&= -size_of_int; + printf("\t.set _%d,%d\n",code_disp_label,disp+code_disp_offset); + printf("_%d:\n",labelno); + printf("\t.size\t%s,_%d-%s\n",name,labelno,name); + local_table(); + labelno++; + free_all_register(); +} + +void +enter(char *name) +{ + printf("\t.align 2\n"); + if (stmode!=STATIC) + printf(".globl %s\n",name); + printf("%s:\n",name); + printf("\t.type\t%s,@function\n",name); + printf("\tpushl %%ebp\n"); + printf("\tmovl %%esp,%%ebp\n"); + printf("\tpushl %%ebx\n"); + printf("\tpushl %%esi\n"); + printf("\tpushl %%edi\n"); +} + +void +enter1() +{ + func_disp_label=fwdlabel(); + printf("\tlea _%d(%%ebp),%%esp\n",func_disp_label); + /* if(disp) printf("\tsubl $%d,%%esp\n",-disp); */ +} + +void +leave(int control, char *name) +{ + if (control) + use_register(creg,REG_EAX,1); + if (retcont) { + if (control) + jmp(retlabel); + fwddef(retcont); + use_register(creg,REG_EAX,0); + printf("\tmovl %s,%s\n",reg_name[REG_ESI],register_name(creg)); + /* printf("\tleave\n"); */ + } + fwddef(retlabel); + /* use_register(creg,REG_EAX,0); too late */ + /* if(disp) printf("\taddl $%d,%%esp\n",-disp); */ + disp &= -size_of_int; + + printf("\tlea %d(%%ebp),%%esp\n",disp_offset); + printf("\tpopl %%edi\n"); + printf("\tpopl %%esi\n"); + printf("\tpopl %%ebx\n"); + printf("\tleave\n"); + printf("\tret\n"); + printf("\t.set _%d,%d\n",func_disp_label,disp+disp_offset); + printf("_%d:\n",labelno); + printf("\t.size\t%s,_%d-%s\n",name,labelno,name); + local_table(); + labelno++; + free_all_register(); +} + + +void +code_set_fixed_creg(int mode) { + use_register(creg,REG_EAX,mode); +} + +void +gen_gdecl(char *n, int gpc) +{ + /* + if (stmode!=STATIC) + printf(".globl %s\n",n); + */ +} + +void +align(int t) +{ + if (t!=CHAR) { + if (data_alignment & 1) + printf("\t.align 2\n"); + data_alignment = 0; + } +} + +void +emit_data(int e, int t, NMTBL *n) +{ + int l; + double d; + float f; + char *name; + name = n->nm; + if(mode!=GDECL) { + error(-1); return; + } + if (chk) return; + if (n->dsp != -1) { + n->dsp = -1; /* initiallized flag */ + printf(".globl\t%s\n",name); + data_mode(name); + align(t); + printf("%s:\n",name); + } else { + data_mode(0); + } + if(car(e)==CONST) { + if (t==CHAR) { + printf("\t.byte %d\n",cadr(e)); + if (data_alignment>0) + data_alignment++; + gpc += 1; + } else if (t==SHORT) { + printf("\t.word %d\n",cadr(e)); + if (data_alignment>0) data_alignment++; + gpc += 2; + } else { + printf("\t.long %d\n",cadr(e)); + gpc += size_of_int; + } + } else if(t==DOUBLE) { + d = dcadr(e); + printf("\t.long\t0x%x,0x%x\n",code_d1(d),code_d2(d)); + } else if(t==FLOAT) { + f = dcadr(e); + printf("\t.long\t0x%x\n",*(int *)&f); + } else if(t!=CHAR) { + gpc += size_of_int; + if(car(e)==ADDRESS&&car(cadr(e))==GVAR) { + printf("\t.long %s\n",(char *)caddr(cadr(e))); + } else if(car(e)==FNAME) { + printf("\t.long %s\n",((NMTBL *)cadr(e))->nm); + } else if(car(e)==STRING) { + if (car(n->ty)!=ARRAY || cadr(n->ty)!=CHAR) { + l = fwdlabel(); + printf("\t.long _%d\n",l); + printf(".section\t.rodata\n"); + printf("_%d:\n",l); + output_mode = RODATA_EMIT_MODE; + } + ascii((char *)cadr(e)); + } else error(TYERR); + } +} + +void +emit_data_closing(NMTBL *n) +{ + int lb; + if (chk) return; + if (mode==GDECL) { + data_mode(0); + lb=fwdlabel(); + printf("_%d:\n",lb); + printf("\t.size\t%s,_%d-%s\n",n->nm,lb,n->nm); + } +} + +void +global_table(void) +{ + NMTBL *n; + int init; + init=0; + for(n=ntable;n < &ntable[GSYMS];n++) { + if (n->sc == GVAR && n->dsp != -1) { + /* n->dsp = -1 means initialized global */ + if (init==0) { + data_mode(0); + init=1; + } + printf(".comm %s,%d\n",n->nm,size(n->ty)); + } + } +} + +void +local_table(void) +{ + NMTBL *n; + int init; + init=0; + /* static local variables */ + for(n=ntable+GSYMS;n < &ntable[GSYMS+LSYMS];n++) { + if (n->sc == GVAR) { + if (init==0) { + data_mode(0); + init=1; + } + printf(".lcomm %s,%d\n",n->nm,size(n->ty)); + } + } +} + +void +text_mode(void) +{ + if (output_mode!=TEXT_EMIT_MODE) { + printf(".text\n"); + printf("\t.align 2\n"); + output_mode = TEXT_EMIT_MODE; + } +} + +void +data_mode(char *name) +{ + if (output_mode!=DATA_EMIT_MODE) { + printf(".data\n"); + output_mode = DATA_EMIT_MODE; + } + if (name) + printf("\t.type\t%s,@object\n",name); +} + +int +lvar(int l) +{ + if (fnptr->sc==CODE) { + return l+code_disp_offset; + } else if (l<0) { + return l+disp_offset; + } else { + return l+arg_offset; + } +} + +/* floating point */ + + +char * +fstore(int d) +{ + return use? + (d?"fstl":"fsts"): + (d?"fstpl":"fstps") + ; +} + +char * +fstore_u(int d) +{ + return d?"fstpl":"fstps"; +} + +char * +fload(int d) +{ + return d?"fldl":"flds"; +} + + +void code_dassign_gvar(int e2,int d) +{ + printf("\t%s %s\n",fstore(d),(char *)caddr(e2)) ; +} + +void code_dassign_lvar(int e2,int d) +{ + printf("\t%s %d(%%ebp)\n",fstore(d),e2); +} + +void code_dassign(int e2,int d) +{ + printf("\t%s (%s)\n",fstore(d),register_name(e2,0)); +} + +static double d0 = 1.0; + +int +code_d1(double d) +{ + int *i = (int *)&d0; int *j = (int *)&d; + return (i[1] == 0x3ff00000)?j[0]:j[1]; +} + +int +code_d2(double d) +{ + int *i = (int *)&d0; int *j = (int *)&d; + return (i[1] == 0x3ff00000)?j[1]:j[0]; +} + +void code_dconst(int e2) +{ + int lb; + double d = dcadr(e2); + + if (d==0.0) { + printf("\tfldz\n"); return; + } + if (d==1.0) { + printf("\tfld1\n"); return; + } + printf(" \t.section\t.rodata\n\t.align 8\n"); + lb=fwdlabel(); + printf("_%d:\n",lb); + printf("\t.long\t0x%x,0x%x\n",code_d1(d),code_d2(d)); + if (output_mode==TEXT_EMIT_MODE) { + printf(".text\n"); + } else { + text_mode(); + } + printf("\tfldl _%d\n",lb); +} + +void code_dneg() +{ + printf("\tfchs\n"); +} + +void code_d2i() +{ + /* fuck you! */ + printf("\tlea -%d(%%esp),%%esp\n",size_of_int*2); + printf("\tfnstcw (%%esp)\n"); + printf("\tmovl (%%esp), %s\n",register_name(creg)); + printf("\tmovb $12, 1(%%esp)\n"); + printf("\tfldcw (%%esp)\n"); + printf("\tmovl %s, (%%ebp)\n",register_name(creg)); + printf("\tfistpl %d(%%esp)\n",size_of_int); + printf("\tfldcw (%%esp)\n"); + printf("\tpopl %s\n",register_name(creg)); + printf("\tpopl %s\n",register_name(creg)); +} + +void code_i2d() +{ + printf("\tpushl %s\n",register_name(creg)); + printf("\tfildl (%%esp)\n"); + printf("\tlea %d(%%esp),%%esp\n",size_of_int); +} + +void code_d2u() +{ + /* fuck you! */ + printf("\tlea -%d(%%esp),%%esp\n",size_of_int*3); + printf("\tfnstcw (%%esp)\n"); + printf("\tmovl (%%esp), %s\n",register_name(creg)); + printf("\tmovb $12, 1(%%esp)\n"); + printf("\tfldcw (%%esp)\n"); + printf("\tmovl %s, (%%ebp)\n",register_name(creg)); + printf("\tfistpll %d(%%esp)\n",size_of_int); + printf("\tfldcw (%%esp)\n"); + printf("\tmovl %d(%%esp),%s\n",size_of_int,register_name(creg)); + printf("\tlea %d(%%esp),%%esp\n",size_of_int*3); +} + +void code_u2d() +{ + printf("\tpushl %s\n",register_name(creg)); + printf("\tpushl %s\n",register_name(creg)); + printf("\tmovl $0, %d(%%esp)\n",size_of_int); + printf("\tfildll (%%esp)\n"); + printf("\tlea %d(%%esp),%%esp\n",size_of_int*2); +} + +void code_drgvar(int e2,int d) +{ + printf("\t%s %s\n",fload(d),(char *)caddr(e2)) ; +} + + +void code_drlvar(int e2,int d) +{ + printf("\t%s %d(%%ebp)\n",fload(d),e2); +} + +void code_cmp_drgvar(int e2) +{ + printf("\tfcomp %s\n",(char *)caddr(e2)) ; +} + +void code_cmp_drlvar(int e2) +{ + printf("\tfcomp %d(%%ebp)\n",e2); +} + +void dtosop(int op,int e1) +{ + switch(op) { + case DADD: printf("\tfaddp %%st,%%st(1)\n"); break; + case DSUB: printf("\tfsubp %%st,%%st(1)\n"); break; + case DDIV: printf("\tfdivp %%st,%%st(1)\n"); break; + case DMUL: printf("\tfmulp %%st,%%st(1)\n"); break; + case DCOMP: + /* printf("\tfxch\t%%st(1)\n"); */ + printf("\tfucompp\n"); + printf("\tfnstsw\t%%ax\n"); + break; + } +} + +void +code_dassop(int op,int d) { + /* we have lvalue in creg, applied floating value is in %st(0) */ + printf("\t%s (%s)\n",fload(d),register_name(creg)); + dtosop(op,0); + printf("\t%s (%s)\n",fstore(d),register_name(creg)); +} + +void +code_dpreinc(int e1,int e2,int d) { + g_expr(e2); + printf("\t%s (%s)\n",fload(d),register_name(creg)); + printf("\tfld1\n"); + if (caddr(e1)>0) + printf("\tfaddp %%st,%%st(1)\n"); + else + printf("\tfsubrp %%st,%%st(1)\n"); + printf("\t%s (%s)\n",fstore(d),register_name(creg)); +} + +void +code_dpostinc(int e1,int e2,int d) { + g_expr(e2); + printf("\t%s (%s)\n",fload(d),register_name(creg)); + if (use) + printf("\t%s (%s)\n",fload(d),register_name(creg)); + printf("\tfld1\n"); + if (caddr(e1)>0) + printf("\tfaddp %%st,%%st(1)\n"); + else + printf("\tfsubrp %%st,%%st(1)\n"); + printf("\t%s (%s)\n",(use?fstore_u(d):fstore(d)),register_name(creg)); +} + +void +drexpr(int e1, int e2,int l1, int op) +{ + g_expr(list3(DCOMP,e1,e2)); + switch(op) { + case DOP+GE: + printf("\ttestb\t$5,%%ah\n"); + printf("\tjne\t_%d\n",l1); + break; + case DOP+GT: + printf("\ttestb\t$69,%%ah\n"); + printf("\tjne\t_%d\n",l1); + break; + case DOP+EQ: + printf("\tandb\t$69,%%ah\n"); + printf("\txorb\t$64,%%ah\n"); + printf("\tjne\t_%d\n",l1); + break; + case DOP+NEQ: + printf("\tandb\t$69,%%ah\n"); + printf("\txorb\t$64,%%ah\n"); + printf("\tje\t_%d\n",l1); + break; + } +} + +int dpop_register() +{ + return 1; +} + +int emit_dpop(int e1) +{ + return 1; +} + +void emit_dpop_free(int e1) +{ +} + +void emit_dpush() +{ +} + +/* end */ +
--- a/mc-code.h Wed Mar 05 23:07:00 2003 +0900 +++ b/mc-code.h Thu Mar 06 23:47:42 2003 +0900 @@ -68,7 +68,7 @@ extern void tosop(int op,int oreg); extern void code_opening(char *filename); extern void code_closing(); -extern void rexpr(int e1, int l1, char *s); +extern void rexpr(int e1, int l1, char *s,int t); extern void drexpr(int e1, int e2,int l1, int op); extern void jcond(int l, char cond); extern void jmp(int l); @@ -101,3 +101,13 @@ extern void code_dpreinc(int e1,int e2,int d); extern void code_dpostinc(int e1,int e2,int d); extern void code_dassop(int op,int d); + +extern void code_arg_register(int); + +extern int get_register(void); +extern void free_register(int i) ; +extern int virtual(int real); +extern int pop_register(void); +extern void emit_pop_free(int xreg); + +/* */
--- a/mc-codegen.c Wed Mar 05 23:07:00 2003 +0900 +++ b/mc-codegen.c Thu Mar 06 23:47:42 2003 +0900 @@ -54,172 +54,6 @@ void assop(int e1); void g_expr0(int e1); -int -get_register(void) -{ /* �Ȥ��Ƥ��ʤ��쥸������Ĵ�٤� */ - int i; - for(i=0;i<MAX_REGISTER;i++) { - if (! regs[i]) { /* �Ȥ��Ƥ��ʤ��ʤ� */ - regs[i]=1; /* ���Υ쥸������Ȥ����Ȥ������ */ - return i; /* ���ξ���ɽ���ֹ���֤� */ - } - } - return -1; /* �����Ƥ����꤬�ʤ��ʤ顢�����ɽ�� -1 ���֤� */ -} - -void -free_register(int i) { /* ����ʤ��ʤä��쥸�������� */ - regv[i]=regs[i]=0; -} - -int -register_full(void) -{ - int i; - for(i=0;i<MAX_REGISTER;i++) { - if (! regs[i]) { - return 0; - } - } - return 1; -} - -int -free_register_count(void) -{ - int i,count; - count = 0; - for(i=0;i<MAX_REGISTER;i++) { - if (! regs[i] && ! regv[i]) count++; - } - return count; -} - -void -free_all_register(void) -{ - int i; - for(i=0;i<MAX_REGISTER;i++) { - regs[i]=regv[i]=0; - } - creg = get_register(); - dreg = get_register(); - return; -} - -void -use_register_var(int i) { - regv[i]=1; -} - -void -set_register_var() { -} - -void -arg_register0(int args) -{ - NMTBL *n; - if (args) { - /* process in reverse order */ - n = (NMTBL*)caddr(args); - if(n->sc==REGISTER) { - if ((n->dsp = get_register_var()) <0) { - error(-1); return; - } - use_register_var(n->dsp); /* it has now value in it */ - } - arg_register0(cadr(args)); - } -} - -void -arg_register(NMTBL *fnptr) -{ - arg_register0(fnptr->dsp); -} - -void -register_usage(char *s) -{ - int i; - if (chk) return; - printf("# %d: %s:",lineno,s); - printf(" creg=%s dreg=%s ",register_name(creg,0),register_name(dreg,0)); - for(i=0;i<MAX_REGISTER;i++) { - printf("%d",regs[i]); - } - printf(":"); - for(i=0;i<MAX_REGISTER;i++) { - printf("%d",regv[i]); - } -#if 0 - printf(" regs_stack",register_name(creg,0),register_name(dreg,0)); - for(i=reg_sp;i>=0;i--) { - if(reg_stack[i]>=0) - printf(" %s",register_name(reg_stack[i],0)); - } -#endif - printf("\n"); -} - -void -gexpr_init(void) -{ - while(reg_sp > 0) { - free_register(reg_stack[--reg_sp]); - } - text_mode(); - gexpr_code_init(); - register_usage("gexpr_init"); -} - - -void -emit_init(void) -{ - int i; - for(i=0;i<MAX_REGISTER;i++) { regs[i]=0; regv[i]=0;rname[i]=i;} - free_all_register(); - reg_sp = 0; - text_mode(); -} - -int -virtual(int real) -{ - int real_v,i; - real_v = -1; - for(i=0;i<MAX_REGISTER;i++) { - if (rname[i]==real) { - real_v=i; - break; - } - } - return real_v; -} - -int -pop_register(void) -{ /* �쥸���������ͤ���Ф� */ - return reg_stack[--reg_sp]; -} - -int -stack_used(void) { - return reg_stack[--reg_sp]<0; -} - -void -emit_pop_free(int xreg) -{ - if (xreg==dreg) { - regv[dreg]=0; - } else if (xreg!=-1) { - free_register(xreg); - } -} - void gexpr(int e1,int use0) { @@ -409,7 +243,7 @@ return; case DMUL: case DDIV: case DADD: case DSUB: - case DCOMP: + case DCMP: dmachinop(e1); return; case COND: @@ -483,34 +317,34 @@ b_expr(e2,!cond,l1,0); return; case GT: - rexpr(e1,l1,code_gt(cond)); + rexpr(e1,l1,code_gt(cond),INT); return; case UGT: - rexpr(e1,l1,code_ugt(cond)); + rexpr(e1,l1,code_ugt(cond),UNSIGNED); return; case GE: - rexpr(e1,l1,code_ge(cond)); + rexpr(e1,l1,code_ge(cond),INT); return; case UGE: - rexpr(e1,l1,code_uge(cond)); + rexpr(e1,l1,code_uge(cond),UNSIGNED); return; case LT: - rexpr(e1,l1,code_ge(!cond)); + rexpr(e1,l1,code_ge(!cond),INT); return; case ULT: - rexpr(e1,l1,code_uge(!cond)); + rexpr(e1,l1,code_uge(!cond),UNSIGNED); return; case LE: - rexpr(e1,l1,code_gt(!cond)); + rexpr(e1,l1,code_gt(!cond),INT); return; case ULE: - rexpr(e1,l1,code_ugt(!cond)); + rexpr(e1,l1,code_ugt(!cond),UNSIGNED); return; case EQ: - rexpr(e1,l1,code_eq(cond)); + rexpr(e1,l1,code_eq(cond),INT); return; case NEQ: - rexpr(e1,l1,code_eq(!cond)); + rexpr(e1,l1,code_eq(!cond),INT); return; case DOP+GT: @@ -588,6 +422,12 @@ } +void +arg_register(NMTBL *fnptr) +{ + code_arg_register(fnptr->dsp); +} + /* goto arguments list */ /* target list4(list2(tag,disp),cdr,ty,source_expr) */ /* source expr=listn(tag,...) */
--- a/mc-codegen.h Wed Mar 05 23:07:00 2003 +0900 +++ b/mc-codegen.h Thu Mar 06 23:47:42 2003 +0900 @@ -31,17 +31,9 @@ extern int csvalue(); extern int free_register_count(void); extern int fwdlabel(void); -extern int get_register(void); -extern int pop_register(void); -extern int register_full(void); -extern int virtual(int real); -extern void use_register_var(int i) ; extern void b_expr(int e1, char cond, int l1,int err); extern void bexpr(int e1, char cond, int l1); extern void emit_init(void); -extern void emit_pop_free(int xreg); -extern void free_all_register(void); -extern void free_register(int i); extern void fwddef(int l); extern int csvalue(); @@ -69,10 +61,8 @@ extern void opening(char *filename); extern void closing(); extern void ret(void); -extern void use_register_var(int); -extern void arg_register(NMTBL *); extern void creg_destroy(); -extern void regvar_creg(int); +extern void arg_register(NMTBL *fnptr); /* floating point */
--- a/mc.h Wed Mar 05 23:07:00 2003 +0900 +++ b/mc.h Thu Mar 06 23:47:42 2003 +0900 @@ -108,57 +108,58 @@ #define UMOD 29 #define ADD 30 #define SUB 31 -#define RSHIFT 32 -#define URSHIFT 33 -#define LSHIFT 34 -#define ULSHIFT 35 -#define GT 36 -#define UGT 37 -#define GE 38 -#define UGE 39 -#define LT 40 -#define ULT 41 -#define LE 42 -#define ULE 43 -#define EQ 44 -#define NEQ 45 -#define BAND 46 -#define EOR 47 -#define BOR 48 -#define LAND 49 -#define LOR 50 -#define COND 51 -#define ASS 52 -#define CASS 53 -#define ASSOP 54 -#define CASSOP 55 -#define COMMA 56 -#define LPAR 57 -#define RPAR 58 -#define LBRA 59 -#define RBRA 60 -#define LC 61 -#define RC 62 -#define COLON 63 -#define SM 64 -#define PERIOD 65 -#define ARROW 66 -#define CNAME 67 -#define SASS 68 -#define RSTRUCT 69 +#define CMP 32 +#define RSHIFT 33 +#define URSHIFT 34 +#define LSHIFT 35 +#define ULSHIFT 36 +#define GT 37 +#define UGT 38 +#define GE 39 +#define UGE 40 +#define LT 41 +#define ULT 42 +#define LE 43 +#define ULE 44 +#define EQ 45 +#define NEQ 46 +#define BAND 47 +#define EOR 48 +#define BOR 49 +#define LAND 50 +#define LOR 51 +#define COND 52 +#define ASS 53 +#define CASS 54 +#define ASSOP 55 +#define CASSOP 56 +#define COMMA 57 +#define LPAR 58 +#define RPAR 59 +#define LBRA 60 +#define RBRA 61 +#define LC 62 +#define RC 63 +#define COLON 64 +#define SM 65 +#define PERIOD 66 +#define ARROW 67 +#define CNAME 68 +#define SASS 69 +#define RSTRUCT 70 -#define FASSOP 70 -#define DASSOP 71 -#define DCOMP 72 -#define DMINUS 73 +#define FASSOP 71 +#define DASSOP (DOP+ASSOP) +#define DCMP (DOP+CMP) +#define DMINUS (DOP+MINUS) #define DMUL (DOP+MUL) #define DDIV (DOP+DIV) #define DADD (DOP+ADD) #define DSUB (DOP+SUB) -#define LMUL 78 -#define LDIV 79 -#define LADD 80 -#define LSUB 81 +#define LMUL 72 +#define LDIV 73 +#define LADD 74 +#define LSUB 75 #define FRGVAR 82 #define FRLVAR 83
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/basic.c Thu Mar 06 23:47:42 2003 +0900 @@ -0,0 +1,47 @@ + +int i; +print(double d) +{ + float f; + int *dd; + + f = d; + + dd = (int*) &d; + printf("d %g\n",d); + printf("dx %08x %08x\n",*(dd),*(dd+1)); + + dd = (int*) &f; + printf("f %g\n",f); + printf("dx %08x \n",*(dd)); +} + +void +tmp () { + char c; + int i; + c=-1; + i=c; + printf("%d %d %d\n",!i,~i,-i); + printf("%d\n",i); +} + +void +tmp1 () { + + printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d \n", +0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49 +); + printf("%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g \n", +0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,38.0,39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,49.0 +); + +} + + +main() { + print(1.0); + print(0.1234); + print(1.234e10); + print(1.234e-10); +}